Program: 18110
Project: 18110
Buggy source:
public static String parseWhereExpression(final CommonExpression whereExpression) throws ODataException {
switch (whereExpression.getKind()) {
case UNARY:
    final UnaryExpression unaryExpression=(UnaryExpression)whereExpression;
  final String operand=parseWhereExpression(unaryExpression.getOperand());
switch (unaryExpression.getOperator()) {
case NOT:
  return Boolean.toString(!Boolean.parseBoolean(operand));
case MINUS:
if (operand.startsWith("String_Node_Str")) return operand.substring(1);
 else return "String_Node_Str" + operand;
default :
throw new ODataNotImplementedException();
}
case BINARY:
final BinaryExpression binaryExpression=(BinaryExpression)whereExpression;
final EdmSimpleType binaryType=(EdmSimpleType)binaryExpression.getEdmType();
final String left=parseWhereExpression(binaryExpression.getLeftOperand());
final String right=parseWhereExpression(binaryExpression.getRightOperand());
switch (binaryExpression.getOperator()) {
case ADD:
return Double.toString(Double.valueOf(left) + Double.valueOf(right));
case SUB:
return Double.toString(Double.valueOf(left) - Double.valueOf(right));
case MUL:
return Double.toString(Double.valueOf(left) * Double.valueOf(right));
case DIV:
return Double.toString(Double.valueOf(left) / Double.valueOf(right));
case MODULO:
return Double.toString(Double.valueOf(left) % Double.valueOf(right));
case AND:
return Boolean.toString(left.equals("String_Node_Str") && right.equals("String_Node_Str"));
case OR:
return Boolean.toString(left.equals("String_Node_Str") || right.equals("String_Node_Str"));
case EQ:
return left + OdataProcessorConstants.STRING_OPERATOR_EQ + right;
case NE:
return left + OdataProcessorConstants.STRING_OPERATOR_NE + right;
case LT:
return left + OdataProcessorConstants.STRING_OPERATOR_LT + right;
case LE:
return left + OdataProcessorConstants.STRING_OPERATOR_LE + right;
case GT:
return left + OdataProcessorConstants.STRING_OPERATOR_GT + right;
case GE:
return left + OdataProcessorConstants.STRING_OPERATOR_GE + right;
case PROPERTY_ACCESS:
throw new ODataNotImplementedException();
default :
throw new ODataNotImplementedException();
}
case PROPERTY:
return ((PropertyExpression)whereExpression).getPropertyName();
case LITERAL:
final LiteralExpression literal=(LiteralExpression)whereExpression;
final EdmSimpleType literalType=(EdmSimpleType)literal.getEdmType();
return literalType.getName();
case METHOD:
final MethodExpression methodExpression=(MethodExpression)whereExpression;
final String first=parseWhereExpression(methodExpression.getParameters().get(0));
final String second=methodExpression.getParameterCount() > 1 ? parseWhereExpression(methodExpression.getParameters().get(1)) : null;
final String third=methodExpression.getParameterCount() > 2 ? parseWhereExpression(methodExpression.getParameters().get(2)) : null;
switch (methodExpression.getMethod()) {
case ENDSWITH:
return Boolean.toString(first.endsWith(second));
case INDEXOF:
return Integer.toString(first.indexOf(second));
case STARTSWITH:
return Boolean.toString(first.startsWith(second));
case TOLOWER:
return first.toLowerCase(Locale.ROOT);
case TOUPPER:
return first.toUpperCase(Locale.ROOT);
case TRIM:
return first.trim();
case SUBSTRING:
final int offset=first.indexOf(second);
return first.substring(offset,offset + Integer.parseInt(third));
case SUBSTRINGOF:
return Boolean.toString(first.contains(second));
case CONCAT:
return first + second;
case LENGTH:
return Integer.toString(first.length());
case YEAR:
return String.valueOf(Integer.parseInt(first.substring(0,4)));
case MONTH:
return String.valueOf(Integer.parseInt(first.substring(5,7)));
case DAY:
return String.valueOf(Integer.parseInt(first.substring(8,10)));
case HOUR:
return String.valueOf(Integer.parseInt(first.substring(11,13)));
case MINUTE:
return String.valueOf(Integer.parseInt(first.substring(14,16)));
case SECOND:
return String.valueOf(Integer.parseInt(first.substring(17,19)));
case ROUND:
return Long.toString(Math.round(Double.valueOf(first)));
case FLOOR:
return Long.toString(Math.round(Math.floor(Double.valueOf(first))));
case CEILING:
return Long.toString(Math.round(Math.ceil(Double.valueOf(first))));
default :
throw new ODataNotImplementedException();
}
default :
throw new ODataNotImplementedException();
}
}

Fixed version (ground truth):
public static String parseWhereExpression(final CommonExpression whereExpression) throws ODataException {
switch (whereExpression.getKind()) {
case UNARY:
    final UnaryExpression unaryExpression=(UnaryExpression)whereExpression;
  final String operand=parseWhereExpression(unaryExpression.getOperand());
switch (unaryExpression.getOperator()) {
case NOT:
  return Boolean.toString(!Boolean.parseBoolean(operand));
case MINUS:
if (operand.startsWith("String_Node_Str")) return operand.substring(1);
 else return "String_Node_Str" + operand;
default :
throw new ODataNotImplementedException();
}
case BINARY:
final BinaryExpression binaryExpression=(BinaryExpression)whereExpression;
final EdmSimpleType binaryType=(EdmSimpleType)binaryExpression.getEdmType();
final String left=parseWhereExpression(binaryExpression.getLeftOperand());
final String right=parseWhereExpression(binaryExpression.getRightOperand());
switch (binaryExpression.getOperator()) {
case ADD:
return Double.toString(Double.valueOf(left) + Double.valueOf(right));
case SUB:
return Double.toString(Double.valueOf(left) - Double.valueOf(right));
case MUL:
return Double.toString(Double.valueOf(left) * Double.valueOf(right));
case DIV:
return Double.toString(Double.valueOf(left) / Double.valueOf(right));
case MODULO:
return Double.toString(Double.valueOf(left) % Double.valueOf(right));
case AND:
return Boolean.toString(left.equals("String_Node_Str") && right.equals("String_Node_Str"));
case OR:
return Boolean.toString(left.equals("String_Node_Str") || right.equals("String_Node_Str"));
case EQ:
return left + JPQLStatement.Operator.EQ + right;
case NE:
return left + JPQLStatement.Operator.NE + right;
case LT:
return left + JPQLStatement.Operator.LT + right;
case LE:
return left + JPQLStatement.Operator.LE + right;
case GT:
return left + JPQLStatement.Operator.GT + right;
case GE:
return left + JPQLStatement.Operator.GE + right;
case PROPERTY_ACCESS:
throw new ODataNotImplementedException();
default :
throw new ODataNotImplementedException();
}
case PROPERTY:
return ((PropertyExpression)whereExpression).getPropertyName();
case LITERAL:
final LiteralExpression literal=(LiteralExpression)whereExpression;
final EdmSimpleType literalType=(EdmSimpleType)literal.getEdmType();
return literalType.getName();
case METHOD:
final MethodExpression methodExpression=(MethodExpression)whereExpression;
final String first=parseWhereExpression(methodExpression.getParameters().get(0));
final String second=methodExpression.getParameterCount() > 1 ? parseWhereExpression(methodExpression.getParameters().get(1)) : null;
final String third=methodExpression.getParameterCount() > 2 ? parseWhereExpression(methodExpression.getParameters().get(2)) : null;
switch (methodExpression.getMethod()) {
case ENDSWITH:
return Boolean.toString(first.endsWith(second));
case INDEXOF:
return Integer.toString(first.indexOf(second));
case STARTSWITH:
return Boolean.toString(first.startsWith(second));
case TOLOWER:
return first.toLowerCase(Locale.ROOT);
case TOUPPER:
return first.toUpperCase(Locale.ROOT);
case TRIM:
return first.trim();
case SUBSTRING:
final int offset=first.indexOf(second);
return first.substring(offset,offset + Integer.parseInt(third));
case SUBSTRINGOF:
return Boolean.toString(first.contains(second));
case CONCAT:
return first + second;
case LENGTH:
return Integer.toString(first.length());
case YEAR:
return String.valueOf(Integer.parseInt(first.substring(0,4)));
case MONTH:
return String.valueOf(Integer.parseInt(first.substring(5,7)));
case DAY:
return String.valueOf(Integer.parseInt(first.substring(8,10)));
case HOUR:
return String.valueOf(Integer.parseInt(first.substring(11,13)));
case MINUTE:
return String.valueOf(Integer.parseInt(first.substring(14,16)));
case SECOND:
return String.valueOf(Integer.parseInt(first.substring(17,19)));
case ROUND:
return Long.toString(Math.round(Double.valueOf(first)));
case FLOOR:
return Long.toString(Math.round(Math.floor(Double.valueOf(first))));
case CEILING:
return Long.toString(Math.round(Math.ceil(Double.valueOf(first))));
default :
throw new ODataNotImplementedException();
}
default :
throw new ODataNotImplementedException();
}
}