Program: 75090
Project: 75090
Buggy source:
/** 
 * Handle an alias expression. If the expression is not aliased (e.g., an expression corresponding to an object or a primitive integer cannot be aliased), nothing is done. If it can be aliased, in the refactored result, the expression's <tt>clone</tt> method is called and the copy is used as the record.
 * @param node The node that may be aliased.
 * @param state The current state of the type analyzer.
 * @return The new node if the given node is an alias, or <tt>null</tt>otherwise.
 */
private Expression _handleAlias(Expression node,TypeAnalyzerState state){
  Type owner=Type.getOwner(node);
  if (owner == null)   return null;
  String ownerName=owner.getName();
  Type type=Type.getType(node);
  String typeName=type.getName();
  Expression array=node;
  Type arrayType=type;
  boolean needRefactor=type.isArray();
  if (node instanceof ArrayAccess) {
    ArrayAccess arrayAccess=(ArrayAccess)node;
    while (arrayAccess.getArray() instanceof ArrayAccess) {
      arrayAccess=(ArrayAccess)arrayAccess.getArray();
      arrayType=arrayType.addOneDimension();
    }
    array=arrayAccess.getArray();
    arrayType=arrayType.addOneDimension();
    if (array instanceof MethodInvocation)     needRefactor=false;
  }
  if (needRefactor)   if (state.getCurrentClass().getName().equals(ownerName))   needRefactor=true;
 else {
    Iterator previousClasses=state.getPreviousClasses().iterator();
    while (previousClasses.hasNext()) {
      Class previous=(Class)previousClasses.next();
      if (previous != null && previous.getName().equals(ownerName))       needRefactor=true;
    }
  }
  if (needRefactor) {
    AST ast=node.getAST();
    CompilationUnit root=(CompilationUnit)node.getRoot();
    String typeClassName=getClassName(typeName,state,root);
    int nIndices=0;
    Expression nodeIterator=node;
    while (nodeIterator instanceof ParenthesizedExpression)     nodeIterator=((ParenthesizedExpression)nodeIterator).getExpression();
    List indices=new LinkedList();
    while (nodeIterator instanceof ArrayAccess) {
      nIndices++;
      ArrayAccess arrayAccess=(ArrayAccess)nodeIterator;
      indices.add(0,ASTNode.copySubtree(ast,arrayAccess.getIndex()));
      nodeIterator=arrayAccess.getArray();
      while (nodeIterator instanceof ParenthesizedExpression)       nodeIterator=((ParenthesizedExpression)nodeIterator).getExpression();
    }
    Expression newObject=null;
    SimpleName name;
    if (nodeIterator instanceof FieldAccess) {
      Expression object=((FieldAccess)nodeIterator).getExpression();
      name=((FieldAccess)nodeIterator).getName();
      newObject=(Expression)ASTNode.copySubtree(ast,object);
    }
 else     if (nodeIterator instanceof QualifiedName) {
      Name object=((QualifiedName)nodeIterator).getQualifier();
      name=((QualifiedName)nodeIterator).getName();
      newObject=(Expression)ASTNode.copySubtree(ast,object);
    }
 else     if (nodeIterator instanceof SimpleName)     name=(SimpleName)nodeIterator;
 else     return null;
    Class ownerClass;
    boolean isStatic;
    try {
      ownerClass=owner.toClass(state.getClassLoader());
      Field field=ownerClass.getDeclaredField(name.getIdentifier());
      int modifiers=field.getModifiers();
      if (!java.lang.reflect.Modifier.isPrivate(modifiers))       return null;
      isStatic=java.lang.reflect.Modifier.isStatic(modifiers);
    }
 catch (    ClassNotFoundException e) {
      throw new ASTClassNotFoundException(owner.getName());
    }
catch (    NoSuchFieldException e) {
      return null;
    }
    if (isStatic && !HANDLE_STATIC_FIELDS)     return null;
    MethodInvocation backup=ast.newMethodInvocation();
    if (newObject != null)     backup.setExpression(newObject);
    SimpleName newName=ast.newSimpleName(_getBackupMethodName(name.getIdentifier()));
    backup.setName(newName);
    if (isStatic)     backup.arguments().add(ast.newSimpleName(CHECKPOINT_NAME));
    backup.arguments().addAll(indices);
    replaceNode(node,backup);
    _recordField(_backupFields,owner.getName(),name.getIdentifier(),nIndices);
    return backup;
  }
  return null;
}

Fixed version (ground truth):
/** 
 * Handle an alias expression. If the expression is not aliased (e.g., an expression corresponding to an object or a primitive integer cannot be aliased), nothing is done. If it can be aliased, in the refactored result, the expression's <tt>clone</tt> method is called and the copy is used as the record.
 * @param node The node that may be aliased.
 * @param state The current state of the type analyzer.
 * @return The new node if the given node is an alias, or <tt>null</tt>otherwise.
 */
private Expression _handleAlias(Expression node,TypeAnalyzerState state){
  Type owner=Type.getOwner(node);
  if (owner == null)   return null;
  String ownerName=owner.getName();
  Type type=Type.getType(node);
  String typeName=type.getName();
  Expression array=node;
  Type arrayType=type;
  boolean needRefactor=type.isArray();
  if (node instanceof ArrayAccess) {
    ArrayAccess arrayAccess=(ArrayAccess)node;
    while (arrayAccess.getArray() instanceof ArrayAccess) {
      arrayAccess=(ArrayAccess)arrayAccess.getArray();
      arrayType=arrayType.addOneDimension();
    }
    array=arrayAccess.getArray();
    arrayType=arrayType.addOneDimension();
    if (array instanceof MethodInvocation)     needRefactor=false;
  }
  if (needRefactor) {
    AST ast=node.getAST();
    CompilationUnit root=(CompilationUnit)node.getRoot();
    String typeClassName=getClassName(typeName,state,root);
    int nIndices=0;
    Expression nodeIterator=node;
    while (nodeIterator instanceof ParenthesizedExpression)     nodeIterator=((ParenthesizedExpression)nodeIterator).getExpression();
    List indices=new LinkedList();
    while (nodeIterator instanceof ArrayAccess) {
      nIndices++;
      ArrayAccess arrayAccess=(ArrayAccess)nodeIterator;
      indices.add(0,ASTNode.copySubtree(ast,arrayAccess.getIndex()));
      nodeIterator=arrayAccess.getArray();
      while (nodeIterator instanceof ParenthesizedExpression)       nodeIterator=((ParenthesizedExpression)nodeIterator).getExpression();
    }
    Expression newObject=null;
    SimpleName name;
    if (nodeIterator instanceof FieldAccess) {
      Expression object=((FieldAccess)nodeIterator).getExpression();
      name=((FieldAccess)nodeIterator).getName();
      newObject=(Expression)ASTNode.copySubtree(ast,object);
    }
 else     if (nodeIterator instanceof QualifiedName) {
      Name object=((QualifiedName)nodeIterator).getQualifier();
      name=((QualifiedName)nodeIterator).getName();
      newObject=(Expression)ASTNode.copySubtree(ast,object);
    }
 else     if (nodeIterator instanceof SimpleName)     name=(SimpleName)nodeIterator;
 else     return null;
    Class ownerClass;
    boolean isStatic;
    try {
      ownerClass=owner.toClass(state.getClassLoader());
      Field field=ownerClass.getDeclaredField(name.getIdentifier());
      int modifiers=field.getModifiers();
      if (!java.lang.reflect.Modifier.isPrivate(modifiers))       return null;
      isStatic=java.lang.reflect.Modifier.isStatic(modifiers);
    }
 catch (    ClassNotFoundException e) {
      throw new ASTClassNotFoundException(owner.getName());
    }
catch (    NoSuchFieldException e) {
      return null;
    }
    if (isStatic && !HANDLE_STATIC_FIELDS)     return null;
    MethodInvocation backup=ast.newMethodInvocation();
    if (newObject != null)     backup.setExpression(newObject);
    SimpleName newName=ast.newSimpleName(_getBackupMethodName(name.getIdentifier()));
    backup.setName(newName);
    if (isStatic)     backup.arguments().add(ast.newSimpleName(CHECKPOINT_NAME));
    backup.arguments().addAll(indices);
    replaceNode(node,backup);
    _recordField(_backupFields,owner.getName(),name.getIdentifier(),nIndices);
    return backup;
  }
  return null;
}