Program: 12124
Project: 12124
Buggy source:
private void addMethods(){
  ExpressionExtractor expressionExtractor=new ExpressionExtractor();
  ListRewrite targetClassBodyRewrite=targetRewriter.getListRewrite(targetTypeDeclaration,TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
  HashMap<MethodDeclaration,MethodDeclaration> newMethods=new HashMap<MethodDeclaration,MethodDeclaration>();
  HashMap<MethodDeclaration,ArrayList<MethodInvocation>> targetInvocationsMap=new HashMap<MethodDeclaration,ArrayList<MethodInvocation>>();
  for (  MethodDeclaration method : extractedMethods) {
    ArrayList<Assignment> assignmentsToReplace=new ArrayList<Assignment>();
    List<Expression> assignments=expressionExtractor.getAssignments(method.getBody());
    for (    Expression expression : assignments) {
      Assignment assignment=(Assignment)expression;
      if (assignment.getLeftHandSide() instanceof FieldAccess) {
        FieldAccess fieldAccess=(FieldAccess)assignment.getLeftHandSide();
        if (!extractedFieldInstructions.containsKey(fieldAccess.resolveFieldBinding()) && sourceFieldInstructions.containsKey(fieldAccess.resolveFieldBinding())) {
          assignmentsToReplace.add(assignment);
        }
      }
 else       if (assignment.getLeftHandSide() instanceof SimpleName) {
        SimpleName simpleName=(SimpleName)assignment.getLeftHandSide();
        if (!extractedFieldInstructions.containsKey(simpleName.resolveBinding()) && sourceFieldInstructions.containsKey(simpleName.resolveBinding())) {
          assignmentsToReplace.add(assignment);
        }
      }
    }
    ArrayList<SimpleName> instructionsToReplace=new ArrayList<SimpleName>();
    List<Expression> instructions=expressionExtractor.getVariableInstructions(method.getBody());
    for (    Expression expression : instructions) {
      SimpleName instruction=(SimpleName)expression;
      if (isParentAssignment(instruction) == null) {
        if (!extractedFieldInstructions.containsKey(instruction.resolveBinding()) && sourceFieldInstructions.containsKey(instruction.resolveBinding())) {
          instructionsToReplace.add(instruction);
        }
      }
    }
    ArrayList<MethodInvocation> invocationsToReplace=new ArrayList<MethodInvocation>();
    ArrayList<MethodInvocation> targetInvocationsToReplace=new ArrayList<MethodInvocation>();
    List<Expression> invocations=expressionExtractor.getMethodInvocations(method.getBody());
    for (    Expression expression : invocations) {
      MethodInvocation invocation=(MethodInvocation)expression;
      invocationsToReplace=addInvocationToReplace(invocation,invocationsToReplace);
      if (extractedMethodInvocations.containsKey(invocation)) {
        targetInvocationsToReplace.add(invocation);
      }
    }
    targetInvocationsMap.put(method,targetInvocationsToReplace);
    ArrayList<ThisExpression> thisExpressionsToReplace=new ArrayList<ThisExpression>();
    List<Expression> thisExpressions=expressionExtractor.getThisExpressions(method.getBody());
    for (    Expression expression : thisExpressions) {
      ThisExpression thisExpression=(ThisExpression)expression;
      if (thisExpression.getParent() instanceof FieldAccess) {
        FieldAccess access=(FieldAccess)thisExpression.getParent();
        if (!this.extractedFieldInstructions.containsKey(access.resolveFieldBinding())) {
          thisExpressionsToReplace.add(thisExpression);
        }
      }
 else       if (thisExpression.getParent() instanceof MethodInvocation) {
        MethodInvocation invocation=(MethodInvocation)thisExpression.getParent();
        if (this.extractedMethodInvocations.containsKey(invocation)) {
          thisExpressionsToReplace.add(thisExpression);
        }
      }
 else {
        thisExpressionsToReplace.add(thisExpression);
      }
    }
    MethodDeclaration newMethod=(MethodDeclaration)ASTNode.copySubtree(targetTypeDeclaration.getAST(),method);
    AST ast=newMethod.getAST();
    SimpleName sourceClassParameter=null;
    if (!assignmentsToReplace.isEmpty()) {
      sourceClassParameter=addSourceClassParameterToMovedMethod(newMethod,method,false);
      List<Expression> newAssignments=expressionExtractor.getAssignments(newMethod.getBody());
      for (      Expression newAssignment : newAssignments) {
        for (        Assignment oldAssignment : assignmentsToReplace) {
          if (newAssignment.subtreeMatch(new ASTMatcher(),oldAssignment)) {
            Assignment assignment=(Assignment)newAssignment;
            String variableName="String_Node_Str";
            if (assignment.getLeftHandSide() instanceof FieldAccess) {
              FieldAccess fieldAccess=(FieldAccess)assignment.getLeftHandSide();
              variableName=fieldAccess.getName().toString().replaceFirst("String_Node_Str" + fieldAccess.getName().toString().charAt(0),"String_Node_Str" + fieldAccess.getName().toString().toUpperCase().charAt(0));
            }
 else             if (assignment.getLeftHandSide() instanceof SimpleName) {
              SimpleName simpleName=(SimpleName)assignment.getLeftHandSide();
              variableName=simpleName.toString().replaceFirst("String_Node_Str" + simpleName.toString().charAt(0),"String_Node_Str" + simpleName.toString().toUpperCase().charAt(0));
            }
            if (sourceClassContainsSetter(variableName) != null) {
              ListRewrite sourceBodyRewrite=sourceRewriter.getListRewrite(sourceTypeDeclaration,TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
              addSetter(sourceTypeDeclaration.getAST(),sourceBodyRewrite,sourceClassContainsSetter(variableName),fragmentToAddSetter,variableName,sourceRewriter);
            }
            replaceAssignmentWithSetter(sourceClassParameter,ast,assignment,variableName,targetRewriter);
          }
        }
      }
    }
    if (!instructionsToReplace.isEmpty()) {
      for (      SimpleName instruction : instructionsToReplace) {
        FieldDeclaration[] sourceFieldDeclarations=sourceTypeDeclaration.getFields();
        for (        FieldDeclaration sourceFieldDeclaration : sourceFieldDeclarations) {
          List<VariableDeclarationFragment> fragments=sourceFieldDeclaration.fragments();
          for (          VariableDeclarationFragment fragment : fragments) {
            if (fragment.resolveBinding().isEqualTo(instruction.resolveBinding())) {
              int modifiers=sourceFieldDeclaration.getModifiers();
              List<Expression> newInstructions=expressionExtractor.getVariableInstructions(newMethod.getBody());
              for (              Expression newInstruction : newInstructions) {
                if (newInstruction.subtreeMatch(new ASTMatcher(),instruction)) {
                  if ((modifiers & Modifier.STATIC) != 0) {
                    QualifiedName qualifiedName=ast.newQualifiedName(ast.newName(sourceTypeDeclaration.getName().getIdentifier()),ast.newSimpleName(instruction.getIdentifier()));
                    targetRewriter.replace(newInstruction,qualifiedName,null);
                  }
 else {
                    addParameterToMovedMethod(newMethod,instruction,method);
                  }
                }
              }
            }
          }
        }
      }
    }
    ArrayList<MethodInvocation> replacedInvocations=new ArrayList<MethodInvocation>();
    Set<String> sourceMethodsWithPublicModifier=new LinkedHashSet<String>();
    if (!invocationsToReplace.isEmpty()) {
      for (      Expression expression : invocationsToReplace) {
        if (expression instanceof MethodInvocation) {
          MethodInvocation methodInvocation=(MethodInvocation)expression;
          if (methodInvocation.getExpression() == null || methodInvocation.getExpression() instanceof ThisExpression) {
            IMethodBinding methodBinding=methodInvocation.resolveMethodBinding();
            if (methodBinding.getDeclaringClass().isEqualTo(sourceTypeDeclaration.resolveBinding())) {
              MethodDeclaration[] sourceMethodDeclarations=sourceTypeDeclaration.getMethods();
              for (              MethodDeclaration sourceMethodDeclaration : sourceMethodDeclarations) {
                if (sourceMethodDeclaration.resolveBinding().isEqualTo(methodInvocation.resolveMethodBinding())) {
                  SimpleName fieldName=MethodDeclarationUtility.isGetter(sourceMethodDeclaration);
                  int modifiers=sourceMethodDeclaration.getModifiers();
                  List<Expression> newInvocations=expressionExtractor.getMethodInvocations(newMethod.getBody());
                  for (                  Expression newMethodInvocation : newInvocations) {
                    if (newMethodInvocation.subtreeMatch(new ASTMatcher(),methodInvocation)) {
                      if ((modifiers & Modifier.STATIC) != 0) {
                        targetRewriter.set(newMethodInvocation,MethodInvocation.EXPRESSION_PROPERTY,ast.newSimpleName(sourceTypeDeclaration.getName().getIdentifier()),null);
                        if (!sourceMethodsWithPublicModifier.contains(methodInvocation.resolveMethodBinding().getKey())) {
                          setPublicModifierToSourceMethod(methodInvocation);
                          sourceMethodsWithPublicModifier.add(methodInvocation.resolveMethodBinding().getKey());
                          replacedInvocations.add(methodInvocation);
                        }
                      }
 else                       if (fieldName != null) {
                        targetRewriter.replace(newMethodInvocation,ast.newSimpleName(fieldName.getIdentifier()),null);
                        if (!extractedFieldInstructions.containsKey(fieldName.resolveBinding())) {
                          addParameterToMovedMethod(newMethod,fieldName,method);
                          replacedInvocations.add(methodInvocation);
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    invocationsToReplace.removeAll(replacedInvocations);
    if (!invocationsToReplace.isEmpty()) {
      boolean foundAnonymousClassDeclaration=false;
      for (      MethodInvocation invocation : invocationsToReplace) {
        if (isParentAnonymousClassDeclaration(invocation)) {
          foundAnonymousClassDeclaration=true;
        }
      }
      if (sourceClassParameter == null) {
        sourceClassParameter=addSourceClassParameterToMovedMethod(newMethod,method,foundAnonymousClassDeclaration);
      }
      List<Expression> newInvocations=expressionExtractor.getMethodInvocations(newMethod.getBody());
      for (      Expression newInvocation : newInvocations) {
        for (        MethodInvocation oldInvocation : invocationsToReplace) {
          if (newInvocation.subtreeMatch(new ASTMatcher(),oldInvocation)) {
            MethodInvocation invocation=(MethodInvocation)newInvocation;
            targetRewriter.set(invocation,MethodInvocation.EXPRESSION_PROPERTY,sourceClassParameter,null);
            setPublicModifierToSourceMethod(oldInvocation);
          }
        }
      }
    }
    if (!thisExpressionsToReplace.isEmpty()) {
      if (sourceClassParameter == null) {
        sourceClassParameter=addSourceClassParameterToMovedMethod(newMethod,method,false);
      }
      List<Expression> newThisExpressions=expressionExtractor.getThisExpressions(newMethod.getBody());
      for (      ThisExpression oldThisExpression : thisExpressionsToReplace) {
        for (        Expression newThisExpression : newThisExpressions) {
          if (oldThisExpression.getParent().subtreeMatch(new ASTMatcher(),newThisExpression.getParent())) {
            ThisExpression thisExpression=(ThisExpression)newThisExpression;
            targetRewriter.replace(thisExpression,sourceClassParameter,null);
          }
        }
      }
    }
    List<MethodDeclaration> oldMethods=Arrays.asList(sourceTypeDeclaration.getMethods());
    for (    MethodDeclaration oldMethod : oldMethods) {
      if (!oldMethod.equals(method)) {
        List<Expression> oldInvocations=expressionExtractor.getMethodInvocations(oldMethod.getBody());
        for (        Expression oldExpression : oldInvocations) {
          if (oldExpression instanceof MethodInvocation) {
            MethodInvocation invocation=(MethodInvocation)oldExpression;
            if (extractedMethodInvocations.containsKey(invocation)) {
              ListRewrite modifierRewrite=targetRewriter.getListRewrite(newMethod,MethodDeclaration.MODIFIERS2_PROPERTY);
              Modifier publicModifier=newMethod.getAST().newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
              boolean modifierFound=false;
              List<IExtendedModifier> modifiers=newMethod.modifiers();
              for (              IExtendedModifier extendedModifier : modifiers) {
                if (extendedModifier.isModifier()) {
                  Modifier modifier=(Modifier)extendedModifier;
                  if (modifier.getKeyword().equals(Modifier.ModifierKeyword.PUBLIC_KEYWORD)) {
                    modifierFound=true;
                  }
 else                   if (modifier.getKeyword().equals(Modifier.ModifierKeyword.PRIVATE_KEYWORD) || modifier.getKeyword().equals(Modifier.ModifierKeyword.PROTECTED_KEYWORD)) {
                    modifierFound=true;
                    modifierRewrite.replace(modifier,publicModifier,null);
                  }
                }
              }
              if (!modifierFound) {
                modifierRewrite.insertFirst(publicModifier,null);
              }
            }
          }
        }
      }
    }
    newMethods.put(newMethod,method);
  }
  for (  MethodDeclaration newMethod : newMethods.keySet()) {
    if (!targetInvocationsMap.isEmpty()) {
      List<Expression> newInvocations=expressionExtractor.getMethodInvocations(newMethod.getBody());
      for (      Expression newInvocation : newInvocations) {
        for (        MethodDeclaration oldMethod : targetInvocationsMap.keySet()) {
          Set<IMethodBinding> checkedInvocations=new HashSet<IMethodBinding>();
          if (oldMethod.subtreeMatch(new ASTMatcher(),newMethod)) {
            for (            MethodInvocation oldInvocation : targetInvocationsMap.get(oldMethod)) {
              if (newInvocation.subtreeMatch(new ASTMatcher(),oldInvocation)) {
                for (                MethodDeclaration modifiedMethod : this.additionalArgumentsAddedToMovedMethod.keySet()) {
                  if (modifiedMethod.resolveBinding().isEqualTo(oldInvocation.resolveMethodBinding())) {
                    MethodInvocation invocation=(MethodInvocation)newInvocation;
                    if (!checkedInvocations.contains(oldInvocation.resolveMethodBinding())) {
                      AST ast=invocation.getAST();
                      ListRewrite arguments=targetRewriter.getListRewrite(invocation,MethodInvocation.ARGUMENTS_PROPERTY);
                      Set<String> additionalArguments=new TreeSet<String>(this.additionalArgumentsAddedToMovedMethod.get(modifiedMethod));
                      TreeSet<String> checkedArguments=new TreeSet<String>();
                      for (                      String argument : additionalArguments) {
                        if (!argument.equalsIgnoreCase(sourceTypeDeclaration.getName().getIdentifier())) {
                          if (!containsParameter(newMethods.get(newMethod),argument)) {
                            if (isParentAnonymousClassDeclaration(oldInvocation)) {
                              if (!containsParameter(newMethods.get(newMethod),sourceTypeDeclaration.getName().getIdentifier())) {
                                this.addSourceClassParameterToMovedMethod(newMethod,newMethods.get(newMethod),false);
                              }
                              MethodDeclaration[] sourceMethodDeclarations=sourceTypeDeclaration.getMethods();
                              SimpleName fieldName=null;
                              MethodDeclaration methodDeclaration=null;
                              for (                              MethodDeclaration sourceMethodDeclaration : sourceMethodDeclarations) {
                                fieldName=MethodDeclarationUtility.isGetter(sourceMethodDeclaration);
                                methodDeclaration=sourceMethodDeclaration;
                                if (fieldName != null && fieldName.getIdentifier().equals(argument))                                 break;
                              }
                              if (fieldName != null) {
                                MethodInvocation methodInvocation=ast.newMethodInvocation();
                                targetRewriter.set(methodInvocation,MethodInvocation.NAME_PROPERTY,methodDeclaration.getName(),null);
                                targetRewriter.set(methodInvocation,MethodInvocation.EXPRESSION_PROPERTY,ast.newSimpleName(sourceTypeDeclaration.getName().getIdentifier().replaceFirst(Character.toString(sourceTypeDeclaration.getName().getIdentifier().charAt(0)),Character.toString(Character.toLowerCase(sourceTypeDeclaration.getName().getIdentifier().charAt(0))))),null);
                                arguments.insertLast(methodInvocation,null);
                                checkedArguments.add(argument);
                              }
                            }
 else {
                              this.addParameterToMovedMethod(newMethod,ast.newSimpleName(argument),newMethods.get(newMethod));
                            }
                          }
                        }
 else {
                          if (!containsParameter(newMethods.get(newMethod),sourceTypeDeclaration.getName().getIdentifier())) {
                            this.addSourceClassParameterToMovedMethod(newMethod,newMethods.get(newMethod),false);
                          }
                        }
                      }
                      for (                      String argument : this.additionalArgumentsAddedToMovedMethod.get(modifiedMethod)) {
                        if (!checkedArguments.contains(argument)) {
                          if (!argument.equalsIgnoreCase(sourceTypeDeclaration.getName().getIdentifier())) {
                            arguments.insertLast(ast.newSimpleName(argument),null);
                            checkedInvocations.add(invocation.resolveMethodBinding());
                          }
 else {
                            String sourceTypeName=sourceTypeDeclaration.getName().getIdentifier();
                            arguments.insertLast(ast.newSimpleName(sourceTypeName.replaceFirst(Character.toString(sourceTypeName.charAt(0)),Character.toString(Character.toLowerCase(sourceTypeName.charAt(0))))),null);
                            checkedInvocations.add(oldInvocation.resolveMethodBinding());
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    targetClassBodyRewrite.insertLast(newMethod,null);
  }
}

Fixed version (ground truth):
private void addMethods(){
  ExpressionExtractor expressionExtractor=new ExpressionExtractor();
  ListRewrite targetClassBodyRewrite=targetRewriter.getListRewrite(targetTypeDeclaration,TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
  HashMap<MethodDeclaration,MethodDeclaration> newMethods=new HashMap<MethodDeclaration,MethodDeclaration>();
  HashMap<MethodDeclaration,ArrayList<MethodInvocation>> targetInvocationsMap=new HashMap<MethodDeclaration,ArrayList<MethodInvocation>>();
  for (  MethodDeclaration method : extractedMethods) {
    ArrayList<Assignment> assignmentsToReplace=new ArrayList<Assignment>();
    List<Expression> assignments=expressionExtractor.getAssignments(method.getBody());
    for (    Expression expression : assignments) {
      Assignment assignment=(Assignment)expression;
      if (assignment.getLeftHandSide() instanceof FieldAccess) {
        FieldAccess fieldAccess=(FieldAccess)assignment.getLeftHandSide();
        if (!extractedFieldInstructions.containsKey(fieldAccess.resolveFieldBinding()) && sourceFieldInstructions.containsKey(fieldAccess.resolveFieldBinding())) {
          assignmentsToReplace.add(assignment);
        }
      }
 else       if (assignment.getLeftHandSide() instanceof SimpleName) {
        SimpleName simpleName=(SimpleName)assignment.getLeftHandSide();
        if (!extractedFieldInstructions.containsKey(simpleName.resolveBinding()) && sourceFieldInstructions.containsKey(simpleName.resolveBinding())) {
          assignmentsToReplace.add(assignment);
        }
      }
    }
    ArrayList<SimpleName> instructionsToReplace=new ArrayList<SimpleName>();
    List<Expression> instructions=expressionExtractor.getVariableInstructions(method.getBody());
    for (    Expression expression : instructions) {
      SimpleName instruction=(SimpleName)expression;
      if (isParentAssignment(instruction) == null) {
        if (!extractedFieldInstructions.containsKey(instruction.resolveBinding()) && sourceFieldInstructions.containsKey(instruction.resolveBinding())) {
          instructionsToReplace.add(instruction);
        }
      }
    }
    ArrayList<MethodInvocation> invocationsToReplace=new ArrayList<MethodInvocation>();
    ArrayList<MethodInvocation> targetInvocationsToReplace=new ArrayList<MethodInvocation>();
    List<Expression> invocations=expressionExtractor.getMethodInvocations(method.getBody());
    for (    Expression expression : invocations) {
      MethodInvocation invocation=(MethodInvocation)expression;
      invocationsToReplace=addInvocationToReplace(invocation,invocationsToReplace);
      if (extractedMethodInvocations.containsKey(invocation)) {
        targetInvocationsToReplace.add(invocation);
      }
    }
    targetInvocationsMap.put(method,targetInvocationsToReplace);
    ArrayList<ThisExpression> thisExpressionsToReplace=new ArrayList<ThisExpression>();
    List<Expression> thisExpressions=expressionExtractor.getThisExpressions(method.getBody());
    for (    Expression expression : thisExpressions) {
      ThisExpression thisExpression=(ThisExpression)expression;
      if (thisExpression.getParent() instanceof FieldAccess) {
        FieldAccess access=(FieldAccess)thisExpression.getParent();
        if (!this.extractedFieldInstructions.containsKey(access.resolveFieldBinding())) {
          thisExpressionsToReplace.add(thisExpression);
        }
      }
 else       if (thisExpression.getParent() instanceof MethodInvocation) {
        MethodInvocation invocation=(MethodInvocation)thisExpression.getParent();
        if (this.extractedMethodInvocations.containsKey(invocation) || !(invocation.getExpression() instanceof ThisExpression)) {
          thisExpressionsToReplace.add(thisExpression);
        }
      }
 else {
        thisExpressionsToReplace.add(thisExpression);
      }
    }
    MethodDeclaration newMethod=(MethodDeclaration)ASTNode.copySubtree(targetTypeDeclaration.getAST(),method);
    AST ast=newMethod.getAST();
    SimpleName sourceClassParameter=null;
    if (!assignmentsToReplace.isEmpty()) {
      sourceClassParameter=addSourceClassParameterToMovedMethod(newMethod,method,false);
      List<Expression> newAssignments=expressionExtractor.getAssignments(newMethod.getBody());
      for (      Expression newAssignment : newAssignments) {
        for (        Assignment oldAssignment : assignmentsToReplace) {
          if (newAssignment.subtreeMatch(new ASTMatcher(),oldAssignment)) {
            Assignment assignment=(Assignment)newAssignment;
            String variableName="String_Node_Str";
            if (assignment.getLeftHandSide() instanceof FieldAccess) {
              FieldAccess fieldAccess=(FieldAccess)assignment.getLeftHandSide();
              variableName=fieldAccess.getName().toString().replaceFirst("String_Node_Str" + fieldAccess.getName().toString().charAt(0),"String_Node_Str" + fieldAccess.getName().toString().toUpperCase().charAt(0));
            }
 else             if (assignment.getLeftHandSide() instanceof SimpleName) {
              SimpleName simpleName=(SimpleName)assignment.getLeftHandSide();
              variableName=simpleName.toString().replaceFirst("String_Node_Str" + simpleName.toString().charAt(0),"String_Node_Str" + simpleName.toString().toUpperCase().charAt(0));
            }
            if (sourceClassContainsSetter(variableName) != null) {
              ListRewrite sourceBodyRewrite=sourceRewriter.getListRewrite(sourceTypeDeclaration,TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
              addSetter(sourceTypeDeclaration.getAST(),sourceBodyRewrite,sourceClassContainsSetter(variableName),fragmentToAddSetter,variableName,sourceRewriter);
            }
            replaceAssignmentWithSetter(sourceClassParameter,ast,assignment,variableName,targetRewriter);
          }
        }
      }
    }
    if (!instructionsToReplace.isEmpty()) {
      for (      SimpleName instruction : instructionsToReplace) {
        FieldDeclaration[] sourceFieldDeclarations=sourceTypeDeclaration.getFields();
        for (        FieldDeclaration sourceFieldDeclaration : sourceFieldDeclarations) {
          List<VariableDeclarationFragment> fragments=sourceFieldDeclaration.fragments();
          for (          VariableDeclarationFragment fragment : fragments) {
            if (fragment.resolveBinding().isEqualTo(instruction.resolveBinding())) {
              int modifiers=sourceFieldDeclaration.getModifiers();
              List<Expression> newInstructions=expressionExtractor.getVariableInstructions(newMethod.getBody());
              for (              Expression newInstruction : newInstructions) {
                if (newInstruction.subtreeMatch(new ASTMatcher(),instruction)) {
                  if ((modifiers & Modifier.STATIC) != 0) {
                    QualifiedName qualifiedName=ast.newQualifiedName(ast.newName(sourceTypeDeclaration.getName().getIdentifier()),ast.newSimpleName(instruction.getIdentifier()));
                    targetRewriter.replace(newInstruction,qualifiedName,null);
                  }
 else {
                    addParameterToMovedMethod(newMethod,instruction,method);
                  }
                }
              }
            }
          }
        }
      }
    }
    ArrayList<MethodInvocation> replacedInvocations=new ArrayList<MethodInvocation>();
    Set<String> sourceMethodsWithPublicModifier=new LinkedHashSet<String>();
    if (!invocationsToReplace.isEmpty()) {
      for (      Expression expression : invocationsToReplace) {
        if (expression instanceof MethodInvocation) {
          MethodInvocation methodInvocation=(MethodInvocation)expression;
          if (methodInvocation.getExpression() == null || methodInvocation.getExpression() instanceof ThisExpression) {
            IMethodBinding methodBinding=methodInvocation.resolveMethodBinding();
            if (methodBinding.getDeclaringClass().isEqualTo(sourceTypeDeclaration.resolveBinding())) {
              MethodDeclaration[] sourceMethodDeclarations=sourceTypeDeclaration.getMethods();
              for (              MethodDeclaration sourceMethodDeclaration : sourceMethodDeclarations) {
                if (sourceMethodDeclaration.resolveBinding().isEqualTo(methodInvocation.resolveMethodBinding())) {
                  SimpleName fieldName=MethodDeclarationUtility.isGetter(sourceMethodDeclaration);
                  int modifiers=sourceMethodDeclaration.getModifiers();
                  List<Expression> newInvocations=expressionExtractor.getMethodInvocations(newMethod.getBody());
                  for (                  Expression newMethodInvocation : newInvocations) {
                    if (newMethodInvocation.subtreeMatch(new ASTMatcher(),methodInvocation)) {
                      if ((modifiers & Modifier.STATIC) != 0) {
                        targetRewriter.set(newMethodInvocation,MethodInvocation.EXPRESSION_PROPERTY,ast.newSimpleName(sourceTypeDeclaration.getName().getIdentifier()),null);
                        if (!sourceMethodsWithPublicModifier.contains(methodInvocation.resolveMethodBinding().getKey())) {
                          setPublicModifierToSourceMethod(methodInvocation);
                          sourceMethodsWithPublicModifier.add(methodInvocation.resolveMethodBinding().getKey());
                          replacedInvocations.add(methodInvocation);
                        }
                      }
 else                       if (fieldName != null) {
                        targetRewriter.replace(newMethodInvocation,ast.newSimpleName(fieldName.getIdentifier()),null);
                        if (!extractedFieldInstructions.containsKey(fieldName.resolveBinding())) {
                          addParameterToMovedMethod(newMethod,fieldName,method);
                          replacedInvocations.add(methodInvocation);
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    invocationsToReplace.removeAll(replacedInvocations);
    if (!invocationsToReplace.isEmpty()) {
      boolean foundAnonymousClassDeclaration=false;
      for (      MethodInvocation invocation : invocationsToReplace) {
        if (isParentAnonymousClassDeclaration(invocation)) {
          foundAnonymousClassDeclaration=true;
        }
      }
      if (sourceClassParameter == null) {
        sourceClassParameter=addSourceClassParameterToMovedMethod(newMethod,method,foundAnonymousClassDeclaration);
      }
      List<Expression> newInvocations=expressionExtractor.getMethodInvocations(newMethod.getBody());
      for (      Expression newInvocation : newInvocations) {
        for (        MethodInvocation oldInvocation : invocationsToReplace) {
          if (newInvocation.subtreeMatch(new ASTMatcher(),oldInvocation)) {
            MethodInvocation invocation=(MethodInvocation)newInvocation;
            targetRewriter.set(invocation,MethodInvocation.EXPRESSION_PROPERTY,sourceClassParameter,null);
            setPublicModifierToSourceMethod(oldInvocation);
          }
        }
      }
    }
    if (!thisExpressionsToReplace.isEmpty()) {
      if (sourceClassParameter == null) {
        sourceClassParameter=addSourceClassParameterToMovedMethod(newMethod,method,false);
      }
      List<Expression> newThisExpressions=expressionExtractor.getThisExpressions(newMethod.getBody());
      for (      ThisExpression oldThisExpression : thisExpressionsToReplace) {
        for (        Expression newThisExpression : newThisExpressions) {
          if (oldThisExpression.getParent().subtreeMatch(new ASTMatcher(),newThisExpression.getParent())) {
            ThisExpression thisExpression=(ThisExpression)newThisExpression;
            targetRewriter.replace(thisExpression,sourceClassParameter,null);
          }
        }
      }
    }
    List<MethodDeclaration> oldMethods=Arrays.asList(sourceTypeDeclaration.getMethods());
    for (    MethodDeclaration oldMethod : oldMethods) {
      if (!oldMethod.equals(method)) {
        List<Expression> oldInvocations=expressionExtractor.getMethodInvocations(oldMethod.getBody());
        for (        Expression oldExpression : oldInvocations) {
          if (oldExpression instanceof MethodInvocation) {
            MethodInvocation invocation=(MethodInvocation)oldExpression;
            if (extractedMethodInvocations.containsKey(invocation)) {
              ListRewrite modifierRewrite=targetRewriter.getListRewrite(newMethod,MethodDeclaration.MODIFIERS2_PROPERTY);
              Modifier publicModifier=newMethod.getAST().newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
              boolean modifierFound=false;
              List<IExtendedModifier> modifiers=newMethod.modifiers();
              for (              IExtendedModifier extendedModifier : modifiers) {
                if (extendedModifier.isModifier()) {
                  Modifier modifier=(Modifier)extendedModifier;
                  if (modifier.getKeyword().equals(Modifier.ModifierKeyword.PUBLIC_KEYWORD)) {
                    modifierFound=true;
                  }
 else                   if (modifier.getKeyword().equals(Modifier.ModifierKeyword.PRIVATE_KEYWORD) || modifier.getKeyword().equals(Modifier.ModifierKeyword.PROTECTED_KEYWORD)) {
                    modifierFound=true;
                    modifierRewrite.replace(modifier,publicModifier,null);
                  }
                }
              }
              if (!modifierFound) {
                modifierRewrite.insertFirst(publicModifier,null);
              }
            }
          }
        }
      }
    }
    newMethods.put(newMethod,method);
  }
  for (  MethodDeclaration newMethod : newMethods.keySet()) {
    if (!targetInvocationsMap.isEmpty()) {
      List<Expression> newInvocations=expressionExtractor.getMethodInvocations(newMethod.getBody());
      for (      Expression newInvocation : newInvocations) {
        for (        MethodDeclaration oldMethod : targetInvocationsMap.keySet()) {
          Set<IMethodBinding> checkedInvocations=new HashSet<IMethodBinding>();
          if (oldMethod.subtreeMatch(new ASTMatcher(),newMethod)) {
            for (            MethodInvocation oldInvocation : targetInvocationsMap.get(oldMethod)) {
              if (newInvocation.subtreeMatch(new ASTMatcher(),oldInvocation)) {
                for (                MethodDeclaration modifiedMethod : this.additionalArgumentsAddedToMovedMethod.keySet()) {
                  if (modifiedMethod.resolveBinding().isEqualTo(oldInvocation.resolveMethodBinding())) {
                    MethodInvocation invocation=(MethodInvocation)newInvocation;
                    if (!checkedInvocations.contains(oldInvocation.resolveMethodBinding())) {
                      AST ast=invocation.getAST();
                      ListRewrite arguments=targetRewriter.getListRewrite(invocation,MethodInvocation.ARGUMENTS_PROPERTY);
                      Set<String> additionalArguments=new TreeSet<String>(this.additionalArgumentsAddedToMovedMethod.get(modifiedMethod));
                      TreeSet<String> checkedArguments=new TreeSet<String>();
                      for (                      String argument : additionalArguments) {
                        if (!argument.equalsIgnoreCase(sourceTypeDeclaration.getName().getIdentifier())) {
                          if (!containsParameter(newMethods.get(newMethod),argument)) {
                            if (isParentAnonymousClassDeclaration(oldInvocation)) {
                              if (!containsParameter(newMethods.get(newMethod),sourceTypeDeclaration.getName().getIdentifier())) {
                                this.addSourceClassParameterToMovedMethod(newMethod,newMethods.get(newMethod),false);
                              }
                              MethodDeclaration[] sourceMethodDeclarations=sourceTypeDeclaration.getMethods();
                              SimpleName fieldName=null;
                              MethodDeclaration methodDeclaration=null;
                              for (                              MethodDeclaration sourceMethodDeclaration : sourceMethodDeclarations) {
                                fieldName=MethodDeclarationUtility.isGetter(sourceMethodDeclaration);
                                methodDeclaration=sourceMethodDeclaration;
                                if (fieldName != null && fieldName.getIdentifier().equals(argument))                                 break;
                              }
                              if (fieldName != null) {
                                MethodInvocation methodInvocation=ast.newMethodInvocation();
                                targetRewriter.set(methodInvocation,MethodInvocation.NAME_PROPERTY,methodDeclaration.getName(),null);
                                targetRewriter.set(methodInvocation,MethodInvocation.EXPRESSION_PROPERTY,ast.newSimpleName(sourceTypeDeclaration.getName().getIdentifier().replaceFirst(Character.toString(sourceTypeDeclaration.getName().getIdentifier().charAt(0)),Character.toString(Character.toLowerCase(sourceTypeDeclaration.getName().getIdentifier().charAt(0))))),null);
                                arguments.insertLast(methodInvocation,null);
                                checkedArguments.add(argument);
                              }
                            }
 else {
                              this.addParameterToMovedMethod(newMethod,ast.newSimpleName(argument),newMethods.get(newMethod));
                            }
                          }
                        }
 else {
                          if (!containsParameter(newMethods.get(newMethod),sourceTypeDeclaration.getName().getIdentifier())) {
                            this.addSourceClassParameterToMovedMethod(newMethod,newMethods.get(newMethod),false);
                          }
                        }
                      }
                      for (                      String argument : this.additionalArgumentsAddedToMovedMethod.get(modifiedMethod)) {
                        if (!checkedArguments.contains(argument)) {
                          if (!argument.equalsIgnoreCase(sourceTypeDeclaration.getName().getIdentifier())) {
                            arguments.insertLast(ast.newSimpleName(argument),null);
                            checkedInvocations.add(invocation.resolveMethodBinding());
                          }
 else {
                            String sourceTypeName=sourceTypeDeclaration.getName().getIdentifier();
                            arguments.insertLast(ast.newSimpleName(sourceTypeName.replaceFirst(Character.toString(sourceTypeName.charAt(0)),Character.toString(Character.toLowerCase(sourceTypeName.charAt(0))))),null);
                            checkedInvocations.add(oldInvocation.resolveMethodBinding());
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    targetClassBodyRewrite.insertLast(newMethod,null);
  }
}