Program: 12074
Project: 12074
Buggy source:
private void extractClone(){
  CompilationUnit sourceCompilationUnit=null;
  ICompilationUnit sourceICompilationUnit=null;
  TypeDeclaration sourceTypeDeclaration=null;
  ASTRewrite sourceRewriter=null;
  AST ast=null;
  Document document=null;
  IFile file=null;
  ITypeBinding commonSuperTypeOfSourceTypeDeclarations=null;
  if (sourceTypeDeclarations.get(0).resolveBinding().isEqualTo(sourceTypeDeclarations.get(1).resolveBinding())) {
    sourceCompilationUnit=sourceCompilationUnits.get(0);
    sourceICompilationUnit=(ICompilationUnit)sourceCompilationUnit.getJavaElement();
    sourceTypeDeclaration=sourceTypeDeclarations.get(0);
    sourceRewriter=ASTRewrite.create(sourceTypeDeclaration.getAST());
    ast=sourceTypeDeclaration.getAST();
  }
 else {
    ITypeBinding typeBinding1=sourceTypeDeclarations.get(0).resolveBinding();
    ITypeBinding typeBinding2=sourceTypeDeclarations.get(1).resolveBinding();
    commonSuperTypeOfSourceTypeDeclarations=ASTNodeMatcher.commonSuperType(typeBinding1,typeBinding2);
    if (commonSuperTypeOfSourceTypeDeclarations != null) {
      boolean superclassInheritedOnlyByRefactoringSubclasses=false;
      if (!commonSuperTypeOfSourceTypeDeclarations.getQualifiedName().equals("String_Node_Str")) {
        CompilationUnitCache cache=CompilationUnitCache.getInstance();
        Set<IType> subTypes=cache.getSubTypes((IType)commonSuperTypeOfSourceTypeDeclarations.getJavaElement());
        if (subTypes.size() == 2 && subTypes.contains((IType)typeBinding1.getJavaElement()) && subTypes.contains((IType)typeBinding2.getJavaElement()))         superclassInheritedOnlyByRefactoringSubclasses=true;
      }
      boolean superclassIsOneOfTheSourceTypeDeclarations=false;
      if (typeBinding1.isEqualTo(commonSuperTypeOfSourceTypeDeclarations) || typeBinding2.isEqualTo(commonSuperTypeOfSourceTypeDeclarations))       superclassIsOneOfTheSourceTypeDeclarations=true;
      if (((mapper.getAccessedLocalFieldsG1().isEmpty() && mapper.getAccessedLocalFieldsG2().isEmpty() && mapper.getAccessedLocalMethodsG1().isEmpty()&& mapper.getAccessedLocalMethodsG2().isEmpty()) || superclassInheritedOnlyByRefactoringSubclasses || superclassIsOneOfTheSourceTypeDeclarations) && ASTReader.getSystemObject().getClassObject(commonSuperTypeOfSourceTypeDeclarations.getQualifiedName()) != null) {
        IJavaElement javaElement=commonSuperTypeOfSourceTypeDeclarations.getJavaElement();
        javaElementsToOpenInEditor.add(javaElement);
        ICompilationUnit iCompilationUnit=(ICompilationUnit)javaElement.getParent();
        ASTParser parser=ASTParser.newParser(AST.JLS4);
        parser.setKind(ASTParser.K_COMPILATION_UNIT);
        parser.setSource(iCompilationUnit);
        parser.setResolveBindings(true);
        CompilationUnit compilationUnit=(CompilationUnit)parser.createAST(null);
        List<AbstractTypeDeclaration> typeDeclarations=compilationUnit.types();
        for (        AbstractTypeDeclaration abstractTypeDeclaration : typeDeclarations) {
          if (abstractTypeDeclaration instanceof TypeDeclaration) {
            TypeDeclaration typeDeclaration=(TypeDeclaration)abstractTypeDeclaration;
            if (typeDeclaration.resolveBinding().isEqualTo(commonSuperTypeOfSourceTypeDeclarations)) {
              sourceCompilationUnit=compilationUnit;
              sourceICompilationUnit=iCompilationUnit;
              sourceTypeDeclaration=typeDeclaration;
              sourceRewriter=ASTRewrite.create(sourceTypeDeclaration.getAST());
              ast=sourceTypeDeclaration.getAST();
              break;
            }
          }
        }
        MultiTextEdit multiTextEdit=new MultiTextEdit();
        CompilationUnitChange compilationUnitChange=new CompilationUnitChange("String_Node_Str",iCompilationUnit);
        compilationUnitChange.setEdit(multiTextEdit);
        compilationUnitChanges.put(iCompilationUnit,compilationUnitChange);
      }
 else {
        this.intermediateClassName="String_Node_Str" + commonSuperTypeOfSourceTypeDeclarations.getName();
        CompilationUnit compilationUnit=sourceCompilationUnits.get(0);
        ICompilationUnit iCompilationUnit=(ICompilationUnit)compilationUnit.getJavaElement();
        IContainer container=(IContainer)iCompilationUnit.getResource().getParent();
        if (container instanceof IProject) {
          IProject contextProject=(IProject)container;
          file=contextProject.getFile(intermediateClassName + "String_Node_Str");
        }
 else         if (container instanceof IFolder) {
          IFolder contextFolder=(IFolder)container;
          file=contextFolder.getFile(intermediateClassName + "String_Node_Str");
        }
        boolean intermediateAlreadyExists=false;
        ICompilationUnit intermediateICompilationUnit=JavaCore.createCompilationUnitFrom(file);
        javaElementsToOpenInEditor.add(intermediateICompilationUnit);
        ASTParser intermediateParser=ASTParser.newParser(AST.JLS4);
        intermediateParser.setKind(ASTParser.K_COMPILATION_UNIT);
        if (file.exists()) {
          intermediateAlreadyExists=true;
          intermediateParser.setSource(intermediateICompilationUnit);
          intermediateParser.setResolveBindings(true);
        }
 else {
          document=new Document();
          intermediateParser.setSource(document.get().toCharArray());
        }
        CompilationUnit intermediateCompilationUnit=(CompilationUnit)intermediateParser.createAST(null);
        AST intermediateAST=intermediateCompilationUnit.getAST();
        ASTRewrite intermediateRewriter=ASTRewrite.create(intermediateAST);
        ListRewrite intermediateTypesRewrite=intermediateRewriter.getListRewrite(intermediateCompilationUnit,CompilationUnit.TYPES_PROPERTY);
        TypeDeclaration intermediateTypeDeclaration=null;
        if (intermediateAlreadyExists) {
          List<AbstractTypeDeclaration> abstractTypeDeclarations=intermediateCompilationUnit.types();
          for (          AbstractTypeDeclaration abstractTypeDeclaration : abstractTypeDeclarations) {
            if (abstractTypeDeclaration instanceof TypeDeclaration) {
              TypeDeclaration typeDeclaration=(TypeDeclaration)abstractTypeDeclaration;
              if (typeDeclaration.getName().getIdentifier().equals(intermediateClassName)) {
                intermediateTypeDeclaration=typeDeclaration;
                int intermediateModifiers=intermediateTypeDeclaration.getModifiers();
                if ((intermediateModifiers & Modifier.ABSTRACT) == 0) {
                  ListRewrite intermediateModifiersRewrite=intermediateRewriter.getListRewrite(intermediateTypeDeclaration,TypeDeclaration.MODIFIERS2_PROPERTY);
                  intermediateModifiersRewrite.insertLast(intermediateAST.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD),null);
                }
                break;
              }
            }
          }
          MultiTextEdit intermediateMultiTextEdit=new MultiTextEdit();
          CompilationUnitChange intermediateCompilationUnitChange=new CompilationUnitChange("String_Node_Str",intermediateICompilationUnit);
          intermediateCompilationUnitChange.setEdit(intermediateMultiTextEdit);
          compilationUnitChanges.put(intermediateICompilationUnit,intermediateCompilationUnitChange);
        }
 else {
          if (compilationUnit.getPackage() != null) {
            intermediateRewriter.set(intermediateCompilationUnit,CompilationUnit.PACKAGE_PROPERTY,compilationUnit.getPackage(),null);
          }
          intermediateTypeDeclaration=intermediateAST.newTypeDeclaration();
          SimpleName intermediateName=intermediateAST.newSimpleName(intermediateClassName);
          intermediateRewriter.set(intermediateTypeDeclaration,TypeDeclaration.NAME_PROPERTY,intermediateName,null);
          ListRewrite intermediateModifiersRewrite=intermediateRewriter.getListRewrite(intermediateTypeDeclaration,TypeDeclaration.MODIFIERS2_PROPERTY);
          intermediateModifiersRewrite.insertLast(intermediateAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
          intermediateModifiersRewrite.insertLast(intermediateAST.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD),null);
          intermediateRewriter.set(intermediateTypeDeclaration,TypeDeclaration.SUPERCLASS_TYPE_PROPERTY,intermediateAST.newSimpleType(intermediateAST.newSimpleName(commonSuperTypeOfSourceTypeDeclarations.getName())),null);
          intermediateTypesRewrite.insertLast(intermediateTypeDeclaration,null);
        }
        sourceCompilationUnit=intermediateCompilationUnit;
        sourceICompilationUnit=intermediateICompilationUnit;
        sourceTypeDeclaration=intermediateTypeDeclaration;
        sourceRewriter=intermediateRewriter;
        ast=intermediateAST;
      }
    }
  }
  MethodDeclaration sourceMethodDeclaration=sourceMethodDeclarations.get(0);
  Set<ITypeBinding> requiredImportTypeBindings=new LinkedHashSet<ITypeBinding>();
  ListRewrite bodyDeclarationsRewrite=sourceRewriter.getListRewrite(sourceTypeDeclaration,TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
  if (commonSuperTypeOfSourceTypeDeclarations != null) {
    Set<ITypeBinding> typeBindings=new LinkedHashSet<ITypeBinding>();
    typeBindings.add(commonSuperTypeOfSourceTypeDeclarations);
    getSimpleTypeBindings(typeBindings,requiredImportTypeBindings);
  }
  if (!sourceTypeDeclarations.get(0).resolveBinding().isEqualTo(sourceTypeDeclarations.get(1).resolveBinding())) {
    Set<VariableDeclaration> accessedLocalFieldsG1=mapper.getAccessedLocalFieldsG1();
    Set<VariableDeclaration> accessedLocalFieldsG2=mapper.getAccessedLocalFieldsG2();
    for (    VariableDeclaration localFieldG1 : accessedLocalFieldsG1) {
      FieldDeclaration originalFieldDeclarationG1=(FieldDeclaration)localFieldG1.getParent();
      for (      VariableDeclaration localFieldG2 : accessedLocalFieldsG2) {
        FieldDeclaration originalFieldDeclarationG2=(FieldDeclaration)localFieldG2.getParent();
        if (localFieldG1.getName().getIdentifier().equals(localFieldG2.getName().getIdentifier())) {
          if (originalFieldDeclarationG1.getType().resolveBinding().isEqualTo(originalFieldDeclarationG2.getType().resolveBinding())) {
            Set<ITypeBinding> typeBindings=new LinkedHashSet<ITypeBinding>();
            typeBindings.add(localFieldG1.resolveBinding().getType());
            getSimpleTypeBindings(typeBindings,requiredImportTypeBindings);
            fieldDeclarationsToBePulledUp.get(0).add(localFieldG1);
            fieldDeclarationsToBePulledUp.get(1).add(localFieldG2);
            VariableDeclarationFragment fragment=ast.newVariableDeclarationFragment();
            sourceRewriter.set(fragment,VariableDeclarationFragment.NAME_PROPERTY,ast.newSimpleName(localFieldG1.getName().getIdentifier()),null);
            if (localFieldG1.getInitializer() != null && localFieldG2.getInitializer() != null) {
              Expression initializer1=localFieldG1.getInitializer();
              Expression initializer2=localFieldG2.getInitializer();
              if (initializer1.subtreeMatch(new ASTMatcher(),initializer2)) {
                sourceRewriter.set(fragment,VariableDeclarationFragment.INITIALIZER_PROPERTY,ASTNode.copySubtree(ast,initializer1),null);
              }
            }
            FieldDeclaration newFieldDeclaration=ast.newFieldDeclaration(fragment);
            sourceRewriter.set(newFieldDeclaration,FieldDeclaration.TYPE_PROPERTY,originalFieldDeclarationG1.getType(),null);
            if (originalFieldDeclarationG1.getJavadoc() != null) {
              sourceRewriter.set(newFieldDeclaration,FieldDeclaration.JAVADOC_PROPERTY,originalFieldDeclarationG1.getJavadoc(),null);
            }
            ListRewrite newFieldDeclarationModifiersRewrite=sourceRewriter.getListRewrite(newFieldDeclaration,FieldDeclaration.MODIFIERS2_PROPERTY);
            newFieldDeclarationModifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD),null);
            List<IExtendedModifier> originalModifiers=originalFieldDeclarationG1.modifiers();
            for (            IExtendedModifier extendedModifier : originalModifiers) {
              if (extendedModifier.isModifier()) {
                Modifier modifier=(Modifier)extendedModifier;
                if (modifier.isFinal()) {
                  newFieldDeclarationModifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD),null);
                }
 else                 if (modifier.isStatic()) {
                  newFieldDeclarationModifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.STATIC_KEYWORD),null);
                }
 else                 if (modifier.isTransient()) {
                  newFieldDeclarationModifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD),null);
                }
 else                 if (modifier.isVolatile()) {
                  newFieldDeclarationModifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD),null);
                }
              }
            }
            bodyDeclarationsRewrite.insertLast(newFieldDeclaration,null);
            break;
          }
        }
      }
    }
    Set<MethodInvocationObject> accessedLocalMethodsG1=mapper.getAccessedLocalMethodsG1();
    Set<MethodInvocationObject> accessedLocalMethodsG2=mapper.getAccessedLocalMethodsG2();
    for (    MethodInvocationObject localMethodG1 : accessedLocalMethodsG1) {
      for (      MethodInvocationObject localMethodG2 : accessedLocalMethodsG2) {
        if (localMethodG1.getMethodName().equals(localMethodG2.getMethodName()) && localMethodG1.getReturnType().equals(localMethodG2.getReturnType()) && localMethodG1.getParameterTypeList().equals(localMethodG2.getParameterTypeList())) {
          MethodDeclaration[] methodDeclarationsG1=sourceTypeDeclarations.get(0).getMethods();
          IMethodBinding localMethodBindingG1=localMethodG1.getMethodInvocation().resolveMethodBinding();
          MethodDeclaration methodDeclaration1=null;
          for (          MethodDeclaration methodDeclarationG1 : methodDeclarationsG1) {
            if (methodDeclarationG1.resolveBinding().isEqualTo(localMethodBindingG1)) {
              methodDeclaration1=methodDeclarationG1;
              break;
            }
          }
          MethodDeclaration[] methodDeclarationsG2=sourceTypeDeclarations.get(1).getMethods();
          IMethodBinding localMethodBindingG2=localMethodG2.getMethodInvocation().resolveMethodBinding();
          MethodDeclaration methodDeclaration2=null;
          for (          MethodDeclaration methodDeclarationG2 : methodDeclarationsG2) {
            if (methodDeclarationG2.resolveBinding().isEqualTo(localMethodBindingG2)) {
              methodDeclaration2=methodDeclarationG2;
              break;
            }
          }
          boolean exactClones=methodDeclaration1.subtreeMatch(new ASTMatcher(),methodDeclaration2);
          if (exactClones) {
            bodyDeclarationsRewrite.insertLast(methodDeclaration1,null);
            methodDeclarationsToBePulledUp.get(0).add(methodDeclaration1);
            methodDeclarationsToBePulledUp.get(1).add(methodDeclaration2);
          }
 else {
            MethodDeclaration newMethodDeclaration=ast.newMethodDeclaration();
            sourceRewriter.set(newMethodDeclaration,MethodDeclaration.NAME_PROPERTY,ast.newSimpleName(methodDeclaration1.getName().getIdentifier()),null);
            sourceRewriter.set(newMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,methodDeclaration1.getReturnType2(),null);
            ListRewrite modifiersRewrite=sourceRewriter.getListRewrite(newMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
            List<IExtendedModifier> originalModifiers=methodDeclaration1.modifiers();
            for (            IExtendedModifier extendedModifier : originalModifiers) {
              if (extendedModifier.isModifier()) {
                Modifier modifier=(Modifier)extendedModifier;
                if (modifier.isProtected()) {
                  modifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD),null);
                }
 else                 if (modifier.isPublic()) {
                  modifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
                }
              }
            }
            modifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD),null);
            ListRewrite parametersRewrite=sourceRewriter.getListRewrite(newMethodDeclaration,MethodDeclaration.PARAMETERS_PROPERTY);
            List<SingleVariableDeclaration> parameters=methodDeclaration1.parameters();
            for (            SingleVariableDeclaration parameter : parameters) {
              parametersRewrite.insertLast(parameter,null);
            }
            ListRewrite thrownExceptionsRewrite=sourceRewriter.getListRewrite(newMethodDeclaration,MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY);
            List<Name> thrownExceptions=methodDeclaration1.thrownExceptions();
            for (            Name thrownException : thrownExceptions) {
              thrownExceptionsRewrite.insertLast(thrownException,null);
            }
            bodyDeclarationsRewrite.insertLast(newMethodDeclaration,null);
          }
          break;
        }
      }
    }
  }
  MethodDeclaration newMethodDeclaration=ast.newMethodDeclaration();
  sourceRewriter.set(newMethodDeclaration,MethodDeclaration.NAME_PROPERTY,ast.newSimpleName(extractedMethodName),null);
  List<VariableDeclaration> returnedVariables1=this.returnedVariables.get(0);
  List<VariableDeclaration> returnedVariables2=this.returnedVariables.get(1);
  ITypeBinding returnTypeBinding=null;
  if (returnedVariables1.size() == 1 && returnedVariables2.size() == 1) {
    Type returnType1=extractType(returnedVariables1.get(0));
    Type returnType2=extractType(returnedVariables2.get(0));
    if (returnType1.resolveBinding().isEqualTo(returnType2.resolveBinding()))     returnTypeBinding=returnType1.resolveBinding();
 else     returnTypeBinding=ASTNodeMatcher.commonSuperType(returnType1.resolveBinding(),returnType2.resolveBinding());
  }
 else {
    returnTypeBinding=findReturnTypeBinding();
  }
  if (returnTypeBinding != null) {
    Set<ITypeBinding> typeBindings=new LinkedHashSet<ITypeBinding>();
    typeBindings.add(returnTypeBinding);
    getSimpleTypeBindings(typeBindings,requiredImportTypeBindings);
    Type returnType=generateTypeFromTypeBinding(returnTypeBinding,ast,sourceRewriter);
    sourceRewriter.set(newMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,returnType,null);
  }
 else {
    sourceRewriter.set(newMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,ast.newPrimitiveType(PrimitiveType.VOID),null);
  }
  ListRewrite modifierRewrite=sourceRewriter.getListRewrite(newMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
  if (sourceTypeDeclarations.get(0).resolveBinding().isEqualTo(sourceTypeDeclaration.resolveBinding()) && sourceTypeDeclarations.get(1).resolveBinding().isEqualTo(sourceTypeDeclaration.resolveBinding())) {
    Modifier accessModifier=newMethodDeclaration.getAST().newModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
    modifierRewrite.insertLast(accessModifier,null);
  }
 else {
    Modifier accessModifier=newMethodDeclaration.getAST().newModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
    modifierRewrite.insertLast(accessModifier,null);
  }
  if ((sourceMethodDeclarations.get(0).getModifiers() & Modifier.STATIC) != 0 && (sourceMethodDeclarations.get(1).getModifiers() & Modifier.STATIC) != 0) {
    Modifier staticModifier=newMethodDeclaration.getAST().newModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
    modifierRewrite.insertLast(staticModifier,null);
  }
  ListRewrite thrownExceptionRewrite=sourceRewriter.getListRewrite(newMethodDeclaration,MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY);
  List<Name> thrownExceptions1=sourceMethodDeclarations.get(0).thrownExceptions();
  List<Name> thrownExceptions2=sourceMethodDeclarations.get(1).thrownExceptions();
  for (  Name thrownException1 : thrownExceptions1) {
    for (    Name thrownException2 : thrownExceptions2) {
      if (thrownException1.resolveTypeBinding().isEqualTo(thrownException2.resolveTypeBinding())) {
        thrownExceptionRewrite.insertLast(thrownException1,null);
        break;
      }
    }
  }
  ListRewrite parameterRewrite=sourceRewriter.getListRewrite(newMethodDeclaration,MethodDeclaration.PARAMETERS_PROPERTY);
  Map<String,ArrayList<VariableDeclaration>> commonPassedParameters=mapper.getCommonPassedParameters();
  for (  String parameterName : commonPassedParameters.keySet()) {
    ArrayList<VariableDeclaration> variableDeclarations=commonPassedParameters.get(parameterName);
    VariableDeclaration variableDeclaration1=variableDeclarations.get(0);
    VariableDeclaration variableDeclaration2=variableDeclarations.get(1);
    if (parameterIsUsedByNodesWithoutDifferences(variableDeclaration1,variableDeclaration2)) {
      if (!variableDeclaration1.resolveBinding().isField() && !variableDeclaration2.resolveBinding().isField()) {
        ITypeBinding typeBinding1=extractType(variableDeclaration1).resolveBinding();
        ITypeBinding typeBinding2=extractType(variableDeclaration2).resolveBinding();
        ITypeBinding typeBinding=null;
        if (!typeBinding1.isEqualTo(typeBinding2)) {
          ITypeBinding commonSuperTypeBinding=ASTNodeMatcher.commonSuperType(typeBinding1,typeBinding2);
          if (commonSuperTypeBinding != null) {
            typeBinding=commonSuperTypeBinding;
          }
        }
 else {
          typeBinding=typeBinding1;
        }
        Type variableType=generateTypeFromTypeBinding(typeBinding,ast,sourceRewriter);
        Set<ITypeBinding> typeBindings=new LinkedHashSet<ITypeBinding>();
        typeBindings.add(typeBinding);
        getSimpleTypeBindings(typeBindings,requiredImportTypeBindings);
        SingleVariableDeclaration parameter=ast.newSingleVariableDeclaration();
        sourceRewriter.set(parameter,SingleVariableDeclaration.NAME_PROPERTY,variableDeclaration1.getName(),null);
        sourceRewriter.set(parameter,SingleVariableDeclaration.TYPE_PROPERTY,variableType,null);
        parameterRewrite.insertLast(parameter,null);
        originalPassedParameters.put(parameterName,variableDeclarations);
      }
    }
  }
  Block newMethodBody=newMethodDeclaration.getAST().newBlock();
  ListRewrite methodBodyRewrite=sourceRewriter.getListRewrite(newMethodBody,Block.STATEMENTS_PROPERTY);
  for (  PDGNodeMapping pdgNodeMapping : sortedNodeMappings) {
    PDGNode pdgNode1=pdgNodeMapping.getNodeG1();
    Statement statement1=pdgNode1.getASTStatement();
    TypeVisitor typeVisitor1=new TypeVisitor();
    statement1.accept(typeVisitor1);
    getSimpleTypeBindings(typeVisitor1.getTypeBindings(),requiredImportTypeBindings);
    PDGNode pdgNode2=pdgNodeMapping.getNodeG2();
    Statement statement2=pdgNode2.getASTStatement();
    TypeVisitor typeVisitor2=new TypeVisitor();
    statement2.accept(typeVisitor2);
    getSimpleTypeBindings(typeVisitor2.getTypeBindings(),requiredImportTypeBindings);
  }
  CloneStructureNode root=mapper.getCloneStructureRoot();
  for (  CloneStructureNode child : root.getChildren()) {
    if (child.getMapping() instanceof PDGNodeMapping) {
      Statement statement=processCloneStructureNode(child,ast,sourceRewriter);
      methodBodyRewrite.insertLast(statement,null);
    }
  }
  if (returnedVariables1.size() == 1 && returnedVariables2.size() == 1 && findReturnTypeBinding() == null) {
    ReturnStatement returnStatement=ast.newReturnStatement();
    sourceRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,returnedVariables1.get(0).getName(),null);
    methodBodyRewrite.insertLast(returnStatement,null);
  }
  int i=0;
  for (  ASTNodeDifference difference : parameterizedDifferenceMap.values()) {
    AbstractExpression expression1=difference.getExpression1();
    AbstractExpression expression2=difference.getExpression2();
    boolean isReturnedVariable=false;
    if (expression1 != null) {
      isReturnedVariable=isReturnedVariable(expression1.getExpression(),this.returnedVariables.get(0));
    }
 else     if (expression2 != null) {
      isReturnedVariable=isReturnedVariable(expression2.getExpression(),this.returnedVariables.get(1));
    }
    if (!isReturnedVariable) {
      ITypeBinding typeBinding=null;
      if (difference.containsDifferenceType(DifferenceType.SUBCLASS_TYPE_MISMATCH) || differenceContainsSubDifferenceWithSubclassTypeMismatch(difference)) {
        ITypeBinding typeBinding1=expression1 != null ? expression1.getExpression().resolveTypeBinding() : expression2.getExpression().resolveTypeBinding();
        ITypeBinding typeBinding2=expression2 != null ? expression2.getExpression().resolveTypeBinding() : expression1.getExpression().resolveTypeBinding();
        if (!typeBinding1.isEqualTo(typeBinding2)) {
          ITypeBinding commonSuperTypeBinding=ASTNodeMatcher.commonSuperType(typeBinding1,typeBinding2);
          if (commonSuperTypeBinding != null) {
            typeBinding=commonSuperTypeBinding;
          }
        }
 else {
          typeBinding=typeBinding1;
        }
      }
 else {
        typeBinding=expression1 != null ? expression1.getExpression().resolveTypeBinding() : expression2.getExpression().resolveTypeBinding();
      }
      Type type=generateTypeFromTypeBinding(typeBinding,ast,sourceRewriter);
      Set<ITypeBinding> typeBindings=new LinkedHashSet<ITypeBinding>();
      typeBindings.add(typeBinding);
      getSimpleTypeBindings(typeBindings,requiredImportTypeBindings);
      SingleVariableDeclaration parameter=ast.newSingleVariableDeclaration();
      sourceRewriter.set(parameter,SingleVariableDeclaration.NAME_PROPERTY,ast.newSimpleName("String_Node_Str" + i),null);
      i++;
      sourceRewriter.set(parameter,SingleVariableDeclaration.TYPE_PROPERTY,type,null);
      parameterRewrite.insertLast(parameter,null);
    }
  }
  sourceRewriter.set(newMethodDeclaration,MethodDeclaration.BODY_PROPERTY,newMethodBody,null);
  bodyDeclarationsRewrite.insertLast(newMethodDeclaration,null);
  try {
    CompilationUnitChange change=compilationUnitChanges.get(sourceICompilationUnit);
    if (change != null) {
      ImportRewrite importRewrite=ImportRewrite.create(sourceCompilationUnit,true);
      for (      ITypeBinding typeBinding : requiredImportTypeBindings) {
        if (!typeBinding.isNested())         importRewrite.addImport(typeBinding);
      }
      TextEdit importEdit=importRewrite.rewriteImports(null);
      if (importRewrite.getCreatedImports().length > 0) {
        change.getEdit().addChild(importEdit);
        change.addTextEditGroup(new TextEditGroup("String_Node_Str",new TextEdit[]{importEdit}));
      }
      TextEdit sourceEdit=sourceRewriter.rewriteAST();
      change.getEdit().addChild(sourceEdit);
      change.addTextEditGroup(new TextEditGroup("String_Node_Str",new TextEdit[]{sourceEdit}));
    }
    if (document != null) {
      for (      ITypeBinding typeBinding : requiredImportTypeBindings) {
        addImportDeclaration(typeBinding,sourceCompilationUnit,sourceRewriter);
      }
      TextEdit intermediateEdit=sourceRewriter.rewriteAST(document,null);
      intermediateEdit.apply(document);
      CreateCompilationUnitChange createCompilationUnitChange=new CreateCompilationUnitChange(sourceICompilationUnit,document.get(),file.getCharset());
      createCompilationUnitChanges.put(sourceICompilationUnit,createCompilationUnitChange);
    }
  }
 catch (  JavaModelException e) {
    e.printStackTrace();
  }
catch (  MalformedTreeException e) {
    e.printStackTrace();
  }
catch (  BadLocationException e) {
    e.printStackTrace();
  }
catch (  CoreException e) {
    e.printStackTrace();
  }
}

Fixed version (ground truth):
private void extractClone(){
  CompilationUnit sourceCompilationUnit=null;
  ICompilationUnit sourceICompilationUnit=null;
  TypeDeclaration sourceTypeDeclaration=null;
  ASTRewrite sourceRewriter=null;
  AST ast=null;
  Document document=null;
  IFile file=null;
  ITypeBinding commonSuperTypeOfSourceTypeDeclarations=null;
  if (sourceTypeDeclarations.get(0).resolveBinding().isEqualTo(sourceTypeDeclarations.get(1).resolveBinding())) {
    sourceCompilationUnit=sourceCompilationUnits.get(0);
    sourceICompilationUnit=(ICompilationUnit)sourceCompilationUnit.getJavaElement();
    sourceTypeDeclaration=sourceTypeDeclarations.get(0);
    sourceRewriter=ASTRewrite.create(sourceTypeDeclaration.getAST());
    ast=sourceTypeDeclaration.getAST();
  }
 else {
    ITypeBinding typeBinding1=sourceTypeDeclarations.get(0).resolveBinding();
    ITypeBinding typeBinding2=sourceTypeDeclarations.get(1).resolveBinding();
    commonSuperTypeOfSourceTypeDeclarations=ASTNodeMatcher.commonSuperType(typeBinding1,typeBinding2);
    if (commonSuperTypeOfSourceTypeDeclarations != null) {
      boolean superclassInheritedOnlyByRefactoringSubclasses=false;
      if (!commonSuperTypeOfSourceTypeDeclarations.getQualifiedName().equals("String_Node_Str")) {
        CompilationUnitCache cache=CompilationUnitCache.getInstance();
        Set<IType> subTypes=cache.getSubTypes((IType)commonSuperTypeOfSourceTypeDeclarations.getJavaElement());
        if (subTypes.size() == 2 && subTypes.contains((IType)typeBinding1.getJavaElement()) && subTypes.contains((IType)typeBinding2.getJavaElement()))         superclassInheritedOnlyByRefactoringSubclasses=true;
      }
      boolean superclassIsOneOfTheSourceTypeDeclarations=false;
      if (typeBinding1.isEqualTo(commonSuperTypeOfSourceTypeDeclarations) || typeBinding2.isEqualTo(commonSuperTypeOfSourceTypeDeclarations))       superclassIsOneOfTheSourceTypeDeclarations=true;
      if (((mapper.getAccessedLocalFieldsG1().isEmpty() && mapper.getAccessedLocalFieldsG2().isEmpty() && mapper.getAccessedLocalMethodsG1().isEmpty()&& mapper.getAccessedLocalMethodsG2().isEmpty()) || superclassInheritedOnlyByRefactoringSubclasses || superclassIsOneOfTheSourceTypeDeclarations) && ASTReader.getSystemObject().getClassObject(commonSuperTypeOfSourceTypeDeclarations.getQualifiedName()) != null) {
        IJavaElement javaElement=commonSuperTypeOfSourceTypeDeclarations.getJavaElement();
        javaElementsToOpenInEditor.add(javaElement);
        ICompilationUnit iCompilationUnit=(ICompilationUnit)javaElement.getParent();
        ASTParser parser=ASTParser.newParser(AST.JLS4);
        parser.setKind(ASTParser.K_COMPILATION_UNIT);
        parser.setSource(iCompilationUnit);
        parser.setResolveBindings(true);
        CompilationUnit compilationUnit=(CompilationUnit)parser.createAST(null);
        List<AbstractTypeDeclaration> typeDeclarations=compilationUnit.types();
        for (        AbstractTypeDeclaration abstractTypeDeclaration : typeDeclarations) {
          if (abstractTypeDeclaration instanceof TypeDeclaration) {
            TypeDeclaration typeDeclaration=(TypeDeclaration)abstractTypeDeclaration;
            if (typeDeclaration.resolveBinding().isEqualTo(commonSuperTypeOfSourceTypeDeclarations)) {
              sourceCompilationUnit=compilationUnit;
              sourceICompilationUnit=iCompilationUnit;
              sourceTypeDeclaration=typeDeclaration;
              sourceRewriter=ASTRewrite.create(sourceTypeDeclaration.getAST());
              ast=sourceTypeDeclaration.getAST();
              break;
            }
          }
        }
        MultiTextEdit multiTextEdit=new MultiTextEdit();
        CompilationUnitChange compilationUnitChange=new CompilationUnitChange("String_Node_Str",iCompilationUnit);
        compilationUnitChange.setEdit(multiTextEdit);
        compilationUnitChanges.put(iCompilationUnit,compilationUnitChange);
      }
 else {
        this.intermediateClassName="String_Node_Str" + commonSuperTypeOfSourceTypeDeclarations.getName();
        CompilationUnit compilationUnit=sourceCompilationUnits.get(0);
        ICompilationUnit iCompilationUnit=(ICompilationUnit)compilationUnit.getJavaElement();
        IContainer container=(IContainer)iCompilationUnit.getResource().getParent();
        if (container instanceof IProject) {
          IProject contextProject=(IProject)container;
          file=contextProject.getFile(intermediateClassName + "String_Node_Str");
        }
 else         if (container instanceof IFolder) {
          IFolder contextFolder=(IFolder)container;
          file=contextFolder.getFile(intermediateClassName + "String_Node_Str");
        }
        boolean intermediateAlreadyExists=false;
        ICompilationUnit intermediateICompilationUnit=JavaCore.createCompilationUnitFrom(file);
        javaElementsToOpenInEditor.add(intermediateICompilationUnit);
        ASTParser intermediateParser=ASTParser.newParser(AST.JLS4);
        intermediateParser.setKind(ASTParser.K_COMPILATION_UNIT);
        if (file.exists()) {
          intermediateAlreadyExists=true;
          intermediateParser.setSource(intermediateICompilationUnit);
          intermediateParser.setResolveBindings(true);
        }
 else {
          document=new Document();
          intermediateParser.setSource(document.get().toCharArray());
        }
        CompilationUnit intermediateCompilationUnit=(CompilationUnit)intermediateParser.createAST(null);
        AST intermediateAST=intermediateCompilationUnit.getAST();
        ASTRewrite intermediateRewriter=ASTRewrite.create(intermediateAST);
        ListRewrite intermediateTypesRewrite=intermediateRewriter.getListRewrite(intermediateCompilationUnit,CompilationUnit.TYPES_PROPERTY);
        TypeDeclaration intermediateTypeDeclaration=null;
        if (intermediateAlreadyExists) {
          List<AbstractTypeDeclaration> abstractTypeDeclarations=intermediateCompilationUnit.types();
          for (          AbstractTypeDeclaration abstractTypeDeclaration : abstractTypeDeclarations) {
            if (abstractTypeDeclaration instanceof TypeDeclaration) {
              TypeDeclaration typeDeclaration=(TypeDeclaration)abstractTypeDeclaration;
              if (typeDeclaration.getName().getIdentifier().equals(intermediateClassName)) {
                intermediateTypeDeclaration=typeDeclaration;
                int intermediateModifiers=intermediateTypeDeclaration.getModifiers();
                if ((intermediateModifiers & Modifier.ABSTRACT) == 0) {
                  ListRewrite intermediateModifiersRewrite=intermediateRewriter.getListRewrite(intermediateTypeDeclaration,TypeDeclaration.MODIFIERS2_PROPERTY);
                  intermediateModifiersRewrite.insertLast(intermediateAST.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD),null);
                }
                break;
              }
            }
          }
          MultiTextEdit intermediateMultiTextEdit=new MultiTextEdit();
          CompilationUnitChange intermediateCompilationUnitChange=new CompilationUnitChange("String_Node_Str",intermediateICompilationUnit);
          intermediateCompilationUnitChange.setEdit(intermediateMultiTextEdit);
          compilationUnitChanges.put(intermediateICompilationUnit,intermediateCompilationUnitChange);
        }
 else {
          if (compilationUnit.getPackage() != null) {
            intermediateRewriter.set(intermediateCompilationUnit,CompilationUnit.PACKAGE_PROPERTY,compilationUnit.getPackage(),null);
          }
          intermediateTypeDeclaration=intermediateAST.newTypeDeclaration();
          SimpleName intermediateName=intermediateAST.newSimpleName(intermediateClassName);
          intermediateRewriter.set(intermediateTypeDeclaration,TypeDeclaration.NAME_PROPERTY,intermediateName,null);
          ListRewrite intermediateModifiersRewrite=intermediateRewriter.getListRewrite(intermediateTypeDeclaration,TypeDeclaration.MODIFIERS2_PROPERTY);
          intermediateModifiersRewrite.insertLast(intermediateAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
          intermediateModifiersRewrite.insertLast(intermediateAST.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD),null);
          intermediateRewriter.set(intermediateTypeDeclaration,TypeDeclaration.SUPERCLASS_TYPE_PROPERTY,intermediateAST.newSimpleType(intermediateAST.newSimpleName(commonSuperTypeOfSourceTypeDeclarations.getName())),null);
          intermediateTypesRewrite.insertLast(intermediateTypeDeclaration,null);
        }
        sourceCompilationUnit=intermediateCompilationUnit;
        sourceICompilationUnit=intermediateICompilationUnit;
        sourceTypeDeclaration=intermediateTypeDeclaration;
        sourceRewriter=intermediateRewriter;
        ast=intermediateAST;
      }
    }
  }
  MethodDeclaration sourceMethodDeclaration=sourceMethodDeclarations.get(0);
  Set<ITypeBinding> requiredImportTypeBindings=new LinkedHashSet<ITypeBinding>();
  ListRewrite bodyDeclarationsRewrite=sourceRewriter.getListRewrite(sourceTypeDeclaration,TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
  if (commonSuperTypeOfSourceTypeDeclarations != null) {
    Set<ITypeBinding> typeBindings=new LinkedHashSet<ITypeBinding>();
    typeBindings.add(commonSuperTypeOfSourceTypeDeclarations);
    getSimpleTypeBindings(typeBindings,requiredImportTypeBindings);
  }
  if (!sourceTypeDeclarations.get(0).resolveBinding().isEqualTo(sourceTypeDeclarations.get(1).resolveBinding())) {
    Set<VariableDeclaration> accessedLocalFieldsG1=mapper.getAccessedLocalFieldsG1();
    Set<VariableDeclaration> accessedLocalFieldsG2=mapper.getAccessedLocalFieldsG2();
    for (    VariableDeclaration localFieldG1 : accessedLocalFieldsG1) {
      FieldDeclaration originalFieldDeclarationG1=(FieldDeclaration)localFieldG1.getParent();
      for (      VariableDeclaration localFieldG2 : accessedLocalFieldsG2) {
        FieldDeclaration originalFieldDeclarationG2=(FieldDeclaration)localFieldG2.getParent();
        if (localFieldG1.getName().getIdentifier().equals(localFieldG2.getName().getIdentifier())) {
          if (originalFieldDeclarationG1.getType().resolveBinding().isEqualTo(originalFieldDeclarationG2.getType().resolveBinding())) {
            Set<ITypeBinding> typeBindings=new LinkedHashSet<ITypeBinding>();
            typeBindings.add(localFieldG1.resolveBinding().getType());
            getSimpleTypeBindings(typeBindings,requiredImportTypeBindings);
            fieldDeclarationsToBePulledUp.get(0).add(localFieldG1);
            fieldDeclarationsToBePulledUp.get(1).add(localFieldG2);
            VariableDeclarationFragment fragment=ast.newVariableDeclarationFragment();
            sourceRewriter.set(fragment,VariableDeclarationFragment.NAME_PROPERTY,ast.newSimpleName(localFieldG1.getName().getIdentifier()),null);
            if (localFieldG1.getInitializer() != null && localFieldG2.getInitializer() != null) {
              Expression initializer1=localFieldG1.getInitializer();
              Expression initializer2=localFieldG2.getInitializer();
              if (initializer1.subtreeMatch(new ASTMatcher(),initializer2)) {
                sourceRewriter.set(fragment,VariableDeclarationFragment.INITIALIZER_PROPERTY,ASTNode.copySubtree(ast,initializer1),null);
              }
            }
            FieldDeclaration newFieldDeclaration=ast.newFieldDeclaration(fragment);
            sourceRewriter.set(newFieldDeclaration,FieldDeclaration.TYPE_PROPERTY,originalFieldDeclarationG1.getType(),null);
            if (originalFieldDeclarationG1.getJavadoc() != null) {
              sourceRewriter.set(newFieldDeclaration,FieldDeclaration.JAVADOC_PROPERTY,originalFieldDeclarationG1.getJavadoc(),null);
            }
            ListRewrite newFieldDeclarationModifiersRewrite=sourceRewriter.getListRewrite(newFieldDeclaration,FieldDeclaration.MODIFIERS2_PROPERTY);
            newFieldDeclarationModifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD),null);
            List<IExtendedModifier> originalModifiers=originalFieldDeclarationG1.modifiers();
            for (            IExtendedModifier extendedModifier : originalModifiers) {
              if (extendedModifier.isModifier()) {
                Modifier modifier=(Modifier)extendedModifier;
                if (modifier.isFinal()) {
                  newFieldDeclarationModifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD),null);
                }
 else                 if (modifier.isStatic()) {
                  newFieldDeclarationModifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.STATIC_KEYWORD),null);
                }
 else                 if (modifier.isTransient()) {
                  newFieldDeclarationModifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD),null);
                }
 else                 if (modifier.isVolatile()) {
                  newFieldDeclarationModifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD),null);
                }
              }
            }
            bodyDeclarationsRewrite.insertLast(newFieldDeclaration,null);
            break;
          }
        }
      }
    }
    Set<MethodInvocationObject> accessedLocalMethodsG1=mapper.getAccessedLocalMethodsG1();
    Set<MethodInvocationObject> accessedLocalMethodsG2=mapper.getAccessedLocalMethodsG2();
    for (    MethodInvocationObject localMethodG1 : accessedLocalMethodsG1) {
      for (      MethodInvocationObject localMethodG2 : accessedLocalMethodsG2) {
        if (localMethodG1.getMethodName().equals(localMethodG2.getMethodName()) && localMethodG1.getReturnType().equals(localMethodG2.getReturnType()) && localMethodG1.getParameterTypeList().equals(localMethodG2.getParameterTypeList())) {
          MethodDeclaration[] methodDeclarationsG1=sourceTypeDeclarations.get(0).getMethods();
          IMethodBinding localMethodBindingG1=localMethodG1.getMethodInvocation().resolveMethodBinding();
          MethodDeclaration methodDeclaration1=null;
          for (          MethodDeclaration methodDeclarationG1 : methodDeclarationsG1) {
            if (methodDeclarationG1.resolveBinding().isEqualTo(localMethodBindingG1)) {
              methodDeclaration1=methodDeclarationG1;
              break;
            }
          }
          MethodDeclaration[] methodDeclarationsG2=sourceTypeDeclarations.get(1).getMethods();
          IMethodBinding localMethodBindingG2=localMethodG2.getMethodInvocation().resolveMethodBinding();
          MethodDeclaration methodDeclaration2=null;
          for (          MethodDeclaration methodDeclarationG2 : methodDeclarationsG2) {
            if (methodDeclarationG2.resolveBinding().isEqualTo(localMethodBindingG2)) {
              methodDeclaration2=methodDeclarationG2;
              break;
            }
          }
          boolean exactClones=methodDeclaration1.subtreeMatch(new ASTMatcher(),methodDeclaration2);
          if (exactClones) {
            bodyDeclarationsRewrite.insertLast(methodDeclaration1,null);
            methodDeclarationsToBePulledUp.get(0).add(methodDeclaration1);
            methodDeclarationsToBePulledUp.get(1).add(methodDeclaration2);
          }
 else {
            MethodDeclaration newMethodDeclaration=ast.newMethodDeclaration();
            sourceRewriter.set(newMethodDeclaration,MethodDeclaration.NAME_PROPERTY,ast.newSimpleName(methodDeclaration1.getName().getIdentifier()),null);
            sourceRewriter.set(newMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,methodDeclaration1.getReturnType2(),null);
            ListRewrite modifiersRewrite=sourceRewriter.getListRewrite(newMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
            List<IExtendedModifier> originalModifiers=methodDeclaration1.modifiers();
            for (            IExtendedModifier extendedModifier : originalModifiers) {
              if (extendedModifier.isModifier()) {
                Modifier modifier=(Modifier)extendedModifier;
                if (modifier.isProtected()) {
                  modifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD),null);
                }
 else                 if (modifier.isPublic()) {
                  modifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
                }
              }
            }
            modifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD),null);
            ListRewrite parametersRewrite=sourceRewriter.getListRewrite(newMethodDeclaration,MethodDeclaration.PARAMETERS_PROPERTY);
            List<SingleVariableDeclaration> parameters=methodDeclaration1.parameters();
            for (            SingleVariableDeclaration parameter : parameters) {
              parametersRewrite.insertLast(parameter,null);
            }
            ListRewrite thrownExceptionsRewrite=sourceRewriter.getListRewrite(newMethodDeclaration,MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY);
            List<Name> thrownExceptions=methodDeclaration1.thrownExceptions();
            for (            Name thrownException : thrownExceptions) {
              thrownExceptionsRewrite.insertLast(thrownException,null);
            }
            bodyDeclarationsRewrite.insertLast(newMethodDeclaration,null);
          }
          break;
        }
      }
    }
  }
  MethodDeclaration newMethodDeclaration=ast.newMethodDeclaration();
  sourceRewriter.set(newMethodDeclaration,MethodDeclaration.NAME_PROPERTY,ast.newSimpleName(extractedMethodName),null);
  List<VariableDeclaration> returnedVariables1=this.returnedVariables.get(0);
  List<VariableDeclaration> returnedVariables2=this.returnedVariables.get(1);
  ITypeBinding returnTypeBinding=null;
  if (returnedVariables1.size() == 1 && returnedVariables2.size() == 1) {
    Type returnType1=extractType(returnedVariables1.get(0));
    Type returnType2=extractType(returnedVariables2.get(0));
    if (returnType1.resolveBinding().isEqualTo(returnType2.resolveBinding()))     returnTypeBinding=returnType1.resolveBinding();
 else     returnTypeBinding=ASTNodeMatcher.commonSuperType(returnType1.resolveBinding(),returnType2.resolveBinding());
  }
 else {
    returnTypeBinding=findReturnTypeBinding();
  }
  if (returnTypeBinding != null) {
    Set<ITypeBinding> typeBindings=new LinkedHashSet<ITypeBinding>();
    typeBindings.add(returnTypeBinding);
    getSimpleTypeBindings(typeBindings,requiredImportTypeBindings);
    Type returnType=generateTypeFromTypeBinding(returnTypeBinding,ast,sourceRewriter);
    sourceRewriter.set(newMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,returnType,null);
  }
 else {
    sourceRewriter.set(newMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,ast.newPrimitiveType(PrimitiveType.VOID),null);
  }
  ListRewrite modifierRewrite=sourceRewriter.getListRewrite(newMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
  if (sourceTypeDeclarations.get(0).resolveBinding().isEqualTo(sourceTypeDeclaration.resolveBinding()) && sourceTypeDeclarations.get(1).resolveBinding().isEqualTo(sourceTypeDeclaration.resolveBinding())) {
    Modifier accessModifier=newMethodDeclaration.getAST().newModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
    modifierRewrite.insertLast(accessModifier,null);
  }
 else {
    Modifier accessModifier=newMethodDeclaration.getAST().newModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
    modifierRewrite.insertLast(accessModifier,null);
  }
  if ((sourceMethodDeclarations.get(0).getModifiers() & Modifier.STATIC) != 0 && (sourceMethodDeclarations.get(1).getModifiers() & Modifier.STATIC) != 0) {
    Modifier staticModifier=newMethodDeclaration.getAST().newModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
    modifierRewrite.insertLast(staticModifier,null);
  }
  ListRewrite thrownExceptionRewrite=sourceRewriter.getListRewrite(newMethodDeclaration,MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY);
  List<Name> thrownExceptions1=sourceMethodDeclarations.get(0).thrownExceptions();
  List<Name> thrownExceptions2=sourceMethodDeclarations.get(1).thrownExceptions();
  for (  Name thrownException1 : thrownExceptions1) {
    for (    Name thrownException2 : thrownExceptions2) {
      if (thrownException1.resolveTypeBinding().isEqualTo(thrownException2.resolveTypeBinding())) {
        thrownExceptionRewrite.insertLast(thrownException1,null);
        break;
      }
    }
  }
  ListRewrite parameterRewrite=sourceRewriter.getListRewrite(newMethodDeclaration,MethodDeclaration.PARAMETERS_PROPERTY);
  Map<VariableBindingKeyPair,ArrayList<VariableDeclaration>> commonPassedParameters=mapper.getCommonPassedParameters();
  for (  VariableBindingKeyPair parameterName : commonPassedParameters.keySet()) {
    ArrayList<VariableDeclaration> variableDeclarations=commonPassedParameters.get(parameterName);
    VariableDeclaration variableDeclaration1=variableDeclarations.get(0);
    VariableDeclaration variableDeclaration2=variableDeclarations.get(1);
    if (parameterIsUsedByNodesWithoutDifferences(variableDeclaration1,variableDeclaration2)) {
      if (!variableDeclaration1.resolveBinding().isField() && !variableDeclaration2.resolveBinding().isField()) {
        ITypeBinding typeBinding1=extractType(variableDeclaration1).resolveBinding();
        ITypeBinding typeBinding2=extractType(variableDeclaration2).resolveBinding();
        ITypeBinding typeBinding=null;
        if (!typeBinding1.isEqualTo(typeBinding2)) {
          ITypeBinding commonSuperTypeBinding=ASTNodeMatcher.commonSuperType(typeBinding1,typeBinding2);
          if (commonSuperTypeBinding != null) {
            typeBinding=commonSuperTypeBinding;
          }
        }
 else {
          typeBinding=typeBinding1;
        }
        Type variableType=generateTypeFromTypeBinding(typeBinding,ast,sourceRewriter);
        Set<ITypeBinding> typeBindings=new LinkedHashSet<ITypeBinding>();
        typeBindings.add(typeBinding);
        getSimpleTypeBindings(typeBindings,requiredImportTypeBindings);
        SingleVariableDeclaration parameter=ast.newSingleVariableDeclaration();
        sourceRewriter.set(parameter,SingleVariableDeclaration.NAME_PROPERTY,variableDeclaration1.getName(),null);
        sourceRewriter.set(parameter,SingleVariableDeclaration.TYPE_PROPERTY,variableType,null);
        parameterRewrite.insertLast(parameter,null);
        originalPassedParameters.put(parameterName,variableDeclarations);
      }
    }
  }
  Block newMethodBody=newMethodDeclaration.getAST().newBlock();
  ListRewrite methodBodyRewrite=sourceRewriter.getListRewrite(newMethodBody,Block.STATEMENTS_PROPERTY);
  for (  PDGNodeMapping pdgNodeMapping : sortedNodeMappings) {
    PDGNode pdgNode1=pdgNodeMapping.getNodeG1();
    Statement statement1=pdgNode1.getASTStatement();
    TypeVisitor typeVisitor1=new TypeVisitor();
    statement1.accept(typeVisitor1);
    getSimpleTypeBindings(typeVisitor1.getTypeBindings(),requiredImportTypeBindings);
    PDGNode pdgNode2=pdgNodeMapping.getNodeG2();
    Statement statement2=pdgNode2.getASTStatement();
    TypeVisitor typeVisitor2=new TypeVisitor();
    statement2.accept(typeVisitor2);
    getSimpleTypeBindings(typeVisitor2.getTypeBindings(),requiredImportTypeBindings);
  }
  CloneStructureNode root=mapper.getCloneStructureRoot();
  for (  CloneStructureNode child : root.getChildren()) {
    if (child.getMapping() instanceof PDGNodeMapping) {
      Statement statement=processCloneStructureNode(child,ast,sourceRewriter);
      methodBodyRewrite.insertLast(statement,null);
    }
  }
  if (returnedVariables1.size() == 1 && returnedVariables2.size() == 1 && findReturnTypeBinding() == null) {
    ReturnStatement returnStatement=ast.newReturnStatement();
    sourceRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,returnedVariables1.get(0).getName(),null);
    methodBodyRewrite.insertLast(returnStatement,null);
  }
  int i=0;
  for (  ASTNodeDifference difference : parameterizedDifferenceMap.values()) {
    AbstractExpression expression1=difference.getExpression1();
    AbstractExpression expression2=difference.getExpression2();
    boolean isReturnedVariable=false;
    if (expression1 != null) {
      isReturnedVariable=isReturnedVariable(expression1.getExpression(),this.returnedVariables.get(0));
    }
 else     if (expression2 != null) {
      isReturnedVariable=isReturnedVariable(expression2.getExpression(),this.returnedVariables.get(1));
    }
    if (!isReturnedVariable) {
      ITypeBinding typeBinding=null;
      if (difference.containsDifferenceType(DifferenceType.SUBCLASS_TYPE_MISMATCH) || differenceContainsSubDifferenceWithSubclassTypeMismatch(difference)) {
        ITypeBinding typeBinding1=expression1 != null ? expression1.getExpression().resolveTypeBinding() : expression2.getExpression().resolveTypeBinding();
        ITypeBinding typeBinding2=expression2 != null ? expression2.getExpression().resolveTypeBinding() : expression1.getExpression().resolveTypeBinding();
        if (!typeBinding1.isEqualTo(typeBinding2)) {
          ITypeBinding commonSuperTypeBinding=ASTNodeMatcher.commonSuperType(typeBinding1,typeBinding2);
          if (commonSuperTypeBinding != null) {
            typeBinding=commonSuperTypeBinding;
          }
        }
 else {
          typeBinding=typeBinding1;
        }
      }
 else {
        typeBinding=expression1 != null ? expression1.getExpression().resolveTypeBinding() : expression2.getExpression().resolveTypeBinding();
      }
      Type type=generateTypeFromTypeBinding(typeBinding,ast,sourceRewriter);
      Set<ITypeBinding> typeBindings=new LinkedHashSet<ITypeBinding>();
      typeBindings.add(typeBinding);
      getSimpleTypeBindings(typeBindings,requiredImportTypeBindings);
      SingleVariableDeclaration parameter=ast.newSingleVariableDeclaration();
      sourceRewriter.set(parameter,SingleVariableDeclaration.NAME_PROPERTY,ast.newSimpleName("String_Node_Str" + i),null);
      i++;
      sourceRewriter.set(parameter,SingleVariableDeclaration.TYPE_PROPERTY,type,null);
      parameterRewrite.insertLast(parameter,null);
    }
  }
  sourceRewriter.set(newMethodDeclaration,MethodDeclaration.BODY_PROPERTY,newMethodBody,null);
  bodyDeclarationsRewrite.insertLast(newMethodDeclaration,null);
  try {
    CompilationUnitChange change=compilationUnitChanges.get(sourceICompilationUnit);
    if (change != null) {
      ImportRewrite importRewrite=ImportRewrite.create(sourceCompilationUnit,true);
      for (      ITypeBinding typeBinding : requiredImportTypeBindings) {
        if (!typeBinding.isNested())         importRewrite.addImport(typeBinding);
      }
      TextEdit importEdit=importRewrite.rewriteImports(null);
      if (importRewrite.getCreatedImports().length > 0) {
        change.getEdit().addChild(importEdit);
        change.addTextEditGroup(new TextEditGroup("String_Node_Str",new TextEdit[]{importEdit}));
      }
      TextEdit sourceEdit=sourceRewriter.rewriteAST();
      change.getEdit().addChild(sourceEdit);
      change.addTextEditGroup(new TextEditGroup("String_Node_Str",new TextEdit[]{sourceEdit}));
    }
    if (document != null) {
      for (      ITypeBinding typeBinding : requiredImportTypeBindings) {
        addImportDeclaration(typeBinding,sourceCompilationUnit,sourceRewriter);
      }
      TextEdit intermediateEdit=sourceRewriter.rewriteAST(document,null);
      intermediateEdit.apply(document);
      CreateCompilationUnitChange createCompilationUnitChange=new CreateCompilationUnitChange(sourceICompilationUnit,document.get(),file.getCharset());
      createCompilationUnitChanges.put(sourceICompilationUnit,createCompilationUnitChange);
    }
  }
 catch (  JavaModelException e) {
    e.printStackTrace();
  }
catch (  MalformedTreeException e) {
    e.printStackTrace();
  }
catch (  BadLocationException e) {
    e.printStackTrace();
  }
catch (  CoreException e) {
    e.printStackTrace();
  }
}