Program: 15784
Project: 15784
Buggy source:
/** 
 * @param leftExp {@code null} is allowed, but may results in less helpful error messages
 * @param operator one of the {@code COMP_OP_...} constants, like {@link #CMP_OP_EQUALS}.
 * @param operatorString can be null {@code null}; the actual operator used, used for more accurate error message.
 * @param rightExp {@code null} is allowed, but may results in less helpful error messages
 * @param typeMismatchMeansNotEqual If the two types are incompatible, they are treated as non-equal insteadof throwing an exception. Comparing dates of different types will still throw an exception, however. 
 * @param leftNullReturnsFalse if {@code true}, a   {@code null} left value will not cause exception, but make theexpression  {@code false}.  
 * @param rightNullReturnsFalse if {@code true}, a   {@code null} right value will not cause exception, but make theexpression  {@code false}.  
 */
static boolean compare(TemplateModel leftValue,Expression leftExp,int operator,String operatorString,TemplateModel rightValue,Expression rightExp,boolean typeMismatchMeansNotEqual,boolean leftNullReturnsFalse,boolean rightNullReturnsFalse,Environment env) throws TemplateException {
  if (leftValue == null) {
    if (env != null && env.isClassicCompatible()) {
      leftValue=TemplateScalarModel.EMPTY_STRING;
    }
 else {
      if (leftNullReturnsFalse) {
        return false;
      }
 else {
        if (leftExp != null) {
          leftExp.assertNonNull(leftValue);
        }
 else {
          throw new TemplateException("String_Node_Str",env);
        }
      }
    }
  }
  if (rightValue == null) {
    if (env != null && env.isClassicCompatible()) {
      rightValue=TemplateScalarModel.EMPTY_STRING;
    }
 else {
      if (rightNullReturnsFalse) {
        return false;
      }
 else {
        if (rightExp != null) {
          throw rightExp.newInvalidReferenceException();
        }
 else {
          throw new TemplateException("String_Node_Str",env);
        }
      }
    }
  }
  final int cmpResult;
  if (leftValue instanceof TemplateNumberModel && rightValue instanceof TemplateNumberModel) {
    Number leftNum=EvaluationUtil.getNumber((TemplateNumberModel)leftValue,leftExp,env);
    Number rightNum=EvaluationUtil.getNumber((TemplateNumberModel)rightValue,rightExp,env);
    ArithmeticEngine ae=env != null ? env.getArithmeticEngine() : (leftExp != null ? leftExp.getTemplate().getArithmeticEngine() : ArithmeticEngine.BIGDECIMAL_ENGINE);
    try {
      cmpResult=ae.compareNumbers(leftNum,rightNum);
    }
 catch (    RuntimeException e) {
      throw new TemplateModelException("String_Node_Str" + e,e);
    }
  }
 else   if (leftValue instanceof TemplateDateModel && rightValue instanceof TemplateDateModel) {
    TemplateDateModel leftDateModel=(TemplateDateModel)leftValue;
    TemplateDateModel rightDateModel=(TemplateDateModel)rightValue;
    int leftDateType=leftDateModel.getDateType();
    int rightDateType=rightDateModel.getDateType();
    if (leftDateType != rightDateType) {
      throw new TemplateException("String_Node_Str" + TemplateDateModel.TYPE_NAMES.get(leftDateType) + "String_Node_Str"+ TemplateDateModel.TYPE_NAMES.get(rightDateType)+ "String_Node_Str",env);
    }
    if (leftDateType == TemplateDateModel.UNKNOWN) {
      if (leftExp != null) {
        leftExp.newTemplateException("String_Node_Str" + DATE_OF_THE_COMPARISON_IS_OF_TYPE_UNKNOWN + "String_Node_Str"+ USE_DATE_TIME_TYPE_BUILTINS);
      }
 else {
        throw new TemplateException("String_Node_Str" + DATE_OF_THE_COMPARISON_IS_OF_TYPE_UNKNOWN,env);
      }
    }
    if (rightDateType == TemplateDateModel.UNKNOWN) {
      if (rightExp != null) {
        rightExp.newTemplateException("String_Node_Str" + DATE_OF_THE_COMPARISON_IS_OF_TYPE_UNKNOWN + "String_Node_Str"+ USE_DATE_TIME_TYPE_BUILTINS);
      }
 else {
        throw new TemplateException("String_Node_Str" + DATE_OF_THE_COMPARISON_IS_OF_TYPE_UNKNOWN,env);
      }
    }
    Date leftDate=EvaluationUtil.getDate(leftDateModel,leftExp,env);
    Date rightDate=EvaluationUtil.getDate(rightDateModel,rightExp,env);
    cmpResult=leftDate.compareTo(rightDate);
  }
 else   if (leftValue instanceof TemplateScalarModel && rightValue instanceof TemplateScalarModel) {
    if (operator != CMP_OP_EQUALS && operator != CMP_OP_NOT_EQUALS) {
      throw new TemplateException("String_Node_Str" + cmpOpToString(operator,operatorString) + "String_Node_Str",env);
    }
    String leftString=EvaluationUtil.getString((TemplateScalarModel)leftValue,leftExp,env);
    String rightString=EvaluationUtil.getString((TemplateScalarModel)rightValue,rightExp,env);
    cmpResult=env.getCollator().compare(leftString,rightString);
  }
 else   if (leftValue instanceof TemplateBooleanModel && rightValue instanceof TemplateBooleanModel) {
    if (operator != CMP_OP_EQUALS && operator != CMP_OP_NOT_EQUALS) {
      throw new TemplateException("String_Node_Str" + cmpOpToString(operator,operatorString) + "String_Node_Str",env);
    }
    boolean leftBool=((TemplateBooleanModel)leftValue).getAsBoolean();
    boolean rightBool=((TemplateBooleanModel)rightValue).getAsBoolean();
    cmpResult=(leftBool ? 1 : 0) - (rightBool ? 1 : 0);
  }
 else   if (env.isClassicCompatible()) {
    String leftSting=leftExp.getStringValue(env);
    String rightString=rightExp.getStringValue(env);
    cmpResult=env.getCollator().compare(leftSting,rightString);
  }
 else {
    if (typeMismatchMeansNotEqual) {
      if (operator == CMP_OP_EQUALS) {
        return false;
      }
 else       if (operator == CMP_OP_NOT_EQUALS) {
        return true;
      }
    }
    throw new TemplateException("String_Node_Str" + "String_Node_Str" + "String_Node_Str" + ClassUtil.getFTLTypeDescription(leftValue) + "String_Node_Str"+ "String_Node_Str"+ ClassUtil.getFTLTypeDescription(rightValue)+ "String_Node_Str",env);
  }
switch (operator) {
case CMP_OP_EQUALS:
    return cmpResult == 0;
case CMP_OP_NOT_EQUALS:
  return cmpResult != 0;
case CMP_OP_LESS_THAN:
return cmpResult < 0;
case CMP_OP_GREATER_THAN:
return cmpResult > 0;
case CMP_OP_LESS_THAN_EQUALS:
return cmpResult <= 0;
case CMP_OP_GREATER_THAN_EQUALS:
return cmpResult >= 0;
default :
throw new TemplateException("String_Node_Str" + operator,env);
}
}

Fixed version (ground truth):
/** 
 * @param leftExp {@code null} is allowed, but may results in less helpful error messages
 * @param operator one of the {@code COMP_OP_...} constants, like {@link #CMP_OP_EQUALS}.
 * @param operatorString can be null {@code null}; the actual operator used, used for more accurate error message.
 * @param rightExp {@code null} is allowed, but may results in less helpful error messages
 * @param typeMismatchMeansNotEqual If the two types are incompatible, they are treated as non-equal insteadof throwing an exception. Comparing dates of different types will still throw an exception, however. 
 * @param leftNullReturnsFalse if {@code true}, a   {@code null} left value will not cause exception, but make theexpression  {@code false}.  
 * @param rightNullReturnsFalse if {@code true}, a   {@code null} right value will not cause exception, but make theexpression  {@code false}.  
 */
static boolean compare(TemplateModel leftValue,Expression leftExp,int operator,String operatorString,TemplateModel rightValue,Expression rightExp,boolean typeMismatchMeansNotEqual,boolean leftNullReturnsFalse,boolean rightNullReturnsFalse,Environment env) throws TemplateException {
  if (leftValue == null) {
    if (env != null && env.isClassicCompatible()) {
      leftValue=TemplateScalarModel.EMPTY_STRING;
    }
 else {
      if (leftNullReturnsFalse) {
        return false;
      }
 else {
        if (leftExp != null) {
          leftExp.assertNonNull(leftValue);
        }
 else {
          throw new TemplateException("String_Node_Str",env);
        }
      }
    }
  }
  if (rightValue == null) {
    if (env != null && env.isClassicCompatible()) {
      rightValue=TemplateScalarModel.EMPTY_STRING;
    }
 else {
      if (rightNullReturnsFalse) {
        return false;
      }
 else {
        if (rightExp != null) {
          throw rightExp.newInvalidReferenceException();
        }
 else {
          throw new TemplateException("String_Node_Str",env);
        }
      }
    }
  }
  final int cmpResult;
  if (leftValue instanceof TemplateNumberModel && rightValue instanceof TemplateNumberModel) {
    Number leftNum=EvaluationUtil.getNumber((TemplateNumberModel)leftValue,leftExp,env);
    Number rightNum=EvaluationUtil.getNumber((TemplateNumberModel)rightValue,rightExp,env);
    ArithmeticEngine ae=env != null ? env.getArithmeticEngine() : (leftExp != null ? leftExp.getTemplate().getArithmeticEngine() : ArithmeticEngine.BIGDECIMAL_ENGINE);
    try {
      cmpResult=ae.compareNumbers(leftNum,rightNum);
    }
 catch (    RuntimeException e) {
      throw new TemplateModelException("String_Node_Str" + e,e);
    }
  }
 else   if (leftValue instanceof TemplateDateModel && rightValue instanceof TemplateDateModel) {
    TemplateDateModel leftDateModel=(TemplateDateModel)leftValue;
    TemplateDateModel rightDateModel=(TemplateDateModel)rightValue;
    int leftDateType=leftDateModel.getDateType();
    int rightDateType=rightDateModel.getDateType();
    if (leftDateType != rightDateType) {
      throw new TemplateException("String_Node_Str" + TemplateDateModel.TYPE_NAMES.get(leftDateType) + "String_Node_Str"+ TemplateDateModel.TYPE_NAMES.get(rightDateType)+ "String_Node_Str",env);
    }
    if (leftDateType == TemplateDateModel.UNKNOWN) {
      if (leftExp != null) {
        throw leftExp.newTemplateException("String_Node_Str" + DATE_OF_THE_COMPARISON_IS_OF_TYPE_UNKNOWN + "String_Node_Str"+ USE_DATE_TIME_TYPE_BUILTINS);
      }
 else {
        throw new TemplateException("String_Node_Str" + DATE_OF_THE_COMPARISON_IS_OF_TYPE_UNKNOWN,env);
      }
    }
    if (rightDateType == TemplateDateModel.UNKNOWN) {
      if (rightExp != null) {
        throw rightExp.newTemplateException("String_Node_Str" + DATE_OF_THE_COMPARISON_IS_OF_TYPE_UNKNOWN + "String_Node_Str"+ USE_DATE_TIME_TYPE_BUILTINS);
      }
 else {
        throw new TemplateException("String_Node_Str" + DATE_OF_THE_COMPARISON_IS_OF_TYPE_UNKNOWN,env);
      }
    }
    Date leftDate=EvaluationUtil.getDate(leftDateModel,leftExp,env);
    Date rightDate=EvaluationUtil.getDate(rightDateModel,rightExp,env);
    cmpResult=leftDate.compareTo(rightDate);
  }
 else   if (leftValue instanceof TemplateScalarModel && rightValue instanceof TemplateScalarModel) {
    if (operator != CMP_OP_EQUALS && operator != CMP_OP_NOT_EQUALS) {
      throw new TemplateException("String_Node_Str" + cmpOpToString(operator,operatorString) + "String_Node_Str",env);
    }
    String leftString=EvaluationUtil.getString((TemplateScalarModel)leftValue,leftExp,env);
    String rightString=EvaluationUtil.getString((TemplateScalarModel)rightValue,rightExp,env);
    cmpResult=env.getCollator().compare(leftString,rightString);
  }
 else   if (leftValue instanceof TemplateBooleanModel && rightValue instanceof TemplateBooleanModel) {
    if (operator != CMP_OP_EQUALS && operator != CMP_OP_NOT_EQUALS) {
      throw new TemplateException("String_Node_Str" + cmpOpToString(operator,operatorString) + "String_Node_Str",env);
    }
    boolean leftBool=((TemplateBooleanModel)leftValue).getAsBoolean();
    boolean rightBool=((TemplateBooleanModel)rightValue).getAsBoolean();
    cmpResult=(leftBool ? 1 : 0) - (rightBool ? 1 : 0);
  }
 else   if (env.isClassicCompatible()) {
    String leftSting=leftExp.getStringValue(env);
    String rightString=rightExp.getStringValue(env);
    cmpResult=env.getCollator().compare(leftSting,rightString);
  }
 else {
    if (typeMismatchMeansNotEqual) {
      if (operator == CMP_OP_EQUALS) {
        return false;
      }
 else       if (operator == CMP_OP_NOT_EQUALS) {
        return true;
      }
    }
    throw new TemplateException("String_Node_Str" + "String_Node_Str" + "String_Node_Str" + ClassUtil.getFTLTypeDescription(leftValue) + "String_Node_Str"+ "String_Node_Str"+ ClassUtil.getFTLTypeDescription(rightValue)+ "String_Node_Str",env);
  }
switch (operator) {
case CMP_OP_EQUALS:
    return cmpResult == 0;
case CMP_OP_NOT_EQUALS:
  return cmpResult != 0;
case CMP_OP_LESS_THAN:
return cmpResult < 0;
case CMP_OP_GREATER_THAN:
return cmpResult > 0;
case CMP_OP_LESS_THAN_EQUALS:
return cmpResult <= 0;
case CMP_OP_GREATER_THAN_EQUALS:
return cmpResult >= 0;
default :
throw new TemplateException("String_Node_Str" + operator,env);
}
}