Program: 86838
Project: 86838
Buggy source:
/** 
 * This method will parse the passed expression and return a value based on the following criteria:<br/> <ul> <li>Any string that matches a passed parameter will be replaced by the value of that parameter <li>If this date is followed by an expression, it will attempt to evaluate this by incrementing/decrementing days/weeks/months/years as specified</li> <li>Examples: Given 2 parameters: <ul> <li>report.startDate = java.util.Date with value of [2007-01-10] <li>report.gender = "male" </ul> The following should result:<br/> <br/> <pre> evaluateExpression("${report.startDate}") -> "2007-01-10" as Date evaluateExpression("${report.startDate+5d}") -> "2007-01-15" as Date evaluateExpression("${report.startDate-1w}") -> "2007-01-03" as Date evaluateExpression("${report.startDate+3m}") -> "2007-04-15" as Date evaluateExpression("${report.startDate+1y}") -> "2008-01-10" as Date <pre> </ul>
 * @param expression
 * @return value for given expression, as an <code>Object</code>
 * @throws ParameterException
 */
public static Object evaluateExpression(String expression,Map<String,Object> parameters,Class<?> type) throws ParameterException {
  log.info("String_Node_Str" + expression);
  if (expression == null) {
    log.warn("String_Node_Str");
    return null;
  }
  List<Object> elements=new ArrayList<Object>();
  StringBuilder curr=new StringBuilder();
  char[] chars=expression.toCharArray();
  for (int i=0; i < chars.length; i++) {
    char c=chars[i];
    boolean isStartOfExpr=(c == '$' && chars.length > (i + 1) && chars[i + 1] == '{');
    if (isStartOfExpr || c == '}') {
      if (curr.length() > 0) {
        if (c == '}') {
          elements.add(evaluateParameterExpression(curr.toString(),parameters,type));
        }
 else {
          elements.add(curr.toString());
        }
        curr=new StringBuilder();
      }
      if (isStartOfExpr) {
        i++;
      }
    }
 else {
      curr.append(c);
    }
  }
  if (curr.length() > 0) {
    elements.add(curr.toString());
  }
  if (elements.size() == 1) {
    return elements.get(0);
  }
 else {
    if (type != null && type != String.class) {
      throw new ParameterException("String_Node_Str" + expression + "String_Node_Str"+ type);
    }
    StringBuilder sb=new StringBuilder();
    for (    Object o : elements) {
      sb.append(o.toString());
    }
    return sb.toString();
  }
}

Fixed version (ground truth):
/** 
 * This method will parse the passed expression and return a value based on the following criteria:<br/> <ul> <li>Any string that matches a passed parameter will be replaced by the value of that parameter <li>If this date is followed by an expression, it will attempt to evaluate this by incrementing/decrementing days/weeks/months/years as specified</li> <li>Examples: Given 2 parameters: <ul> <li>report.startDate = java.util.Date with value of [2007-01-10] <li>report.gender = "male" </ul> The following should result:<br/> <br/> <pre> evaluateExpression("${report.startDate}") -> "2007-01-10" as Date evaluateExpression("${report.startDate+5d}") -> "2007-01-15" as Date evaluateExpression("${report.startDate-1w}") -> "2007-01-03" as Date evaluateExpression("${report.startDate+3m}") -> "2007-04-15" as Date evaluateExpression("${report.startDate+1y}") -> "2008-01-10" as Date <pre> </ul>
 * @param expression
 * @return value for given expression, as an <code>Object</code>
 * @throws ParameterException
 */
public static Object evaluateExpression(String expression,Map<String,Object> parameters,Class<?> type) throws ParameterException {
  log.info("String_Node_Str" + expression);
  if (expression == null) {
    log.warn("String_Node_Str");
    return null;
  }
  List<Object> elements=new ArrayList<Object>();
  StringBuilder curr=new StringBuilder();
  char[] chars=expression.toCharArray();
  boolean inExpression=false;
  for (int i=0; i < chars.length; i++) {
    char c=chars[i];
    boolean isStartOfExpr=(c == '$' && chars.length > (i + 1) && chars[i + 1] == '{');
    if (isStartOfExpr) {
      if (curr.length() > 0) {
        elements.add(curr.toString());
        curr=new StringBuilder();
      }
      inExpression=true;
      i++;
    }
 else     if (c == '}' && inExpression) {
      if (curr.length() > 0) {
        elements.add(evaluateParameterExpression(curr.toString(),parameters,type));
        curr=new StringBuilder();
      }
      inExpression=false;
    }
 else {
      curr.append(c);
    }
  }
  if (curr.length() > 0) {
    elements.add(curr.toString());
  }
  if (elements.size() == 1) {
    return elements.get(0);
  }
 else {
    if (type != null && type != String.class) {
      throw new ParameterException("String_Node_Str" + expression + "String_Node_Str"+ type);
    }
    StringBuilder sb=new StringBuilder();
    for (    Object o : elements) {
      sb.append(o.toString());
    }
    return sb.toString();
  }
}