Program: 75103
Project: 75103
Buggy source:
/** 
 * Create a restore method for a class, which restores all its state variables.
 * @param ast The {@link AST} object.
 * @param root The root of the AST.
 * @param state The current state of the type analyzer.
 * @param fieldNames The list of all the accessed fields.
 * @param fieldTypes The types corresponding to the accessed fields.
 * @param isAnonymous Whether the current class is anonymous.
 * @return The declaration of the method that restores the old valueof all the private fields.
 */
private MethodDeclaration _createRestoreMethod(AST ast,CompilationUnit root,TypeAnalyzerState state,List fieldNames,List fieldTypes,boolean isAnonymous){
  Class currentClass=state.getCurrentClass();
  Class parent=currentClass.getSuperclass();
  String methodName=_getRestoreMethodName(isAnonymous);
  if (hasMethod(currentClass,methodName,new Class[]{int.class,boolean.class},true))   throw new ASTDuplicatedMethodException(currentClass.getName(),methodName);
  MethodDeclaration method=ast.newMethodDeclaration();
  method.setName(ast.newSimpleName(methodName));
  SingleVariableDeclaration timestamp=ast.newSingleVariableDeclaration();
  timestamp.setType(ast.newPrimitiveType(PrimitiveType.LONG));
  timestamp.setName(ast.newSimpleName("String_Node_Str"));
  method.parameters().add(timestamp);
  SingleVariableDeclaration trim=ast.newSingleVariableDeclaration();
  trim.setType(ast.newPrimitiveType(PrimitiveType.BOOLEAN));
  trim.setName(ast.newSimpleName("String_Node_Str"));
  method.parameters().add(trim);
  Block body=ast.newBlock();
  method.setBody(body);
  if (parent != null && (state.getCrossAnalyzedTypes().contains(parent.getName()) || hasMethod(parent,methodName,new Class[]{int.class,boolean.class}))) {
    SuperMethodInvocation superRestore=ast.newSuperMethodInvocation();
    superRestore.setName(ast.newSimpleName(_getRestoreMethodName(false)));
    superRestore.arguments().add(ast.newSimpleName("String_Node_Str"));
    superRestore.arguments().add(ast.newSimpleName("String_Node_Str"));
    body.statements().add(ast.newExpressionStatement(superRestore));
  }
 else   addToLists(_fixParentRestoreMethods,parent.getName(),body);
  Iterator namesIter=fieldNames.iterator();
  Iterator typesIter=fieldTypes.iterator();
  while (namesIter.hasNext()) {
    String fieldName=(String)namesIter.next();
    Type fieldType=(Type)typesIter.next();
    if (_getAccessedField(currentClass.getName(),fieldName) == null)     continue;
    MethodInvocation restoreMethodCall=ast.newMethodInvocation();
    restoreMethodCall.setExpression(ast.newSimpleName(_getRecordName(fieldName)));
    restoreMethodCall.arguments().add(ast.newSimpleName(fieldName));
    restoreMethodCall.setName(ast.newSimpleName("String_Node_Str"));
    restoreMethodCall.arguments().add(ast.newSimpleName("String_Node_Str"));
    restoreMethodCall.arguments().add(ast.newSimpleName("String_Node_Str"));
    boolean isFinal=false;
    try {
      Field field=currentClass.getDeclaredField(fieldName);
      if (java.lang.reflect.Modifier.isFinal(field.getModifiers()))       isFinal=true;
    }
 catch (    NoSuchFieldException e) {
    }
    if (isFinal)     body.statements().add(ast.newExpressionStatement(restoreMethodCall));
 else {
      Expression rightHandSide;
      if (fieldType.isPrimitive())       rightHandSide=restoreMethodCall;
 else {
        CastExpression castExpression=ast.newCastExpression();
        String typeName=getClassName(fieldType.getName(),state,root);
        castExpression.setType(createType(ast,typeName));
        castExpression.setExpression(restoreMethodCall);
        rightHandSide=castExpression;
      }
      Assignment assignment=ast.newAssignment();
      assignment.setLeftHandSide(ast.newSimpleName(fieldName));
      assignment.setRightHandSide(rightHandSide);
      body.statements().add(ast.newExpressionStatement(assignment));
    }
  }
  IfStatement restoreCheckpoint=ast.newIfStatement();
  InfixExpression timestampTester=ast.newInfixExpression();
  timestampTester.setLeftOperand(ast.newSimpleName("String_Node_Str"));
  timestampTester.setOperator(InfixExpression.Operator.LESS_EQUALS);
  MethodInvocation topTimestamp=ast.newMethodInvocation();
  topTimestamp.setExpression(ast.newSimpleName(CHECKPOINT_RECORD_NAME));
  topTimestamp.setName(ast.newSimpleName("String_Node_Str"));
  timestampTester.setRightOperand(topTimestamp);
  restoreCheckpoint.setExpression(timestampTester);
  Block restoreBlock=ast.newBlock();
  restoreCheckpoint.setThenStatement(restoreBlock);
  Assignment assignCheckpoint=ast.newAssignment();
  assignCheckpoint.setLeftHandSide(ast.newSimpleName(CHECKPOINT_NAME));
  MethodInvocation restoreCheckpointInvocation=ast.newMethodInvocation();
  restoreCheckpointInvocation.setExpression(ast.newSimpleName(CHECKPOINT_RECORD_NAME));
  restoreCheckpointInvocation.setName(ast.newSimpleName("String_Node_Str"));
  restoreCheckpointInvocation.arguments().add(ast.newSimpleName(CHECKPOINT_NAME));
  restoreCheckpointInvocation.arguments().add(_createRollbackableObject(ast,isAnonymous));
  restoreCheckpointInvocation.arguments().add(ast.newSimpleName("String_Node_Str"));
  restoreCheckpointInvocation.arguments().add(ast.newSimpleName("String_Node_Str"));
  assignCheckpoint.setRightHandSide(restoreCheckpointInvocation);
  restoreBlock.statements().add(ast.newExpressionStatement(assignCheckpoint));
  MethodInvocation popStates=ast.newMethodInvocation();
  String recordType=getClassName(FieldRecord.class,state,root);
  popStates.setExpression(createName(ast,recordType));
  popStates.setName(ast.newSimpleName("String_Node_Str"));
  popStates.arguments().add(ast.newSimpleName(RECORDS_NAME));
  restoreBlock.statements().add(ast.newExpressionStatement(popStates));
  body.statements().add(restoreCheckpoint);
  method.setModifiers(Modifier.PUBLIC);
  return method;
}

Fixed version (ground truth):
/** 
 * Create a restore method for a class, which restores all its state variables.
 * @param ast The {@link AST} object.
 * @param root The root of the AST.
 * @param state The current state of the type analyzer.
 * @param fieldNames The list of all the accessed fields.
 * @param fieldTypes The types corresponding to the accessed fields.
 * @param isAnonymous Whether the current class is anonymous.
 * @return The declaration of the method that restores the old valueof all the private fields.
 */
private MethodDeclaration _createRestoreMethod(AST ast,CompilationUnit root,TypeAnalyzerState state,List fieldNames,List fieldTypes,boolean isAnonymous){
  Class currentClass=state.getCurrentClass();
  Class parent=currentClass.getSuperclass();
  String methodName=_getRestoreMethodName(isAnonymous);
  if (hasMethod(currentClass,methodName,new Class[]{int.class,boolean.class},true))   throw new ASTDuplicatedMethodException(currentClass.getName(),methodName);
  MethodDeclaration method=ast.newMethodDeclaration();
  method.setName(ast.newSimpleName(methodName));
  SingleVariableDeclaration timestamp=ast.newSingleVariableDeclaration();
  timestamp.setType(ast.newPrimitiveType(PrimitiveType.LONG));
  timestamp.setName(ast.newSimpleName("String_Node_Str"));
  method.parameters().add(timestamp);
  SingleVariableDeclaration trim=ast.newSingleVariableDeclaration();
  trim.setType(ast.newPrimitiveType(PrimitiveType.BOOLEAN));
  trim.setName(ast.newSimpleName("String_Node_Str"));
  method.parameters().add(trim);
  Block body=ast.newBlock();
  method.setBody(body);
  Iterator namesIter=fieldNames.iterator();
  Iterator typesIter=fieldTypes.iterator();
  while (namesIter.hasNext()) {
    String fieldName=(String)namesIter.next();
    Type fieldType=(Type)typesIter.next();
    if (_getAccessedField(currentClass.getName(),fieldName) == null)     continue;
    MethodInvocation restoreMethodCall=ast.newMethodInvocation();
    restoreMethodCall.setExpression(ast.newSimpleName(_getRecordName(fieldName)));
    restoreMethodCall.arguments().add(ast.newSimpleName(fieldName));
    restoreMethodCall.setName(ast.newSimpleName("String_Node_Str"));
    restoreMethodCall.arguments().add(ast.newSimpleName("String_Node_Str"));
    restoreMethodCall.arguments().add(ast.newSimpleName("String_Node_Str"));
    boolean isFinal=false;
    try {
      Field field=currentClass.getDeclaredField(fieldName);
      if (java.lang.reflect.Modifier.isFinal(field.getModifiers()))       isFinal=true;
    }
 catch (    NoSuchFieldException e) {
    }
    if (isFinal)     body.statements().add(ast.newExpressionStatement(restoreMethodCall));
 else {
      Expression rightHandSide;
      if (fieldType.isPrimitive())       rightHandSide=restoreMethodCall;
 else {
        CastExpression castExpression=ast.newCastExpression();
        String typeName=getClassName(fieldType.getName(),state,root);
        castExpression.setType(createType(ast,typeName));
        castExpression.setExpression(restoreMethodCall);
        rightHandSide=castExpression;
      }
      Assignment assignment=ast.newAssignment();
      assignment.setLeftHandSide(ast.newSimpleName(fieldName));
      assignment.setRightHandSide(rightHandSide);
      body.statements().add(ast.newExpressionStatement(assignment));
    }
  }
  if (parent != null && (state.getCrossAnalyzedTypes().contains(parent.getName()) || hasMethod(parent,methodName,new Class[]{int.class,boolean.class}))) {
    SuperMethodInvocation superRestore=ast.newSuperMethodInvocation();
    superRestore.setName(ast.newSimpleName(_getRestoreMethodName(false)));
    superRestore.arguments().add(ast.newSimpleName("String_Node_Str"));
    superRestore.arguments().add(ast.newSimpleName("String_Node_Str"));
    body.statements().add(ast.newExpressionStatement(superRestore));
  }
 else {
    IfStatement restoreCheckpoint=ast.newIfStatement();
    InfixExpression timestampTester=ast.newInfixExpression();
    timestampTester.setLeftOperand(ast.newSimpleName("String_Node_Str"));
    timestampTester.setOperator(InfixExpression.Operator.LESS_EQUALS);
    MethodInvocation topTimestamp=ast.newMethodInvocation();
    topTimestamp.setExpression(ast.newSimpleName(CHECKPOINT_RECORD_NAME));
    topTimestamp.setName(ast.newSimpleName("String_Node_Str"));
    timestampTester.setRightOperand(topTimestamp);
    restoreCheckpoint.setExpression(timestampTester);
    Block restoreBlock=ast.newBlock();
    restoreCheckpoint.setThenStatement(restoreBlock);
    Assignment assignCheckpoint=ast.newAssignment();
    assignCheckpoint.setLeftHandSide(ast.newSimpleName(CHECKPOINT_NAME));
    MethodInvocation restoreCheckpointInvocation=ast.newMethodInvocation();
    restoreCheckpointInvocation.setExpression(ast.newSimpleName(CHECKPOINT_RECORD_NAME));
    restoreCheckpointInvocation.setName(ast.newSimpleName("String_Node_Str"));
    restoreCheckpointInvocation.arguments().add(ast.newSimpleName(CHECKPOINT_NAME));
    restoreCheckpointInvocation.arguments().add(_createRollbackableObject(ast,isAnonymous));
    restoreCheckpointInvocation.arguments().add(ast.newSimpleName("String_Node_Str"));
    restoreCheckpointInvocation.arguments().add(ast.newSimpleName("String_Node_Str"));
    assignCheckpoint.setRightHandSide(restoreCheckpointInvocation);
    restoreBlock.statements().add(ast.newExpressionStatement(assignCheckpoint));
    MethodInvocation popStates=ast.newMethodInvocation();
    String recordType=getClassName(FieldRecord.class,state,root);
    popStates.setExpression(createName(ast,recordType));
    popStates.setName(ast.newSimpleName("String_Node_Str"));
    popStates.arguments().add(ast.newSimpleName(RECORDS_NAME));
    restoreBlock.statements().add(ast.newExpressionStatement(popStates));
    body.statements().add(restoreCheckpoint);
    addToLists(_fixParentRestoreMethods,parent.getName(),body);
  }
  method.setModifiers(Modifier.PUBLIC);
  return method;
}