Program: 12067
Project: 12067
Buggy source:
private void extractClone(){
  this.cloneInfo=new CloneInformation();
  ITypeBinding commonSuperTypeOfSourceTypeDeclarations=null;
  if (sourceTypeDeclarations.get(0).resolveBinding().isEqualTo(sourceTypeDeclarations.get(1).resolveBinding())) {
    cloneInfo.sourceCompilationUnit=sourceCompilationUnits.get(0);
    cloneInfo.sourceICompilationUnit=(ICompilationUnit)cloneInfo.sourceCompilationUnit.getJavaElement();
    cloneInfo.sourceTypeDeclaration=sourceTypeDeclarations.get(0);
    cloneInfo.sourceRewriter=ASTRewrite.create(cloneInfo.sourceTypeDeclaration.getAST());
    cloneInfo.ast=cloneInfo.sourceTypeDeclaration.getAST();
  }
 else {
    ITypeBinding typeBinding1=sourceTypeDeclarations.get(0).resolveBinding();
    ITypeBinding typeBinding2=sourceTypeDeclarations.get(1).resolveBinding();
    commonSuperTypeOfSourceTypeDeclarations=ASTNodeMatcher.commonSuperType(typeBinding1,typeBinding2);
    if (commonSuperTypeOfSourceTypeDeclarations != null) {
      if (pullUpToCommonSuperclass(commonSuperTypeOfSourceTypeDeclarations,typeBinding1,typeBinding2)) {
        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)) {
              cloneInfo.sourceCompilationUnit=compilationUnit;
              cloneInfo.sourceICompilationUnit=iCompilationUnit;
              cloneInfo.sourceTypeDeclaration=typeDeclaration;
              cloneInfo.sourceRewriter=ASTRewrite.create(cloneInfo.sourceTypeDeclaration.getAST());
              cloneInfo.ast=cloneInfo.sourceTypeDeclaration.getAST();
              cloneInfo.superclassNotDirectlyInheritedFromRefactoredSubclasses=!superclassDirectlyInheritedFromRefactoredSubclasses(commonSuperTypeOfSourceTypeDeclarations,typeBinding1,typeBinding2);
              break;
            }
          }
        }
        MultiTextEdit multiTextEdit=new MultiTextEdit();
        CompilationUnitChange compilationUnitChange=new CompilationUnitChange("String_Node_Str",iCompilationUnit);
        compilationUnitChange.setEdit(multiTextEdit);
        compilationUnitChanges.put(iCompilationUnit,compilationUnitChange);
      }
 else {
        if (extractToUtilityClass(commonSuperTypeOfSourceTypeDeclarations)) {
          cloneInfo.extractUtilityClass=true;
        }
        if (cloneInfo.extractUtilityClass) {
          cloneInfo.intermediateClassName="String_Node_Str";
        }
 else {
          cloneInfo.intermediateClassName="String_Node_Str" + commonSuperTypeOfSourceTypeDeclarations.getName();
        }
        ClassObject commonSuperType=ASTReader.getSystemObject().getClassObject(commonSuperTypeOfSourceTypeDeclarations.getQualifiedName());
        CompilationUnit compilationUnit=null;
        if (commonSuperType != null) {
          compilationUnit=findCompilationUnit(commonSuperType.getAbstractTypeDeclaration());
        }
 else {
          compilationUnit=sourceCompilationUnits.get(0);
        }
        cloneInfo.intermediateClassPackageBinding=compilationUnit.getPackage().resolveBinding();
        ICompilationUnit iCompilationUnit=(ICompilationUnit)compilationUnit.getJavaElement();
        IContainer container=(IContainer)iCompilationUnit.getResource().getParent();
        if (container instanceof IProject) {
          IProject contextProject=(IProject)container;
          cloneInfo.file=contextProject.getFile(cloneInfo.intermediateClassName + "String_Node_Str");
        }
 else         if (container instanceof IFolder) {
          IFolder contextFolder=(IFolder)container;
          cloneInfo.file=contextFolder.getFile(cloneInfo.intermediateClassName + "String_Node_Str");
        }
        boolean intermediateAlreadyExists=false;
        ICompilationUnit intermediateICompilationUnit=JavaCore.createCompilationUnitFrom(cloneInfo.file);
        javaElementsToOpenInEditor.add(intermediateICompilationUnit);
        ASTParser intermediateParser=ASTParser.newParser(AST.JLS4);
        intermediateParser.setKind(ASTParser.K_COMPILATION_UNIT);
        if (cloneInfo.file.exists()) {
          intermediateAlreadyExists=true;
          intermediateParser.setSource(intermediateICompilationUnit);
          intermediateParser.setResolveBindings(true);
        }
 else {
          cloneInfo.document=new Document();
          intermediateParser.setSource(cloneInfo.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(cloneInfo.intermediateClassName)) {
                intermediateTypeDeclaration=typeDeclaration;
                int intermediateModifiers=intermediateTypeDeclaration.getModifiers();
                if ((intermediateModifiers & Modifier.ABSTRACT) == 0 && !cloneInfo.extractUtilityClass) {
                  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(cloneInfo.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);
          if (!cloneInfo.extractUtilityClass) {
            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);
        }
        cloneInfo.sourceCompilationUnit=intermediateCompilationUnit;
        cloneInfo.sourceICompilationUnit=intermediateICompilationUnit;
        cloneInfo.sourceTypeDeclaration=intermediateTypeDeclaration;
        cloneInfo.sourceRewriter=intermediateRewriter;
        cloneInfo.ast=intermediateAST;
      }
    }
  }
  ASTRewrite sourceRewriter=cloneInfo.sourceRewriter;
  AST ast=cloneInfo.ast;
  TypeDeclaration sourceTypeDeclaration=cloneInfo.sourceTypeDeclaration;
  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=getLocallyAccessedFields(mapper.getDirectlyAccessedLocalFieldsG1(),sourceTypeDeclarations.get(0));
    Set<VariableDeclaration> accessedLocalFieldsG2=getLocallyAccessedFields(mapper.getDirectlyAccessedLocalFieldsG2(),sourceTypeDeclarations.get(1));
    pullUpLocallyAccessedFields(accessedLocalFieldsG1,accessedLocalFieldsG2,bodyDeclarationsRewrite,requiredImportTypeBindings);
    Set<VariableDeclaration> indirectlyAccessedLocalFieldsG1=getLocallyAccessedFields(mapper.getIndirectlyAccessedLocalFieldsG1(),sourceTypeDeclarations.get(0));
    Set<VariableDeclaration> indirectlyAccessedLocalFieldsG2=getLocallyAccessedFields(mapper.getIndirectlyAccessedLocalFieldsG2(),sourceTypeDeclarations.get(1));
    Set<MethodObject> accessedLocalMethodsG1=mapper.getAccessedLocalMethodsG1();
    Set<MethodObject> accessedLocalMethodsG2=mapper.getAccessedLocalMethodsG2();
    for (    MethodObject localMethodG1 : accessedLocalMethodsG1) {
      for (      MethodObject localMethodG2 : accessedLocalMethodsG2) {
        if (localMethodG1.getName().equals(localMethodG2.getName()) && localMethodG1.getReturnType().equals(localMethodG2.getReturnType()) && localMethodG1.getParameterTypeList().equals(localMethodG2.getParameterTypeList())) {
          MethodDeclaration methodDeclaration1=localMethodG1.getMethodDeclaration();
          MethodDeclaration methodDeclaration2=localMethodG2.getMethodDeclaration();
          Set<ITypeBinding> typeBindings=new LinkedHashSet<ITypeBinding>();
          boolean clones=type2Clones(methodDeclaration1,methodDeclaration2);
          Type returnType=methodDeclaration1.getReturnType2();
          TypeDeclaration typeDeclaration1=findTypeDeclaration(methodDeclaration1);
          TypeDeclaration typeDeclaration2=findTypeDeclaration(methodDeclaration2);
          if (clones) {
            if (!typeDeclaration1.resolveBinding().isEqualTo(sourceTypeDeclaration.resolveBinding()) && !typeDeclaration2.resolveBinding().isEqualTo(sourceTypeDeclaration.resolveBinding())) {
              bodyDeclarationsRewrite.insertLast(methodDeclaration1,null);
              typeBindings.add(returnType.resolveBinding());
              List<SingleVariableDeclaration> parameters=methodDeclaration1.parameters();
              for (              SingleVariableDeclaration parameter : parameters) {
                typeBindings.add(parameter.getType().resolveBinding());
              }
              List<Name> thrownExceptions=methodDeclaration1.thrownExceptions();
              for (              Name thrownException : thrownExceptions) {
                typeBindings.add(thrownException.resolveTypeBinding());
              }
              Set<VariableDeclaration> fieldsAccessedInMethod1=getFieldsAccessedInMethod(indirectlyAccessedLocalFieldsG1,methodDeclaration1);
              fieldsAccessedInMethod1.removeAll(accessedLocalFieldsG1);
              Set<VariableDeclaration> fieldsAccessedInMethod2=getFieldsAccessedInMethod(indirectlyAccessedLocalFieldsG2,methodDeclaration2);
              fieldsAccessedInMethod2.removeAll(accessedLocalFieldsG2);
              pullUpLocallyAccessedFields(fieldsAccessedInMethod1,fieldsAccessedInMethod2,bodyDeclarationsRewrite,requiredImportTypeBindings);
            }
            if (!typeDeclaration1.resolveBinding().isEqualTo(sourceTypeDeclaration.resolveBinding())) {
              methodDeclarationsToBePulledUp.get(0).add(methodDeclaration1);
            }
            if (!typeDeclaration2.resolveBinding().isEqualTo(sourceTypeDeclaration.resolveBinding())) {
              methodDeclarationsToBePulledUp.get(1).add(methodDeclaration2);
            }
          }
 else {
            if (!typeDeclaration1.resolveBinding().isEqualTo(sourceTypeDeclaration.resolveBinding()) && !typeDeclaration2.resolveBinding().isEqualTo(sourceTypeDeclaration.resolveBinding())) {
              MethodDeclaration newMethodDeclaration=ast.newMethodDeclaration();
              sourceRewriter.set(newMethodDeclaration,MethodDeclaration.NAME_PROPERTY,ast.newSimpleName(methodDeclaration1.getName().getIdentifier()),null);
              sourceRewriter.set(newMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,returnType,null);
              typeBindings.add(returnType.resolveBinding());
              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);
                    updateAccessModifier(methodDeclaration2,Modifier.ModifierKeyword.PROTECTED_KEYWORD);
                  }
 else                   if (modifier.isPublic()) {
                    modifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
                    updateAccessModifier(methodDeclaration2,Modifier.ModifierKeyword.PUBLIC_KEYWORD);
                  }
                }
              }
              if (cloneInfo.superclassNotDirectlyInheritedFromRefactoredSubclasses) {
                Block methodBody=ast.newBlock();
                sourceRewriter.set(newMethodDeclaration,MethodDeclaration.BODY_PROPERTY,methodBody,null);
                Expression returnedExpression=generateDefaultValue(sourceRewriter,ast,returnType);
                if (returnedExpression != null) {
                  ReturnStatement returnStatement=ast.newReturnStatement();
                  sourceRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,returnedExpression,null);
                  ListRewrite statementsRewrite=sourceRewriter.getListRewrite(methodBody,Block.STATEMENTS_PROPERTY);
                  statementsRewrite.insertLast(returnStatement,null);
                }
              }
 else {
                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);
                typeBindings.add(parameter.getType().resolveBinding());
              }
              ListRewrite thrownExceptionsRewrite=sourceRewriter.getListRewrite(newMethodDeclaration,MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY);
              List<Name> thrownExceptions=methodDeclaration1.thrownExceptions();
              for (              Name thrownException : thrownExceptions) {
                thrownExceptionsRewrite.insertLast(thrownException,null);
                typeBindings.add(thrownException.resolveTypeBinding());
              }
              bodyDeclarationsRewrite.insertLast(newMethodDeclaration,null);
            }
          }
          getSimpleTypeBindings(typeBindings,requiredImportTypeBindings);
          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   if (cloneInfo.extractUtilityClass) {
    Modifier accessModifier=newMethodDeclaration.getAST().newModifier(Modifier.ModifierKeyword.PUBLIC_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) || cloneInfo.extractUtilityClass) {
    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 && !mappedNodesContainStatementReturningVariable(returnedVariables1.get(0),returnedVariables2.get(0))) {
    ReturnStatement returnStatement=ast.newReturnStatement();
    sourceRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,returnedVariables1.get(0).getName(),null);
    methodBodyRewrite.insertLast(returnStatement,null);
    if (!mappedNodesContainStatementDeclaringVariable(returnedVariables1.get(0),returnedVariables2.get(0)) && !variableIsPassedAsCommonParameter(returnedVariables1.get(0),returnedVariables2.get(0))) {
      Type returnedType=extractType(returnedVariables1.get(0));
      Expression initializer=generateDefaultValue(sourceRewriter,ast,returnedType);
      VariableDeclarationFragment fragment=ast.newVariableDeclarationFragment();
      sourceRewriter.set(fragment,VariableDeclarationFragment.NAME_PROPERTY,returnedVariables1.get(0).getName(),null);
      sourceRewriter.set(fragment,VariableDeclarationFragment.INITIALIZER_PROPERTY,initializer,null);
      VariableDeclarationStatement declarationStatement=ast.newVariableDeclarationStatement(fragment);
      sourceRewriter.set(declarationStatement,VariableDeclarationStatement.TYPE_PROPERTY,returnedType,null);
      methodBodyRewrite.insertFirst(declarationStatement,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);
  cloneInfo.requiredImportTypeBindings=requiredImportTypeBindings;
  cloneInfo.methodBodyRewrite=methodBodyRewrite;
  cloneInfo.parameterRewrite=parameterRewrite;
}

Fixed version (ground truth):
private void extractClone(){
  this.cloneInfo=new CloneInformation();
  ITypeBinding commonSuperTypeOfSourceTypeDeclarations=null;
  if (sourceTypeDeclarations.get(0).resolveBinding().isEqualTo(sourceTypeDeclarations.get(1).resolveBinding())) {
    cloneInfo.sourceCompilationUnit=sourceCompilationUnits.get(0);
    cloneInfo.sourceICompilationUnit=(ICompilationUnit)cloneInfo.sourceCompilationUnit.getJavaElement();
    cloneInfo.sourceTypeDeclaration=sourceTypeDeclarations.get(0);
    cloneInfo.sourceRewriter=ASTRewrite.create(cloneInfo.sourceTypeDeclaration.getAST());
    cloneInfo.ast=cloneInfo.sourceTypeDeclaration.getAST();
  }
 else {
    ITypeBinding typeBinding1=sourceTypeDeclarations.get(0).resolveBinding();
    ITypeBinding typeBinding2=sourceTypeDeclarations.get(1).resolveBinding();
    commonSuperTypeOfSourceTypeDeclarations=ASTNodeMatcher.commonSuperType(typeBinding1,typeBinding2);
    if (commonSuperTypeOfSourceTypeDeclarations != null) {
      if (pullUpToCommonSuperclass(commonSuperTypeOfSourceTypeDeclarations,typeBinding1,typeBinding2)) {
        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)) {
              cloneInfo.sourceCompilationUnit=compilationUnit;
              cloneInfo.sourceICompilationUnit=iCompilationUnit;
              cloneInfo.sourceTypeDeclaration=typeDeclaration;
              cloneInfo.sourceRewriter=ASTRewrite.create(cloneInfo.sourceTypeDeclaration.getAST());
              cloneInfo.ast=cloneInfo.sourceTypeDeclaration.getAST();
              cloneInfo.superclassNotDirectlyInheritedFromRefactoredSubclasses=!superclassDirectlyInheritedFromRefactoredSubclasses(commonSuperTypeOfSourceTypeDeclarations,typeBinding1,typeBinding2);
              break;
            }
          }
        }
        MultiTextEdit multiTextEdit=new MultiTextEdit();
        CompilationUnitChange compilationUnitChange=new CompilationUnitChange("String_Node_Str",iCompilationUnit);
        compilationUnitChange.setEdit(multiTextEdit);
        compilationUnitChanges.put(iCompilationUnit,compilationUnitChange);
      }
 else {
        if (extractToUtilityClass(commonSuperTypeOfSourceTypeDeclarations)) {
          cloneInfo.extractUtilityClass=true;
        }
        if (cloneInfo.extractUtilityClass) {
          cloneInfo.intermediateClassName="String_Node_Str";
        }
 else {
          cloneInfo.intermediateClassName="String_Node_Str" + commonSuperTypeOfSourceTypeDeclarations.getName();
        }
        ClassObject commonSuperType=ASTReader.getSystemObject().getClassObject(commonSuperTypeOfSourceTypeDeclarations.getQualifiedName());
        CompilationUnit compilationUnit=null;
        if (commonSuperType != null) {
          compilationUnit=findCompilationUnit(commonSuperType.getAbstractTypeDeclaration());
        }
 else {
          compilationUnit=sourceCompilationUnits.get(0);
        }
        cloneInfo.intermediateClassPackageBinding=compilationUnit.getPackage().resolveBinding();
        ICompilationUnit iCompilationUnit=(ICompilationUnit)compilationUnit.getJavaElement();
        IContainer container=(IContainer)iCompilationUnit.getResource().getParent();
        if (container instanceof IProject) {
          IProject contextProject=(IProject)container;
          cloneInfo.file=contextProject.getFile(cloneInfo.intermediateClassName + "String_Node_Str");
        }
 else         if (container instanceof IFolder) {
          IFolder contextFolder=(IFolder)container;
          cloneInfo.file=contextFolder.getFile(cloneInfo.intermediateClassName + "String_Node_Str");
        }
        boolean intermediateAlreadyExists=false;
        ICompilationUnit intermediateICompilationUnit=JavaCore.createCompilationUnitFrom(cloneInfo.file);
        javaElementsToOpenInEditor.add(intermediateICompilationUnit);
        ASTParser intermediateParser=ASTParser.newParser(AST.JLS4);
        intermediateParser.setKind(ASTParser.K_COMPILATION_UNIT);
        if (cloneInfo.file.exists()) {
          intermediateAlreadyExists=true;
          intermediateParser.setSource(intermediateICompilationUnit);
          intermediateParser.setResolveBindings(true);
        }
 else {
          cloneInfo.document=new Document();
          intermediateParser.setSource(cloneInfo.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(cloneInfo.intermediateClassName)) {
                intermediateTypeDeclaration=typeDeclaration;
                int intermediateModifiers=intermediateTypeDeclaration.getModifiers();
                if ((intermediateModifiers & Modifier.ABSTRACT) == 0 && !cloneInfo.extractUtilityClass) {
                  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(cloneInfo.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);
          if (!cloneInfo.extractUtilityClass) {
            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);
        }
        cloneInfo.sourceCompilationUnit=intermediateCompilationUnit;
        cloneInfo.sourceICompilationUnit=intermediateICompilationUnit;
        cloneInfo.sourceTypeDeclaration=intermediateTypeDeclaration;
        cloneInfo.sourceRewriter=intermediateRewriter;
        cloneInfo.ast=intermediateAST;
      }
    }
  }
  ASTRewrite sourceRewriter=cloneInfo.sourceRewriter;
  AST ast=cloneInfo.ast;
  TypeDeclaration sourceTypeDeclaration=cloneInfo.sourceTypeDeclaration;
  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=getLocallyAccessedFields(mapper.getDirectlyAccessedLocalFieldsG1(),sourceTypeDeclarations.get(0));
    Set<VariableDeclaration> accessedLocalFieldsG2=getLocallyAccessedFields(mapper.getDirectlyAccessedLocalFieldsG2(),sourceTypeDeclarations.get(1));
    pullUpLocallyAccessedFields(accessedLocalFieldsG1,accessedLocalFieldsG2,bodyDeclarationsRewrite,requiredImportTypeBindings);
    Set<VariableDeclaration> indirectlyAccessedLocalFieldsG1=getLocallyAccessedFields(mapper.getIndirectlyAccessedLocalFieldsG1(),sourceTypeDeclarations.get(0));
    Set<VariableDeclaration> indirectlyAccessedLocalFieldsG2=getLocallyAccessedFields(mapper.getIndirectlyAccessedLocalFieldsG2(),sourceTypeDeclarations.get(1));
    Set<MethodObject> accessedLocalMethodsG1=mapper.getAccessedLocalMethodsG1();
    Set<MethodObject> accessedLocalMethodsG2=mapper.getAccessedLocalMethodsG2();
    for (    MethodObject localMethodG1 : accessedLocalMethodsG1) {
      for (      MethodObject localMethodG2 : accessedLocalMethodsG2) {
        if (localMethodG1.getName().equals(localMethodG2.getName()) && localMethodG1.getReturnType().equals(localMethodG2.getReturnType()) && localMethodG1.getParameterTypeList().equals(localMethodG2.getParameterTypeList())) {
          MethodDeclaration methodDeclaration1=localMethodG1.getMethodDeclaration();
          MethodDeclaration methodDeclaration2=localMethodG2.getMethodDeclaration();
          Set<ITypeBinding> typeBindings=new LinkedHashSet<ITypeBinding>();
          boolean clones=type2Clones(methodDeclaration1,methodDeclaration2);
          Type returnType=methodDeclaration1.getReturnType2();
          TypeDeclaration typeDeclaration1=findTypeDeclaration(methodDeclaration1);
          TypeDeclaration typeDeclaration2=findTypeDeclaration(methodDeclaration2);
          if (clones) {
            if (!typeDeclaration1.resolveBinding().isEqualTo(sourceTypeDeclaration.resolveBinding()) && !typeDeclaration2.resolveBinding().isEqualTo(sourceTypeDeclaration.resolveBinding())) {
              bodyDeclarationsRewrite.insertLast(methodDeclaration1,null);
              TypeVisitor typeVisitor=new TypeVisitor();
              methodDeclaration1.accept(typeVisitor);
              typeBindings.addAll(typeVisitor.getTypeBindings());
              Set<VariableDeclaration> fieldsAccessedInMethod1=getFieldsAccessedInMethod(indirectlyAccessedLocalFieldsG1,methodDeclaration1);
              fieldsAccessedInMethod1.removeAll(accessedLocalFieldsG1);
              Set<VariableDeclaration> fieldsAccessedInMethod2=getFieldsAccessedInMethod(indirectlyAccessedLocalFieldsG2,methodDeclaration2);
              fieldsAccessedInMethod2.removeAll(accessedLocalFieldsG2);
              pullUpLocallyAccessedFields(fieldsAccessedInMethod1,fieldsAccessedInMethod2,bodyDeclarationsRewrite,requiredImportTypeBindings);
            }
            if (!typeDeclaration1.resolveBinding().isEqualTo(sourceTypeDeclaration.resolveBinding())) {
              methodDeclarationsToBePulledUp.get(0).add(methodDeclaration1);
            }
            if (!typeDeclaration2.resolveBinding().isEqualTo(sourceTypeDeclaration.resolveBinding())) {
              methodDeclarationsToBePulledUp.get(1).add(methodDeclaration2);
            }
          }
 else {
            if (!typeDeclaration1.resolveBinding().isEqualTo(sourceTypeDeclaration.resolveBinding()) && !typeDeclaration2.resolveBinding().isEqualTo(sourceTypeDeclaration.resolveBinding())) {
              MethodDeclaration newMethodDeclaration=ast.newMethodDeclaration();
              sourceRewriter.set(newMethodDeclaration,MethodDeclaration.NAME_PROPERTY,ast.newSimpleName(methodDeclaration1.getName().getIdentifier()),null);
              sourceRewriter.set(newMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,returnType,null);
              typeBindings.add(returnType.resolveBinding());
              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);
                    if ((methodDeclaration2.getModifiers() & Modifier.PROTECTED) == 0) {
                      updateAccessModifier(methodDeclaration2,Modifier.ModifierKeyword.PROTECTED_KEYWORD);
                    }
                  }
 else                   if (modifier.isPublic()) {
                    modifiersRewrite.insertLast(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
                    if ((methodDeclaration2.getModifiers() & Modifier.PUBLIC) == 0) {
                      updateAccessModifier(methodDeclaration2,Modifier.ModifierKeyword.PUBLIC_KEYWORD);
                    }
                  }
                }
              }
              if (cloneInfo.superclassNotDirectlyInheritedFromRefactoredSubclasses) {
                Block methodBody=ast.newBlock();
                sourceRewriter.set(newMethodDeclaration,MethodDeclaration.BODY_PROPERTY,methodBody,null);
                Expression returnedExpression=generateDefaultValue(sourceRewriter,ast,returnType);
                if (returnedExpression != null) {
                  ReturnStatement returnStatement=ast.newReturnStatement();
                  sourceRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,returnedExpression,null);
                  ListRewrite statementsRewrite=sourceRewriter.getListRewrite(methodBody,Block.STATEMENTS_PROPERTY);
                  statementsRewrite.insertLast(returnStatement,null);
                }
              }
 else {
                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);
                typeBindings.add(parameter.getType().resolveBinding());
              }
              ListRewrite thrownExceptionsRewrite=sourceRewriter.getListRewrite(newMethodDeclaration,MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY);
              List<Name> thrownExceptions=methodDeclaration1.thrownExceptions();
              for (              Name thrownException : thrownExceptions) {
                thrownExceptionsRewrite.insertLast(thrownException,null);
                typeBindings.add(thrownException.resolveTypeBinding());
              }
              bodyDeclarationsRewrite.insertLast(newMethodDeclaration,null);
            }
          }
          getSimpleTypeBindings(typeBindings,requiredImportTypeBindings);
          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   if (cloneInfo.extractUtilityClass) {
    Modifier accessModifier=newMethodDeclaration.getAST().newModifier(Modifier.ModifierKeyword.PUBLIC_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) || cloneInfo.extractUtilityClass) {
    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 && !mappedNodesContainStatementReturningVariable(returnedVariables1.get(0),returnedVariables2.get(0))) {
    ReturnStatement returnStatement=ast.newReturnStatement();
    sourceRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,returnedVariables1.get(0).getName(),null);
    methodBodyRewrite.insertLast(returnStatement,null);
    if (!mappedNodesContainStatementDeclaringVariable(returnedVariables1.get(0),returnedVariables2.get(0)) && !variableIsPassedAsCommonParameter(returnedVariables1.get(0),returnedVariables2.get(0))) {
      Type returnedType=extractType(returnedVariables1.get(0));
      Expression initializer=generateDefaultValue(sourceRewriter,ast,returnedType);
      VariableDeclarationFragment fragment=ast.newVariableDeclarationFragment();
      sourceRewriter.set(fragment,VariableDeclarationFragment.NAME_PROPERTY,returnedVariables1.get(0).getName(),null);
      sourceRewriter.set(fragment,VariableDeclarationFragment.INITIALIZER_PROPERTY,initializer,null);
      VariableDeclarationStatement declarationStatement=ast.newVariableDeclarationStatement(fragment);
      sourceRewriter.set(declarationStatement,VariableDeclarationStatement.TYPE_PROPERTY,returnedType,null);
      methodBodyRewrite.insertFirst(declarationStatement,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));
    }
    ITypeBinding typeBinding1=expression1 != null ? expression1.getExpression().resolveTypeBinding() : expression2.getExpression().resolveTypeBinding();
    ITypeBinding typeBinding2=expression2 != null ? expression2.getExpression().resolveTypeBinding() : expression1.getExpression().resolveTypeBinding();
    if (!isReturnedVariable) {
      ITypeBinding typeBinding=null;
      if (difference.containsDifferenceType(DifferenceType.SUBCLASS_TYPE_MISMATCH) || differenceContainsSubDifferenceWithSubclassTypeMismatch(difference)) {
        if (!typeBinding1.isEqualTo(typeBinding2)) {
          ITypeBinding commonSuperTypeBinding=ASTNodeMatcher.commonSuperType(typeBinding1,typeBinding2);
          if (commonSuperTypeBinding != null) {
            typeBinding=commonSuperTypeBinding;
          }
        }
 else {
          typeBinding=typeBinding1;
        }
      }
 else {
        if (expression1 != null && !typeBinding1.getQualifiedName().equals("String_Node_Str")) {
          typeBinding=typeBinding1;
        }
 else {
          typeBinding=typeBinding2;
        }
      }
      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);
  cloneInfo.requiredImportTypeBindings=requiredImportTypeBindings;
  cloneInfo.methodBodyRewrite=methodBodyRewrite;
  cloneInfo.parameterRewrite=parameterRewrite;
}