Program: 75095
Project: 75095
Buggy source:
/** 
 * Handle an explicit or implicit assignment node. An explicit assignment is one that uses the "=" operator or any special assign operator (such as "+=" and "-="). An implicit a prefix expression or postfix expression with the "++" operator or the "--" operator.
 * @param node The AST node of the assignment. It must be of one of thefollowing types:  {@link Assignment},   {@link PostfixExpression}, and  {@link PrefixExpression}.
 * @param state The current state of the type analyzer.
 */
private void _handleAssignment(ASTNode node,TypeAnalyzerState state){
  AST ast=node.getAST();
  boolean isSpecial;
  if (node instanceof Assignment)   isSpecial=((Assignment)node).getOperator() != Assignment.Operator.ASSIGN;
 else   isSpecial=true;
  Expression leftHand, rightHand;
  if (node instanceof Assignment) {
    leftHand=((Assignment)node).getLeftHandSide();
    rightHand=((Assignment)node).getRightHandSide();
  }
 else   if (node instanceof PrefixExpression)   leftHand=rightHand=((PrefixExpression)node).getOperand();
 else   leftHand=rightHand=((PostfixExpression)node).getOperand();
  while (leftHand instanceof ParenthesizedExpression)   leftHand=((ParenthesizedExpression)leftHand).getExpression();
  List indices=new LinkedList();
  while (leftHand instanceof ArrayAccess) {
    ArrayAccess arrayAccess=(ArrayAccess)leftHand;
    indices.add(0,ASTNode.copySubtree(ast,arrayAccess.getIndex()));
    leftHand=arrayAccess.getArray();
    while (leftHand instanceof ParenthesizedExpression)     leftHand=((ParenthesizedExpression)leftHand).getExpression();
  }
  Expression newObject=null;
  SimpleName name;
  if (leftHand instanceof FieldAccess) {
    Expression object=((FieldAccess)leftHand).getExpression();
    name=((FieldAccess)leftHand).getName();
    Type type=Type.getType(object);
    if (!type.getName().equals(state.getCurrentClass().getName()))     return;
    newObject=(Expression)ASTNode.copySubtree(ast,object);
  }
 else   if (leftHand instanceof QualifiedName) {
    Name object=((QualifiedName)leftHand).getQualifier();
    name=((QualifiedName)leftHand).getName();
    Type type=Type.getType(object);
    if (!type.getName().equals(state.getCurrentClass().getName()))     return;
    newObject=(Expression)ASTNode.copySubtree(ast,object);
  }
 else   if (leftHand instanceof SimpleName)   name=(SimpleName)leftHand;
 else   return;
  Type owner=Type.getOwner(leftHand);
  if (owner == null)   return;
  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;
    isStatic=java.lang.reflect.Modifier.isStatic(modifiers);
  }
 catch (  ClassNotFoundException e) {
    throw new ASTClassNotFoundException(owner.getName());
  }
catch (  NoSuchFieldException e) {
    return;
  }
  if (isStatic && !HANDLE_STATIC_FIELDS)   return;
  MethodInvocation invocation=ast.newMethodInvocation();
  if (newObject != null)   invocation.setExpression(newObject);
  SimpleName newName=ast.newSimpleName(_getAssignMethodName(name.getIdentifier(),isSpecial));
  invocation.setName(newName);
  if (isStatic)   invocation.arguments().add(ast.newSimpleName(CHECKPOINT_NAME));
  Type type=Type.getType(node);
  if (isSpecial && _assignOperators.containsKey(type.getName())) {
    int i=0;
    String[] operators=(String[])_assignOperators.get(type.getName());
    String operator;
    if (node instanceof Assignment)     operator=((Assignment)node).getOperator().toString();
 else     if (node instanceof PrefixExpression)     operator=((PrefixExpression)node).getOperator().toString();
 else     operator=((PostfixExpression)node).getOperator().toString();
    for (; i < operators.length; i++)     if (operators[i].equals(operator))     break;
    if (node instanceof PrefixExpression)     i+=2;
    invocation.arguments().add(ast.newNumberLiteral(Integer.toString(i)));
  }
  invocation.arguments().addAll(indices);
  Type rightHandType=Type.getType(rightHand);
  if (!isSpecial && type.isPrimitive() && !type.equals(rightHandType)) {
    CastExpression castExpression=ast.newCastExpression();
    castExpression.setType(createType(ast,type.getName()));
    castExpression.setExpression((Expression)ASTNode.copySubtree(ast,rightHand));
    rightHand=castExpression;
  }
 else {
    rightHand=(Expression)ASTNode.copySubtree(ast,rightHand);
    if (isSpecial && type.getName().equals(String.class.getName()) && !type.equals(rightHandType)) {
      InfixExpression extraPlus=ast.newInfixExpression();
      extraPlus.setLeftOperand(ast.newStringLiteral());
      extraPlus.setOperator(InfixExpression.Operator.PLUS);
      extraPlus.setRightOperand(rightHand);
      rightHand=extraPlus;
    }
  }
  invocation.arguments().add(rightHand);
  Type.propagateType(invocation,node);
  replaceNode(node,invocation);
  Hashtable table=(node instanceof Assignment && ((Assignment)node).getOperator() == Assignment.Operator.ASSIGN) ? _accessedFields : _specialAccessedFields;
  _recordField(table,owner.getName(),name.getIdentifier(),indices.size());
}

Fixed version (ground truth):
/** 
 * Handle an explicit or implicit assignment node. An explicit assignment is one that uses the "=" operator or any special assign operator (such as "+=" and "-="). An implicit a prefix expression or postfix expression with the "++" operator or the "--" operator.
 * @param node The AST node of the assignment. It must be of one of thefollowing types:  {@link Assignment},   {@link PostfixExpression}, and  {@link PrefixExpression}.
 * @param state The current state of the type analyzer.
 */
private void _handleAssignment(ASTNode node,TypeAnalyzerState state){
  AST ast=node.getAST();
  boolean isSpecial;
  if (node instanceof Assignment)   isSpecial=((Assignment)node).getOperator() != Assignment.Operator.ASSIGN;
 else   isSpecial=true;
  Expression leftHand, rightHand;
  if (node instanceof Assignment) {
    leftHand=((Assignment)node).getLeftHandSide();
    rightHand=((Assignment)node).getRightHandSide();
  }
 else   if (node instanceof PrefixExpression)   leftHand=rightHand=((PrefixExpression)node).getOperand();
 else   leftHand=rightHand=((PostfixExpression)node).getOperand();
  while (leftHand instanceof ParenthesizedExpression)   leftHand=((ParenthesizedExpression)leftHand).getExpression();
  List indices=new LinkedList();
  while (leftHand instanceof ArrayAccess) {
    ArrayAccess arrayAccess=(ArrayAccess)leftHand;
    indices.add(0,ASTNode.copySubtree(ast,arrayAccess.getIndex()));
    leftHand=arrayAccess.getArray();
    while (leftHand instanceof ParenthesizedExpression)     leftHand=((ParenthesizedExpression)leftHand).getExpression();
  }
  Expression newObject=null;
  SimpleName name;
  if (leftHand instanceof FieldAccess) {
    Expression object=((FieldAccess)leftHand).getExpression();
    name=((FieldAccess)leftHand).getName();
    Type type=Type.getType(object);
    if (!type.getName().equals(state.getCurrentClass().getName()))     return;
    newObject=(Expression)ASTNode.copySubtree(ast,object);
  }
 else   if (leftHand instanceof QualifiedName) {
    Name object=((QualifiedName)leftHand).getQualifier();
    name=((QualifiedName)leftHand).getName();
    Type type=Type.getType(object);
    if (!type.getName().equals(state.getCurrentClass().getName()))     return;
    newObject=(Expression)ASTNode.copySubtree(ast,object);
  }
 else   if (leftHand instanceof SimpleName)   name=(SimpleName)leftHand;
 else   return;
  Type owner=Type.getOwner(leftHand);
  if (owner == null)   return;
  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;
    if (java.lang.reflect.Modifier.isFinal(modifiers)) {
      if (!field.getType().isArray())       return;
    }
    isStatic=java.lang.reflect.Modifier.isStatic(modifiers);
  }
 catch (  ClassNotFoundException e) {
    throw new ASTClassNotFoundException(owner.getName());
  }
catch (  NoSuchFieldException e) {
    return;
  }
  if (isStatic && !HANDLE_STATIC_FIELDS)   return;
  MethodInvocation invocation=ast.newMethodInvocation();
  if (newObject != null)   invocation.setExpression(newObject);
  SimpleName newName=ast.newSimpleName(_getAssignMethodName(name.getIdentifier(),isSpecial));
  invocation.setName(newName);
  if (isStatic)   invocation.arguments().add(ast.newSimpleName(CHECKPOINT_NAME));
  Type type=Type.getType(node);
  if (isSpecial && _assignOperators.containsKey(type.getName())) {
    int i=0;
    String[] operators=(String[])_assignOperators.get(type.getName());
    String operator;
    if (node instanceof Assignment)     operator=((Assignment)node).getOperator().toString();
 else     if (node instanceof PrefixExpression)     operator=((PrefixExpression)node).getOperator().toString();
 else     operator=((PostfixExpression)node).getOperator().toString();
    for (; i < operators.length; i++)     if (operators[i].equals(operator))     break;
    if (node instanceof PrefixExpression)     i+=2;
    invocation.arguments().add(ast.newNumberLiteral(Integer.toString(i)));
  }
  invocation.arguments().addAll(indices);
  Type rightHandType=Type.getType(rightHand);
  if (!isSpecial && type.isPrimitive() && !type.equals(rightHandType)) {
    CastExpression castExpression=ast.newCastExpression();
    castExpression.setType(createType(ast,type.getName()));
    castExpression.setExpression((Expression)ASTNode.copySubtree(ast,rightHand));
    rightHand=castExpression;
  }
 else {
    rightHand=(Expression)ASTNode.copySubtree(ast,rightHand);
    if (isSpecial && type.getName().equals(String.class.getName()) && !type.equals(rightHandType)) {
      InfixExpression extraPlus=ast.newInfixExpression();
      extraPlus.setLeftOperand(ast.newStringLiteral());
      extraPlus.setOperator(InfixExpression.Operator.PLUS);
      extraPlus.setRightOperand(rightHand);
      rightHand=extraPlus;
    }
  }
  invocation.arguments().add(rightHand);
  Type.propagateType(invocation,node);
  replaceNode(node,invocation);
  Hashtable table=(node instanceof Assignment && ((Assignment)node).getOperator() == Assignment.Operator.ASSIGN) ? _accessedFields : _specialAccessedFields;
  _recordField(table,owner.getName(),name.getIdentifier(),indices.size());
}