/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2014 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/

#include "cmConditionEvaluator.h"
#include "cmOutputConverter.h"
#include "cmAlgorithms.h"

cmConditionEvaluator::cmConditionEvaluator(cmMakefile& makefile,
                                           const cmListFileContext &context,
                                           const cmListFileBacktrace& bt):
  Makefile(makefile),
  ExecutionContext(context),
  Backtrace(bt),
  Policy12Status(makefile.GetPolicyStatus(cmPolicies::CMP0012)),
  Policy54Status(makefile.GetPolicyStatus(cmPolicies::CMP0054)),
  Policy57Status(makefile.GetPolicyStatus(cmPolicies::CMP0057)),
  Policy64Status(makefile.GetPolicyStatus(cmPolicies::CMP0064))
{

}

//=========================================================================
// order of operations,
// 1.   ( )   -- parenthetical groups
// 2.  IS_DIRECTORY EXISTS COMMAND DEFINED etc predicates
// 3. MATCHES LESS GREATER EQUAL STRLESS STRGREATER STREQUAL etc binary ops
// 4. NOT
// 5. AND OR
//
// There is an issue on whether the arguments should be values of references,
// for example IF (FOO AND BAR) should that compare the strings FOO and BAR
// or should it really do IF (${FOO} AND ${BAR}) Currently IS_DIRECTORY
// EXISTS COMMAND and DEFINED all take values. EQUAL, LESS and GREATER can
// take numeric values or variable names. STRLESS and STRGREATER take
// variable names but if the variable name is not found it will use the name
// directly. AND OR take variables or the values 0 or 1.

bool cmConditionEvaluator::IsTrue(
  const std::vector<cmExpandedCommandArgument> &args,
  std::string &errorString,
  cmake::MessageType &status)
{
  errorString = "";

  // handle empty invocation
  if (args.size() < 1)
    {
    return false;
    }

  // store the reduced args in this vector
  cmArgumentList newArgs;

  // copy to the list structure
  newArgs.insert(newArgs.end(), args.begin(), args.end());

  // now loop through the arguments and see if we can reduce any of them
  // we do this multiple times. Once for each level of precedence
  // parens
  if (!this->HandleLevel0(newArgs, errorString, status))
    {
    return false;
    }
  //predicates
  if (!this->HandleLevel1(newArgs, errorString, status))
    {
    return false;
    }
  // binary ops
  if (!this->HandleLevel2(newArgs, errorString, status))
    {
    return false;
    }

  // NOT
  if (!this->HandleLevel3(newArgs, errorString, status))
    {
    return false;
    }
  // AND OR
  if (!this->HandleLevel4(newArgs, errorString, status))
    {
    return false;
    }

  // now at the end there should only be one argument left
  if (newArgs.size() != 1)
    {
    errorString = "Unknown arguments specified";
    status = cmake::FATAL_ERROR;
    return false;
    }

  return this->GetBooleanValueWithAutoDereference(*(newArgs.begin()),
    errorString, status, true);
}

cmListFileContext cmConditionEvaluator::GetConditionContext(
    cmMakefile* mf,
    const cmCommandContext& command,
    const std::string& filePath)
{
  cmListFileContext context =
      cmListFileContext::FromCommandContext(
        command,
        filePath);

  if(!mf->GetCMakeInstance()->GetIsInTryCompile())
    {
    cmOutputConverter converter(mf->GetStateSnapshot());
    context.FilePath = converter.Convert(context.FilePath,
                                         cmOutputConverter::HOME);
    }
  return context;
}

//=========================================================================
const char* cmConditionEvaluator::GetDefinitionIfUnquoted(
  cmExpandedCommandArgument const& argument) const
{
  if((this->Policy54Status != cmPolicies::WARN &&
     this->Policy54Status != cmPolicies::OLD) &&
     argument.WasQuoted())
    {
    return 0;
    }

  const char* def = this->Makefile.GetDefinition(argument.GetValue());

  if(def && argument.WasQuoted() && this->Policy54Status == cmPolicies::WARN)
    {
    if(!this->Makefile.HasCMP0054AlreadyBeenReported(
         this->ExecutionContext))
      {
      std::ostringstream e;
      e << (cmPolicies::GetPolicyWarning(cmPolicies::CMP0054)) << "\n";
      e << "Quoted variables like \"" << argument.GetValue() <<
        "\" will no longer be dereferenced "
        "when the policy is set to NEW.  "
        "Since the policy is not set the OLD behavior will be used.";

      this->Makefile.GetCMakeInstance()
          ->IssueMessage(cmake::AUTHOR_WARNING, e.str(),
                         this->Backtrace);
      }
    }

  return def;
}

//=========================================================================
const char* cmConditionEvaluator::GetVariableOrString(
    const cmExpandedCommandArgument& argument) const
{
  const char* def = this->GetDefinitionIfUnquoted(argument);

  if(!def)
    {
    def = argument.c_str();
    }

  return def;
}

//=========================================================================
bool cmConditionEvaluator::IsKeyword(std::string const& keyword,
  cmExpandedCommandArgument& argument) const
{
  if((this->Policy54Status != cmPolicies::WARN &&
     this->Policy54Status != cmPolicies::OLD) &&
     argument.WasQuoted())
    {
    return false;
    }

  bool isKeyword = argument.GetValue() == keyword;

  if(isKeyword && argument.WasQuoted() &&
    this->Policy54Status == cmPolicies::WARN)
    {
    if(!this->Makefile.HasCMP0054AlreadyBeenReported(
         this->ExecutionContext))
      {
      std::ostringstream e;
      e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0054) << "\n";
      e << "Quoted keywords like \"" << argument.GetValue() <<
        "\" will no longer be interpreted as keywords "
        "when the policy is set to NEW.  "
        "Since the policy is not set the OLD behavior will be used.";

      this->Makefile.GetCMakeInstance()
          ->IssueMessage(cmake::AUTHOR_WARNING, e.str(),
                         this->Backtrace);
      }
    }

  return isKeyword;
}

//=========================================================================
bool cmConditionEvaluator::GetBooleanValue(
  cmExpandedCommandArgument& arg) const
{
  // Check basic constants.
  if (arg == "0")
    {
    return false;
    }
  if (arg == "1")
    {
    return true;
    }

  // Check named constants.
  if (cmSystemTools::IsOn(arg.c_str()))
    {
    return true;
    }
  if (cmSystemTools::IsOff(arg.c_str()))
    {
    return false;
    }

  // Check for numbers.
  if(!arg.empty())
    {
    char* end;
    double d = strtod(arg.c_str(), &end);
    if(*end == '\0')
      {
      // The whole string is a number.  Use C conversion to bool.
      return d? true:false;
      }
    }

  // Check definition.
  const char* def = this->GetDefinitionIfUnquoted(arg);
  return !cmSystemTools::IsOff(def);
}

//=========================================================================
// Boolean value behavior from CMake 2.6.4 and below.
bool cmConditionEvaluator::GetBooleanValueOld(
  cmExpandedCommandArgument const& arg, bool one) const
{
  if(one)
    {
    // Old IsTrue behavior for single argument.
    if(arg == "0")
      { return false; }
    else if(arg == "1")
      { return true; }
    else
      {
      const char* def = this->GetDefinitionIfUnquoted(arg);
      return !cmSystemTools::IsOff(def);
      }
    }
  else
    {
    // Old GetVariableOrNumber behavior.
    const char* def = this->GetDefinitionIfUnquoted(arg);
    if(!def && atoi(arg.c_str()))
      {
      def = arg.c_str();
      }
    return !cmSystemTools::IsOff(def);
    }
}

//=========================================================================
// returns the resulting boolean value
bool cmConditionEvaluator::GetBooleanValueWithAutoDereference(
  cmExpandedCommandArgument &newArg,
  std::string &errorString,
  cmake::MessageType &status,
  bool oneArg) const
{
  // Use the policy if it is set.
  if (this->Policy12Status == cmPolicies::NEW)
    {
    return GetBooleanValue(newArg);
    }
  else if (this->Policy12Status == cmPolicies::OLD)
    {
    return GetBooleanValueOld(newArg, oneArg);
    }

  // Check policy only if old and new results differ.
  bool newResult = this->GetBooleanValue(newArg);
  bool oldResult = this->GetBooleanValueOld(newArg, oneArg);
  if(newResult != oldResult)
    {
    switch(this->Policy12Status)
      {
      case cmPolicies::WARN:
        {
        errorString = "An argument named \"" + newArg.GetValue()
          + "\" appears in a conditional statement.  "
          + cmPolicies::GetPolicyWarning(cmPolicies::CMP0012);
        status = cmake::AUTHOR_WARNING;
        }
      case cmPolicies::OLD:
        return oldResult;
      case cmPolicies::REQUIRED_IF_USED:
      case cmPolicies::REQUIRED_ALWAYS:
        {
        errorString = "An argument named \"" + newArg.GetValue()
          + "\" appears in a conditional statement.  "
          + cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0012);
        status = cmake::FATAL_ERROR;
        }
      case cmPolicies::NEW:
        break;
      }
    }
  return newResult;
}

//=========================================================================
void cmConditionEvaluator::IncrementArguments(cmArgumentList &newArgs,
                        cmArgumentList::iterator &argP1,
                        cmArgumentList::iterator &argP2) const
{
  if (argP1 != newArgs.end())
    {
    argP1++;
    argP2 = argP1;
    if (argP1 != newArgs.end())
      {
      argP2++;
      }
    }
}

//=========================================================================
// helper function to reduce code duplication
void cmConditionEvaluator::HandlePredicate(bool value, int &reducible,
                     cmArgumentList::iterator &arg,
                     cmArgumentList &newArgs,
                     cmArgumentList::iterator &argP1,
                     cmArgumentList::iterator &argP2) const
{
  if(value)
    {
    *arg = cmExpandedCommandArgument("1", true);
    }
  else
    {
    *arg = cmExpandedCommandArgument("0", true);
    }
  newArgs.erase(argP1);
  argP1 = arg;
  this->IncrementArguments(newArgs,argP1,argP2);
  reducible = 1;
}

//=========================================================================
// helper function to reduce code duplication
void cmConditionEvaluator::HandleBinaryOp(bool value, int &reducible,
                     cmArgumentList::iterator &arg,
                     cmArgumentList &newArgs,
                     cmArgumentList::iterator &argP1,
                     cmArgumentList::iterator &argP2)
{
  if(value)
    {
    *arg = cmExpandedCommandArgument("1", true);
    }
  else
    {
    *arg = cmExpandedCommandArgument("0", true);
    }
  newArgs.erase(argP2);
  newArgs.erase(argP1);
  argP1 = arg;
  this->IncrementArguments(newArgs,argP1,argP2);
  reducible = 1;
}

//=========================================================================
// level 0 processes parenthetical expressions
bool cmConditionEvaluator::HandleLevel0(cmArgumentList &newArgs,
                  std::string &errorString,
                  cmake::MessageType &status)
{
  int reducible;
  do
    {
    reducible = 0;
    cmArgumentList::iterator arg = newArgs.begin();
    while (arg != newArgs.end())
      {
      if (IsKeyword("(", *arg))
        {
        // search for the closing paren for this opening one
        cmArgumentList::iterator argClose;
        argClose = arg;
        argClose++;
        unsigned int depth = 1;
        while (argClose != newArgs.end() && depth)
          {
          if (this->IsKeyword("(", *argClose))
            {
              depth++;
            }
          if (this->IsKeyword(")", *argClose))
            {
              depth--;
            }
          argClose++;
          }
        if (depth)
          {
          errorString = "mismatched parenthesis in condition";
          status = cmake::FATAL_ERROR;
          return false;
          }
        // store the reduced args in this vector
        std::vector<cmExpandedCommandArgument> newArgs2;

        // copy to the list structure
        cmArgumentList::iterator argP1 = arg;
        argP1++;
        newArgs2.insert(newArgs2.end(), argP1, argClose);
        newArgs2.pop_back();
        // now recursively invoke IsTrue to handle the values inside the
        // parenthetical expression
        bool value =
          this->IsTrue(newArgs2, errorString, status);
        if(value)
          {
          *arg = cmExpandedCommandArgument("1", true);
          }
        else
          {
          *arg = cmExpandedCommandArgument("0", true);
          }
        argP1 = arg;
        argP1++;
        // remove the now evaluated parenthetical expression
        newArgs.erase(argP1,argClose);
        }
      ++arg;
      }
    }
  while (reducible);
  return true;
}

//=========================================================================
// level one handles most predicates except for NOT
bool cmConditionEvaluator::HandleLevel1(cmArgumentList &newArgs,
                  std::string &, cmake::MessageType &)
{
  int reducible;
  do
    {
    reducible = 0;
    cmArgumentList::iterator arg = newArgs.begin();
    cmArgumentList::iterator argP1;
    cmArgumentList::iterator argP2;
    while (arg != newArgs.end())
      {
      argP1 = arg;
      this->IncrementArguments(newArgs,argP1,argP2);
      // does a file exist
      if (this->IsKeyword("EXISTS", *arg) && argP1 != newArgs.end())
        {
        this->HandlePredicate(
          cmSystemTools::FileExists(argP1->c_str()),
          reducible, arg, newArgs, argP1, argP2);
        }
      // does a directory with this name exist
      if (this->IsKeyword("IS_DIRECTORY", *arg) && argP1 != newArgs.end())
        {
        this->HandlePredicate(
          cmSystemTools::FileIsDirectory(argP1->c_str()),
          reducible, arg, newArgs, argP1, argP2);
        }
      // does a symlink with this name exist
      if (this->IsKeyword("IS_SYMLINK", *arg) && argP1 != newArgs.end())
        {
        this->HandlePredicate(
          cmSystemTools::FileIsSymlink(argP1->c_str()),
          reducible, arg, newArgs, argP1, argP2);
        }
      // is the given path an absolute path ?
      if (this->IsKeyword("IS_ABSOLUTE", *arg) && argP1 != newArgs.end())
        {
        this->HandlePredicate(
          cmSystemTools::FileIsFullPath(argP1->c_str()),
          reducible, arg, newArgs, argP1, argP2);
        }
      // does a command exist
      if (this->IsKeyword("COMMAND", *arg) && argP1 != newArgs.end())
        {
        cmCommand* command =
            this->Makefile.GetState()->GetCommand(argP1->c_str());
        this->HandlePredicate(
          command ? true : false,
          reducible, arg, newArgs, argP1, argP2);
        }
      // does a policy exist
      if (this->IsKeyword("POLICY", *arg) && argP1 != newArgs.end())
        {
        cmPolicies::PolicyID pid;
        this->HandlePredicate(
          cmPolicies::GetPolicyID(argP1->c_str(), pid),
            reducible, arg, newArgs, argP1, argP2);
        }
      // does a target exist
      if (this->IsKeyword("TARGET", *arg) && argP1 != newArgs.end())
        {
        this->HandlePredicate(
          this->Makefile.FindTargetToUse(argP1->GetValue())?true:false,
          reducible, arg, newArgs, argP1, argP2);
        }
      // does a test exist
      if(this->Policy64Status != cmPolicies::OLD &&
        this->Policy64Status != cmPolicies::WARN)
        {
        if (this->IsKeyword("TEST", *arg) && argP1 != newArgs.end())
          {
          const cmTest* haveTest = this->Makefile.GetTest(argP1->c_str());
          this->HandlePredicate(
            haveTest?true:false,
            reducible, arg, newArgs, argP1, argP2);
          }
        }
      else if(this->Policy64Status == cmPolicies::WARN &&
        this->IsKeyword("TEST", *arg))
        {
        std::ostringstream e;
        e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0064) << "\n";
        e << "TEST will be interpreted as an operator "
          "when the policy is set to NEW.  "
          "Since the policy is not set the OLD behavior will be used.";

        this->Makefile.IssueMessage(cmake::AUTHOR_WARNING, e.str());
        }
      // is a variable defined
      if (this->IsKeyword("DEFINED", *arg) && argP1 != newArgs.end())
        {
        size_t argP1len = argP1->GetValue().size();
        bool bdef = false;
        if(argP1len > 4 && argP1->GetValue().substr(0, 4) == "ENV{" &&
           argP1->GetValue().operator[](argP1len-1) == '}')
          {
          std::string env = argP1->GetValue().substr(4, argP1len-5);
          bdef = cmSystemTools::GetEnv(env.c_str())?true:false;
          }
        else
          {
          bdef = this->Makefile.IsDefinitionSet(argP1->GetValue());
          }
        this->HandlePredicate(bdef, reducible, arg, newArgs, argP1, argP2);
        }
      ++arg;
      }
    }
  while (reducible);
  return true;
}

//=========================================================================
// level two handles most binary operations except for AND  OR
bool cmConditionEvaluator::HandleLevel2(cmArgumentList &newArgs,
                  std::string &errorString,
                  cmake::MessageType &status)
{
  int reducible;
  std::string def_buf;
  const char *def;
  const char *def2;
  do
    {
    reducible = 0;
    cmArgumentList::iterator arg = newArgs.begin();
    cmArgumentList::iterator argP1;
    cmArgumentList::iterator argP2;
    while (arg != newArgs.end())
      {
      argP1 = arg;
      this->IncrementArguments(newArgs,argP1,argP2);
      if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
        IsKeyword("MATCHES", *argP1))
        {
        def = this->GetVariableOrString(*arg);
        if (def != arg->c_str() // yes, we compare the pointer value
            && cmHasLiteralPrefix(arg->GetValue(), "CMAKE_MATCH_"))
          {
          // The string to match is owned by our match result variables.
          // Move it to our own buffer before clearing them.
          def_buf = def;
          def = def_buf.c_str();
          }
        const char* rex = argP2->c_str();
        this->Makefile.ClearMatches();
        cmsys::RegularExpression regEntry;
        if ( !regEntry.compile(rex) )
          {
          std::ostringstream error;
          error << "Regular expression \"" << rex << "\" cannot compile";
          errorString = error.str();
          status = cmake::FATAL_ERROR;
          return false;
          }
        if (regEntry.find(def))
          {
          this->Makefile.StoreMatches(regEntry);
          *arg = cmExpandedCommandArgument("1", true);
          }
        else
          {
          *arg = cmExpandedCommandArgument("0", true);
          }
        newArgs.erase(argP2);
        newArgs.erase(argP1);
        argP1 = arg;
        this->IncrementArguments(newArgs,argP1,argP2);
        reducible = 1;
        }

      if (argP1 != newArgs.end() && this->IsKeyword("MATCHES", *arg))
        {
        *arg = cmExpandedCommandArgument("0", true);
        newArgs.erase(argP1);
        argP1 = arg;
        this->IncrementArguments(newArgs,argP1,argP2);
        reducible = 1;
        }

      if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
        (this->IsKeyword("LESS", *argP1) ||
         this->IsKeyword("GREATER", *argP1) ||
         this->IsKeyword("EQUAL", *argP1)))
        {
        def = this->GetVariableOrString(*arg);
        def2 = this->GetVariableOrString(*argP2);
        double lhs;
        double rhs;
        bool result;
        if(sscanf(def, "%lg", &lhs) != 1 ||
           sscanf(def2, "%lg", &rhs) != 1)
          {
          result = false;
          }
        else if (*(argP1) == "LESS")
          {
          result = (lhs < rhs);
          }
        else if (*(argP1) == "GREATER")
          {
          result = (lhs > rhs);
          }
        else
          {
          result = (lhs == rhs);
          }
        this->HandleBinaryOp(result,
          reducible, arg, newArgs, argP1, argP2);
        }

      if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
        (this->IsKeyword("STRLESS", *argP1) ||
         this->IsKeyword("STREQUAL", *argP1) ||
         this->IsKeyword("STRGREATER", *argP1)))
        {
        def = this->GetVariableOrString(*arg);
        def2 = this->GetVariableOrString(*argP2);
        int val = strcmp(def,def2);
        bool result;
        if (*(argP1) == "STRLESS")
          {
          result = (val < 0);
          }
        else if (*(argP1) == "STRGREATER")
          {
          result = (val > 0);
          }
        else // strequal
          {
          result = (val == 0);
          }
        this->HandleBinaryOp(result,
          reducible, arg, newArgs, argP1, argP2);
        }

      if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
        (this->IsKeyword("VERSION_LESS", *argP1) ||
         this->IsKeyword("VERSION_GREATER", *argP1) ||
         this->IsKeyword("VERSION_EQUAL", *argP1)))
        {
        def = this->GetVariableOrString(*arg);
        def2 = this->GetVariableOrString(*argP2);
        cmSystemTools::CompareOp op = cmSystemTools::OP_EQUAL;
        if(*argP1 == "VERSION_LESS")
          {
          op = cmSystemTools::OP_LESS;
          }
        else if(*argP1 == "VERSION_GREATER")
          {
          op = cmSystemTools::OP_GREATER;
          }
        bool result = cmSystemTools::VersionCompare(op, def, def2);
        this->HandleBinaryOp(result,
          reducible, arg, newArgs, argP1, argP2);
        }

      // is file A newer than file B
      if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
          this->IsKeyword("IS_NEWER_THAN", *argP1))
        {
        int fileIsNewer=0;
        bool success=cmSystemTools::FileTimeCompare(arg->GetValue(),
            (argP2)->GetValue(),
            &fileIsNewer);
        this->HandleBinaryOp(
          (success==false || fileIsNewer==1 || fileIsNewer==0),
          reducible, arg, newArgs, argP1, argP2);
        }

      if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
          this->IsKeyword("IN_LIST", *argP1))
        {
        if(this->Policy57Status != cmPolicies::OLD &&
          this->Policy57Status != cmPolicies::WARN)
          {
          bool result = false;

          def = this->GetVariableOrString(*arg);
          def2 = this->Makefile.GetDefinition(argP2->GetValue());

          if(def2)
            {
            std::vector<std::string> list;
            cmSystemTools::ExpandListArgument(def2, list, true);

            result = std::find(list.begin(), list.end(), def) != list.end();
            }

          this->HandleBinaryOp(result,
            reducible, arg, newArgs, argP1, argP2);
          }
          else if(this->Policy57Status == cmPolicies::WARN)
            {
            std::ostringstream e;
            e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0057) << "\n";
            e << "IN_LIST will be interpreted as an operator "
              "when the policy is set to NEW.  "
              "Since the policy is not set the OLD behavior will be used.";

            this->Makefile.IssueMessage(cmake::AUTHOR_WARNING, e.str());
            }
        }

      ++arg;
      }
    }
  while (reducible);
  return true;
}

//=========================================================================
// level 3 handles NOT
bool cmConditionEvaluator::HandleLevel3(cmArgumentList &newArgs,
                  std::string &errorString,
                  cmake::MessageType &status)
{
  int reducible;
  do
    {
    reducible = 0;
    cmArgumentList::iterator arg = newArgs.begin();
    cmArgumentList::iterator argP1;
    cmArgumentList::iterator argP2;
    while (arg != newArgs.end())
      {
      argP1 = arg;
      IncrementArguments(newArgs,argP1,argP2);
      if (argP1 != newArgs.end() && IsKeyword("NOT", *arg))
        {
        bool rhs = this->GetBooleanValueWithAutoDereference(*argP1,
                                                      errorString,
                                                      status);
        this->HandlePredicate(!rhs, reducible, arg, newArgs, argP1, argP2);
        }
      ++arg;
      }
    }
  while (reducible);
  return true;
}

//=========================================================================
// level 4 handles AND OR
bool cmConditionEvaluator::HandleLevel4(cmArgumentList &newArgs,
                  std::string &errorString,
                  cmake::MessageType &status)
{
  int reducible;
  bool lhs;
  bool rhs;
  do
    {
    reducible = 0;
    cmArgumentList::iterator arg = newArgs.begin();
    cmArgumentList::iterator argP1;
    cmArgumentList::iterator argP2;
    while (arg != newArgs.end())
      {
      argP1 = arg;
      IncrementArguments(newArgs,argP1,argP2);
      if (argP1 != newArgs.end() && IsKeyword("AND", *argP1) &&
        argP2 != newArgs.end())
        {
        lhs = this->GetBooleanValueWithAutoDereference(*arg,
                                                 errorString,
                                                 status);
        rhs = this->GetBooleanValueWithAutoDereference(*argP2,
                                                 errorString,
                                                 status);
        this->HandleBinaryOp((lhs && rhs),
          reducible, arg, newArgs, argP1, argP2);
        }

      if (argP1 != newArgs.end() && this->IsKeyword("OR", *argP1) &&
        argP2 != newArgs.end())
        {
        lhs = this->GetBooleanValueWithAutoDereference(*arg,
                                                 errorString,
                                                 status);
        rhs = this->GetBooleanValueWithAutoDereference(*argP2,
                                                 errorString,
                                                 status);
        this->HandleBinaryOp((lhs || rhs),
          reducible, arg, newArgs, argP1, argP2);
        }
      ++arg;
      }
    }
  while (reducible);
  return true;
}
