Program: 75073
Project: 75073
Buggy source:
/** 
 * Handle a class declaration or anonymous class declaration. Records and assignment methods are added to the declaration.
 * @param node The AST node of class declaration or anonymous classdeclaration.
 * @param bodyDeclarations The list of body declarations in the class.
 * @param state The current state of the type analyzer.
 */
private void _handleDeclaration(ASTNode node,List bodyDeclarations,TypeAnalyzerState state){
  Class currentClass=state.getCurrentClass();
  Class parent=currentClass.getSuperclass();
  List newMethods=new LinkedList();
  List newFields=new LinkedList();
  AST ast=node.getAST();
  CompilationUnit root=(CompilationUnit)node.getRoot();
  List fieldNames=new LinkedList();
  List fieldTypes=new LinkedList();
  Iterator bodyIter=bodyDeclarations.iterator();
  while (bodyIter.hasNext()) {
    Object nextDeclaration=bodyIter.next();
    if (nextDeclaration instanceof FieldDeclaration) {
      FieldDeclaration fieldDecl=(FieldDeclaration)nextDeclaration;
      boolean isStatic=Modifier.isStatic(fieldDecl.getModifiers());
      if (isStatic && HANDLE_STATIC_FIELDS != true)       continue;
      if (Modifier.isPrivate(fieldDecl.getModifiers())) {
        Type type=Type.getType(fieldDecl);
        Iterator fragmentIter=fieldDecl.fragments().iterator();
        while (fragmentIter.hasNext()) {
          VariableDeclarationFragment fragment=(VariableDeclarationFragment)fragmentIter.next();
          String fieldName=fragment.getName().getIdentifier();
          Hashtable[] tables=new Hashtable[]{_accessedFields,_specialAccessedFields,_backupFields};
          for (int i=0; i < tables.length; i++) {
            List indicesList=_getAccessedField(tables[i],currentClass.getName(),fieldName);
            if (indicesList == null)             continue;
            Iterator indicesIter=indicesList.iterator();
            while (indicesIter.hasNext()) {
              int indices=((Integer)indicesIter.next()).intValue();
              if (tables[i] == _backupFields)               newMethods.add(_createBackupMethod(ast,root,state,fieldName,type,indices,isStatic));
 else               newMethods.add(_createAssignMethod(ast,root,state,fieldName,type,indices,tables[i] == _specialAccessedFields,isStatic));
            }
          }
          fieldNames.add(fieldName);
          fieldTypes.add(type);
          FieldDeclaration field=_createFieldRecord(ast,root,state,fieldName,type.dimensions(),isStatic);
          if (field != null)           newFields.add(field);
        }
      }
    }
  }
  boolean isInterface=node instanceof TypeDeclaration && ((TypeDeclaration)node).isInterface();
  boolean isAnonymous=node instanceof AnonymousClassDeclaration;
  if (isAnonymous) {
    Class[] interfaces=currentClass.getInterfaces();
    for (int i=0; i < interfaces.length; i++)     if (state.getCrossAnalyzedTypes().contains(interfaces[i].getName()))     isAnonymous=false;
  }
  if (!_isInStaticMethod.isEmpty() && _isInStaticMethod.peek() == Boolean.TRUE && isAnonymous)   return;
  if (!isInterface)   newFields.add(_createRecordArray(ast,root,state,fieldNames));
  newMethods.add(_createRestoreMethod(ast,root,state,fieldNames,fieldTypes,isAnonymous,isInterface));
  MethodDeclaration getCheckpoint=_createGetCheckpointMethod(ast,root,state,isAnonymous,isInterface);
  if (getCheckpoint != null)   newMethods.add(getCheckpoint);
  MethodDeclaration setCheckpoint=_createSetCheckpointMethod(ast,root,state,isAnonymous,isInterface);
  if (setCheckpoint != null)   newMethods.add(setCheckpoint);
  if (isAnonymous)   bodyDeclarations.add(_createProxyClass(ast,root,state));
 else {
    if (node instanceof TypeDeclaration) {
      String rollbackType=getClassName(Rollbackable.class,state,root);
      ((TypeDeclaration)node).superInterfaces().add(createName(ast,rollbackType));
    }
    if (!isInterface) {
      FieldDeclaration checkpointField=_createCheckpointField(ast,root,state);
      if (checkpointField != null)       bodyDeclarations.add(0,checkpointField);
      FieldDeclaration record=_createCheckpointRecord(ast,root,state);
      if (record != null)       newFields.add(0,record);
    }
  }
  bodyDeclarations.addAll(newMethods);
  bodyDeclarations.addAll(newFields);
  if (isAnonymous) {
    Initializer initializer=ast.newInitializer();
    Block body=ast.newBlock();
    initializer.setBody(body);
    MethodInvocation addInvocation=ast.newMethodInvocation();
    addInvocation.setExpression(ast.newSimpleName(CHECKPOINT_NAME));
    addInvocation.setName(ast.newSimpleName("String_Node_Str"));
    ClassInstanceCreation proxy=ast.newClassInstanceCreation();
    proxy.setName(ast.newSimpleName(_getProxyName()));
    addInvocation.arguments().add(proxy);
    body.statements().add(ast.newExpressionStatement(addInvocation));
    bodyDeclarations.add(initializer);
  }
}

Fixed version (ground truth):
/** 
 * Handle a class declaration or anonymous class declaration. Records and assignment methods are added to the declaration.
 * @param node The AST node of class declaration or anonymous classdeclaration.
 * @param bodyDeclarations The list of body declarations in the class.
 * @param state The current state of the type analyzer.
 */
private void _handleDeclaration(ASTNode node,List bodyDeclarations,TypeAnalyzerState state){
  Class currentClass=state.getCurrentClass();
  Class parent=currentClass.getSuperclass();
  List newMethods=new LinkedList();
  List newFields=new LinkedList();
  AST ast=node.getAST();
  CompilationUnit root=(CompilationUnit)node.getRoot();
  List fieldNames=new LinkedList();
  List fieldTypes=new LinkedList();
  Iterator bodyIter=bodyDeclarations.iterator();
  while (bodyIter.hasNext()) {
    Object nextDeclaration=bodyIter.next();
    if (nextDeclaration instanceof FieldDeclaration) {
      FieldDeclaration fieldDecl=(FieldDeclaration)nextDeclaration;
      boolean isStatic=Modifier.isStatic(fieldDecl.getModifiers());
      if (isStatic && HANDLE_STATIC_FIELDS != true)       continue;
      if (Modifier.isPrivate(fieldDecl.getModifiers())) {
        Type type=Type.getType(fieldDecl);
        Iterator fragmentIter=fieldDecl.fragments().iterator();
        while (fragmentIter.hasNext()) {
          VariableDeclarationFragment fragment=(VariableDeclarationFragment)fragmentIter.next();
          String fieldName=fragment.getName().getIdentifier();
          Hashtable[] tables=new Hashtable[]{_accessedFields,_specialAccessedFields,_backupFields};
          for (int i=0; i < tables.length; i++) {
            List indicesList=_getAccessedField(tables[i],currentClass.getName(),fieldName);
            if (indicesList == null)             continue;
            Iterator indicesIter=indicesList.iterator();
            while (indicesIter.hasNext()) {
              int indices=((Integer)indicesIter.next()).intValue();
              if (tables[i] == _backupFields)               newMethods.add(_createBackupMethod(ast,root,state,fieldName,type,indices,isStatic));
 else               newMethods.add(_createAssignMethod(ast,root,state,fieldName,type,indices,tables[i] == _specialAccessedFields,isStatic));
            }
          }
          fieldNames.add(fieldName);
          fieldTypes.add(type);
          FieldDeclaration field=_createFieldRecord(ast,root,state,fieldName,type.dimensions(),isStatic);
          if (field != null)           newFields.add(field);
        }
      }
    }
  }
  boolean isInterface=node instanceof TypeDeclaration && ((TypeDeclaration)node).isInterface();
  boolean isAnonymous=node instanceof AnonymousClassDeclaration;
  if (isAnonymous) {
    Class[] interfaces=currentClass.getInterfaces();
    for (int i=0; i < interfaces.length; i++)     if (state.getCrossAnalyzedTypes().contains(interfaces[i].getName()))     isAnonymous=false;
  }
  RehandleDeclarationRecord declarationRecord=null;
  if (isAnonymous) {
    Class[] interfaces=currentClass.getInterfaces();
    if (interfaces.length == 1) {
      declarationRecord=new RehandleDeclarationRecord(bodyDeclarations);
      addToLists(_rehandleDeclaration,interfaces[0].getName(),declarationRecord);
    }
  }
  boolean ignore=!_isInStaticMethod.isEmpty() && _isInStaticMethod.peek() == Boolean.TRUE && isAnonymous;
  if (!isInterface && !ignore)   newFields.add(_createRecordArray(ast,root,state,fieldNames));
  MethodDeclaration restoreMethod=null;
  if (!ignore) {
    restoreMethod=_createRestoreMethod(ast,root,state,fieldNames,fieldTypes,isAnonymous,isInterface);
    newMethods.add(restoreMethod);
  }
  if (declarationRecord != null) {
    if (!ignore)     declarationRecord._addExtendedDeclaration(restoreMethod);
    MethodDeclaration fixedRestoreMethod=_createRestoreMethod(ast,root,state,fieldNames,fieldTypes,false,isInterface);
    declarationRecord._addFixedDeclaration(fixedRestoreMethod);
  }
  MethodDeclaration getCheckpoint=null;
  if (!ignore) {
    getCheckpoint=_createGetCheckpointMethod(ast,root,state,isAnonymous,isInterface);
    if (getCheckpoint != null)     newMethods.add(getCheckpoint);
  }
  if (declarationRecord != null) {
    if (!ignore)     declarationRecord._addExtendedDeclaration(getCheckpoint);
    MethodDeclaration fixedGetCheckpoint=_createGetCheckpointMethod(ast,root,state,false,isInterface);
    declarationRecord._addFixedDeclaration(fixedGetCheckpoint);
  }
  MethodDeclaration setCheckpoint=null;
  if (!ignore) {
    setCheckpoint=_createSetCheckpointMethod(ast,root,state,isAnonymous,isInterface);
    if (setCheckpoint != null)     newMethods.add(setCheckpoint);
  }
  if (declarationRecord != null) {
    if (!ignore)     declarationRecord._addExtendedDeclaration(setCheckpoint);
    MethodDeclaration fixedSetCheckpoint=_createSetCheckpointMethod(ast,root,state,false,isInterface);
    declarationRecord._addFixedDeclaration(fixedSetCheckpoint);
  }
  if (!ignore) {
    if (isAnonymous) {
      TypeDeclaration proxy=_createProxyClass(ast,root,state);
      bodyDeclarations.add(proxy);
      if (declarationRecord != null)       declarationRecord._addExtendedDeclaration(proxy);
    }
 else {
      if (node instanceof TypeDeclaration) {
        String rollbackType=getClassName(Rollbackable.class,state,root);
        ((TypeDeclaration)node).superInterfaces().add(createName(ast,rollbackType));
      }
      if (!isInterface) {
        FieldDeclaration checkpointField=_createCheckpointField(ast,root,state);
        if (checkpointField != null)         bodyDeclarations.add(0,checkpointField);
        FieldDeclaration record=_createCheckpointRecord(ast,root,state);
        if (record != null)         newFields.add(0,record);
      }
    }
  }
  if (!ignore) {
    bodyDeclarations.addAll(newMethods);
    bodyDeclarations.addAll(newFields);
  }
 else {
    if (declarationRecord != null) {
      declarationRecord._addFixedDeclarations(newMethods);
      declarationRecord._addFixedDeclarations(newFields);
    }
  }
  if (isAnonymous && !ignore) {
    Initializer initializer=ast.newInitializer();
    Block body=ast.newBlock();
    initializer.setBody(body);
    MethodInvocation addInvocation=ast.newMethodInvocation();
    addInvocation.setExpression(ast.newSimpleName(CHECKPOINT_NAME));
    addInvocation.setName(ast.newSimpleName("String_Node_Str"));
    ClassInstanceCreation proxy=ast.newClassInstanceCreation();
    proxy.setName(ast.newSimpleName(_getProxyName()));
    addInvocation.arguments().add(proxy);
    body.statements().add(ast.newExpressionStatement(addInvocation));
    bodyDeclarations.add(initializer);
    if (declarationRecord != null)     declarationRecord._addExtendedDeclaration(initializer);
  }
}