Program: 12236
Project: 12236
Buggy source:
private void createStateStrategyHierarchy(){
  IContainer contextContainer=(IContainer)sourceFile.getParent();
  IFile stateStrategyFile=null;
  if (contextContainer instanceof IProject) {
    IProject contextProject=(IProject)contextContainer;
    stateStrategyFile=contextProject.getFile(typeCheckElimination.getAbstractClassName() + "String_Node_Str");
  }
 else   if (contextContainer instanceof IFolder) {
    IFolder contextFolder=(IFolder)contextContainer;
    stateStrategyFile=contextFolder.getFile(typeCheckElimination.getAbstractClassName() + "String_Node_Str");
  }
  boolean stateStrategyAlreadyExists=false;
  try {
    stateStrategyFile.create(new ByteArrayInputStream("String_Node_Str".getBytes()),true,null);
    undoRefactoring.addNewlyCreatedFile(stateStrategyFile);
  }
 catch (  CoreException e) {
    stateStrategyAlreadyExists=true;
  }
  IJavaElement stateStrategyJavaElement=JavaCore.create(stateStrategyFile);
  ITextEditor stateStrategyEditor=null;
  try {
    stateStrategyEditor=(ITextEditor)JavaUI.openInEditor(stateStrategyJavaElement);
  }
 catch (  PartInitException e) {
    e.printStackTrace();
  }
catch (  JavaModelException e) {
    e.printStackTrace();
  }
  ICompilationUnit stateStrategyICompilationUnit=(ICompilationUnit)stateStrategyJavaElement;
  ASTParser stateStrategyParser=ASTParser.newParser(AST.JLS3);
  stateStrategyParser.setKind(ASTParser.K_COMPILATION_UNIT);
  stateStrategyParser.setSource(stateStrategyICompilationUnit);
  stateStrategyParser.setResolveBindings(true);
  CompilationUnit stateStrategyCompilationUnit=(CompilationUnit)stateStrategyParser.createAST(null);
  AST stateStrategyAST=stateStrategyCompilationUnit.getAST();
  ASTRewrite stateStrategyRewriter=ASTRewrite.create(stateStrategyAST);
  ListRewrite stateStrategyTypesRewrite=stateStrategyRewriter.getListRewrite(stateStrategyCompilationUnit,CompilationUnit.TYPES_PROPERTY);
  TypeDeclaration stateStrategyTypeDeclaration=null;
  if (stateStrategyAlreadyExists) {
    List<AbstractTypeDeclaration> abstractTypeDeclarations=stateStrategyCompilationUnit.types();
    for (    AbstractTypeDeclaration abstractTypeDeclaration : abstractTypeDeclarations) {
      if (abstractTypeDeclaration instanceof TypeDeclaration) {
        TypeDeclaration typeDeclaration=(TypeDeclaration)abstractTypeDeclaration;
        if (typeDeclaration.getName().getIdentifier().equals(typeCheckElimination.getAbstractClassName())) {
          stateStrategyTypeDeclaration=typeDeclaration;
          int stateStrategyModifiers=stateStrategyTypeDeclaration.getModifiers();
          if ((stateStrategyModifiers & Modifier.ABSTRACT) == 0) {
            ListRewrite stateStrategyModifiersRewrite=stateStrategyRewriter.getListRewrite(stateStrategyTypeDeclaration,TypeDeclaration.MODIFIERS2_PROPERTY);
            stateStrategyModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD),null);
          }
          break;
        }
      }
    }
  }
 else {
    if (sourceCompilationUnit.getPackage() != null) {
      stateStrategyRewriter.set(stateStrategyCompilationUnit,CompilationUnit.PACKAGE_PROPERTY,sourceCompilationUnit.getPackage(),null);
    }
    stateStrategyTypeDeclaration=stateStrategyAST.newTypeDeclaration();
    SimpleName stateStrategyName=stateStrategyAST.newSimpleName(typeCheckElimination.getAbstractClassName());
    stateStrategyRewriter.set(stateStrategyTypeDeclaration,TypeDeclaration.NAME_PROPERTY,stateStrategyName,null);
    ListRewrite stateStrategyModifiersRewrite=stateStrategyRewriter.getListRewrite(stateStrategyTypeDeclaration,TypeDeclaration.MODIFIERS2_PROPERTY);
    stateStrategyModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
    stateStrategyModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD),null);
  }
  ListRewrite stateStrategyBodyRewrite=stateStrategyRewriter.getListRewrite(stateStrategyTypeDeclaration,TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
  MethodDeclaration getterMethod=typeCheckElimination.getTypeFieldGetterMethod();
  if (getterMethod != null) {
    MethodDeclaration abstractGetterMethodDeclaration=stateStrategyAST.newMethodDeclaration();
    stateStrategyRewriter.set(abstractGetterMethodDeclaration,MethodDeclaration.NAME_PROPERTY,getterMethod.getName(),null);
    stateStrategyRewriter.set(abstractGetterMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,getterMethod.getReturnType2(),null);
    ListRewrite abstractGetterMethodModifiersRewrite=stateStrategyRewriter.getListRewrite(abstractGetterMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
    abstractGetterMethodModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
    abstractGetterMethodModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD),null);
    stateStrategyBodyRewrite.insertLast(abstractGetterMethodDeclaration,null);
  }
 else {
    MethodDeclaration abstractGetterMethodDeclaration=stateStrategyAST.newMethodDeclaration();
    stateStrategyRewriter.set(abstractGetterMethodDeclaration,MethodDeclaration.NAME_PROPERTY,stateStrategyAST.newSimpleName("String_Node_Str" + typeCheckElimination.getAbstractClassName()),null);
    VariableDeclarationFragment typeField=typeCheckElimination.getTypeField();
    Type returnType=((FieldDeclaration)typeField.getParent()).getType();
    stateStrategyRewriter.set(abstractGetterMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,returnType,null);
    ListRewrite abstractGetterMethodModifiersRewrite=stateStrategyRewriter.getListRewrite(abstractGetterMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
    abstractGetterMethodModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
    abstractGetterMethodModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD),null);
    stateStrategyBodyRewrite.insertLast(abstractGetterMethodDeclaration,null);
  }
  MethodDeclaration abstractMethodDeclaration=stateStrategyAST.newMethodDeclaration();
  String abstractMethodName=typeCheckElimination.getTypeCheckMethodName();
  stateStrategyRewriter.set(abstractMethodDeclaration,MethodDeclaration.NAME_PROPERTY,stateStrategyAST.newSimpleName(abstractMethodName),null);
  stateStrategyRewriter.set(abstractMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,typeCheckElimination.getTypeCheckMethodReturnType(),null);
  ListRewrite abstractMethodModifiersRewrite=stateStrategyRewriter.getListRewrite(abstractMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
  abstractMethodModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
  abstractMethodModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD),null);
  ListRewrite abstractMethodParametersRewrite=stateStrategyRewriter.getListRewrite(abstractMethodDeclaration,MethodDeclaration.PARAMETERS_PROPERTY);
  for (  SingleVariableDeclaration abstractMethodParameter : typeCheckElimination.getAccessedParameters()) {
    abstractMethodParametersRewrite.insertLast(abstractMethodParameter,null);
  }
  for (  VariableDeclarationFragment fragment : typeCheckElimination.getAccessedLocalVariables()) {
    if (!fragment.equals(returnedVariable)) {
      SingleVariableDeclaration parameter=stateStrategyAST.newSingleVariableDeclaration();
      VariableDeclarationStatement variableDeclarationStatement=(VariableDeclarationStatement)fragment.getParent();
      stateStrategyRewriter.set(parameter,SingleVariableDeclaration.TYPE_PROPERTY,variableDeclarationStatement.getType(),null);
      stateStrategyRewriter.set(parameter,SingleVariableDeclaration.NAME_PROPERTY,fragment.getName(),null);
      abstractMethodParametersRewrite.insertLast(parameter,null);
    }
  }
  if (typeCheckElimination.getAccessedFields().size() > 0 || typeCheckElimination.getAssignedFields().size() > 0 || typeCheckElimination.getAccessedMethods().size() > 0) {
    SingleVariableDeclaration parameter=stateStrategyAST.newSingleVariableDeclaration();
    SimpleName parameterType=stateStrategyAST.newSimpleName(sourceTypeDeclaration.getName().getIdentifier());
    stateStrategyRewriter.set(parameter,SingleVariableDeclaration.TYPE_PROPERTY,stateStrategyAST.newSimpleType(parameterType),null);
    String parameterName=sourceTypeDeclaration.getName().getIdentifier();
    parameterName=parameterName.substring(0,1).toLowerCase() + parameterName.substring(1,parameterName.length());
    stateStrategyRewriter.set(parameter,SingleVariableDeclaration.NAME_PROPERTY,stateStrategyAST.newSimpleName(parameterName),null);
    abstractMethodParametersRewrite.insertLast(parameter,null);
  }
  ListRewrite abstractMethodThrownExceptionsRewrite=stateStrategyRewriter.getListRewrite(abstractMethodDeclaration,MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY);
  for (  ITypeBinding typeBinding : thrownExceptions) {
    abstractMethodThrownExceptionsRewrite.insertLast(stateStrategyAST.newSimpleName(typeBinding.getName()),null);
  }
  stateStrategyBodyRewrite.insertLast(abstractMethodDeclaration,null);
  generateRequiredImportDeclarationsBasedOnSignature();
  for (  ITypeBinding typeBinding : requiredImportDeclarationsBasedOnSignature) {
    addImportDeclaration(typeBinding,stateStrategyCompilationUnit,stateStrategyRewriter);
  }
  if (!stateStrategyAlreadyExists)   stateStrategyTypesRewrite.insertLast(stateStrategyTypeDeclaration,null);
  ITextFileBufferManager bufferManager=FileBuffers.getTextFileBufferManager();
  ITextFileBuffer stateStrategyTextFileBuffer=bufferManager.getTextFileBuffer(stateStrategyFile.getFullPath(),LocationKind.IFILE);
  IDocument stateStrategyDocument=stateStrategyTextFileBuffer.getDocument();
  TextEdit stateStrategyEdit=stateStrategyRewriter.rewriteAST(stateStrategyDocument,null);
  try {
    UndoEdit stateStrategyUndoEdit=stateStrategyEdit.apply(stateStrategyDocument,UndoEdit.CREATE_UNDO);
    undoRefactoring.put(stateStrategyFile,stateStrategyDocument,stateStrategyUndoEdit);
  }
 catch (  MalformedTreeException e) {
    e.printStackTrace();
  }
catch (  BadLocationException e) {
    e.printStackTrace();
  }
  stateStrategyEditor.doSave(null);
  List<ArrayList<Statement>> typeCheckStatements=typeCheckElimination.getTypeCheckStatements();
  List<String> subclassNames=typeCheckElimination.getSubclassNames();
  subclassNames.addAll(additionalStaticFields.values());
  List<String> staticFieldNames=typeCheckElimination.getStaticFieldNames();
  staticFieldNames.addAll(additionalStaticFields.keySet());
  List<DefaultMutableTreeNode> remainingIfStatementExpressions=typeCheckElimination.getRemainingIfStatementExpressions();
  for (int i=0; i < staticFieldNames.size(); i++) {
    ArrayList<Statement> statements=null;
    DefaultMutableTreeNode remainingIfStatementExpression=null;
    if (i < typeCheckStatements.size()) {
      statements=typeCheckStatements.get(i);
      remainingIfStatementExpression=remainingIfStatementExpressions.get(i);
    }
 else {
      statements=typeCheckElimination.getDefaultCaseStatements();
    }
    IFile subclassFile=null;
    if (contextContainer instanceof IProject) {
      IProject contextProject=(IProject)contextContainer;
      subclassFile=contextProject.getFile(subclassNames.get(i) + "String_Node_Str");
    }
 else     if (contextContainer instanceof IFolder) {
      IFolder contextFolder=(IFolder)contextContainer;
      subclassFile=contextFolder.getFile(subclassNames.get(i) + "String_Node_Str");
    }
    boolean subclassAlreadyExists=false;
    try {
      subclassFile.create(new ByteArrayInputStream("String_Node_Str".getBytes()),true,null);
      undoRefactoring.addNewlyCreatedFile(subclassFile);
    }
 catch (    CoreException e) {
      subclassAlreadyExists=true;
    }
    IJavaElement subclassJavaElement=JavaCore.create(subclassFile);
    ITextEditor subclassEditor=null;
    try {
      subclassEditor=(ITextEditor)JavaUI.openInEditor(subclassJavaElement);
    }
 catch (    PartInitException e) {
      e.printStackTrace();
    }
catch (    JavaModelException e) {
      e.printStackTrace();
    }
    ICompilationUnit subclassICompilationUnit=(ICompilationUnit)subclassJavaElement;
    ASTParser subclassParser=ASTParser.newParser(AST.JLS3);
    subclassParser.setKind(ASTParser.K_COMPILATION_UNIT);
    subclassParser.setSource(subclassICompilationUnit);
    subclassParser.setResolveBindings(true);
    CompilationUnit subclassCompilationUnit=(CompilationUnit)subclassParser.createAST(null);
    AST subclassAST=subclassCompilationUnit.getAST();
    ASTRewrite subclassRewriter=ASTRewrite.create(subclassAST);
    ListRewrite subclassTypesRewrite=subclassRewriter.getListRewrite(subclassCompilationUnit,CompilationUnit.TYPES_PROPERTY);
    TypeDeclaration subclassTypeDeclaration=null;
    if (subclassAlreadyExists) {
      List<AbstractTypeDeclaration> abstractTypeDeclarations=subclassCompilationUnit.types();
      for (      AbstractTypeDeclaration abstractTypeDeclaration : abstractTypeDeclarations) {
        if (abstractTypeDeclaration instanceof TypeDeclaration) {
          TypeDeclaration typeDeclaration=(TypeDeclaration)abstractTypeDeclaration;
          if (typeDeclaration.getName().getIdentifier().equals(subclassNames.get(i))) {
            subclassTypeDeclaration=typeDeclaration;
            break;
          }
        }
      }
    }
 else {
      if (sourceCompilationUnit.getPackage() != null) {
        subclassRewriter.set(subclassCompilationUnit,CompilationUnit.PACKAGE_PROPERTY,sourceCompilationUnit.getPackage(),null);
      }
      subclassTypeDeclaration=subclassAST.newTypeDeclaration();
      SimpleName subclassName=subclassAST.newSimpleName(subclassNames.get(i));
      subclassRewriter.set(subclassTypeDeclaration,TypeDeclaration.NAME_PROPERTY,subclassName,null);
      subclassRewriter.set(subclassTypeDeclaration,TypeDeclaration.SUPERCLASS_TYPE_PROPERTY,subclassAST.newSimpleType(subclassAST.newSimpleName(typeCheckElimination.getAbstractClassName())),null);
      ListRewrite subclassModifiersRewrite=subclassRewriter.getListRewrite(subclassTypeDeclaration,TypeDeclaration.MODIFIERS2_PROPERTY);
      subclassModifiersRewrite.insertLast(subclassAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
    }
    ListRewrite subclassBodyRewrite=subclassRewriter.getListRewrite(subclassTypeDeclaration,TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
    if (getterMethod != null) {
      MethodDeclaration concreteGetterMethodDeclaration=subclassAST.newMethodDeclaration();
      subclassRewriter.set(concreteGetterMethodDeclaration,MethodDeclaration.NAME_PROPERTY,getterMethod.getName(),null);
      subclassRewriter.set(concreteGetterMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,getterMethod.getReturnType2(),null);
      ListRewrite concreteGetterMethodModifiersRewrite=subclassRewriter.getListRewrite(concreteGetterMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
      concreteGetterMethodModifiersRewrite.insertLast(subclassAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
      Block concreteGetterMethodBody=subclassAST.newBlock();
      ListRewrite concreteGetterMethodBodyRewrite=subclassRewriter.getListRewrite(concreteGetterMethodBody,Block.STATEMENTS_PROPERTY);
      ReturnStatement returnStatement=subclassAST.newReturnStatement();
      FieldAccess fieldAccess=subclassAST.newFieldAccess();
      subclassRewriter.set(fieldAccess,FieldAccess.NAME_PROPERTY,subclassAST.newSimpleName(staticFieldNames.get(i)),null);
      subclassRewriter.set(fieldAccess,FieldAccess.EXPRESSION_PROPERTY,sourceTypeDeclaration.getName(),null);
      subclassRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,fieldAccess,null);
      concreteGetterMethodBodyRewrite.insertLast(returnStatement,null);
      subclassRewriter.set(concreteGetterMethodDeclaration,MethodDeclaration.BODY_PROPERTY,concreteGetterMethodBody,null);
      subclassBodyRewrite.insertLast(concreteGetterMethodDeclaration,null);
    }
 else {
      MethodDeclaration concreteGetterMethodDeclaration=subclassAST.newMethodDeclaration();
      subclassRewriter.set(concreteGetterMethodDeclaration,MethodDeclaration.NAME_PROPERTY,subclassAST.newSimpleName("String_Node_Str" + typeCheckElimination.getAbstractClassName()),null);
      VariableDeclarationFragment typeField=typeCheckElimination.getTypeField();
      Type returnType=((FieldDeclaration)typeField.getParent()).getType();
      subclassRewriter.set(concreteGetterMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,returnType,null);
      ListRewrite concreteGetterMethodModifiersRewrite=subclassRewriter.getListRewrite(concreteGetterMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
      concreteGetterMethodModifiersRewrite.insertLast(subclassAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
      Block concreteGetterMethodBody=subclassAST.newBlock();
      ListRewrite concreteGetterMethodBodyRewrite=subclassRewriter.getListRewrite(concreteGetterMethodBody,Block.STATEMENTS_PROPERTY);
      ReturnStatement returnStatement=subclassAST.newReturnStatement();
      FieldAccess fieldAccess=subclassAST.newFieldAccess();
      subclassRewriter.set(fieldAccess,FieldAccess.NAME_PROPERTY,subclassAST.newSimpleName(staticFieldNames.get(i)),null);
      subclassRewriter.set(fieldAccess,FieldAccess.EXPRESSION_PROPERTY,sourceTypeDeclaration.getName(),null);
      subclassRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,fieldAccess,null);
      concreteGetterMethodBodyRewrite.insertLast(returnStatement,null);
      subclassRewriter.set(concreteGetterMethodDeclaration,MethodDeclaration.BODY_PROPERTY,concreteGetterMethodBody,null);
      subclassBodyRewrite.insertLast(concreteGetterMethodDeclaration,null);
    }
    MethodDeclaration concreteMethodDeclaration=subclassAST.newMethodDeclaration();
    String concreteMethodName=typeCheckElimination.getTypeCheckMethodName();
    subclassRewriter.set(concreteMethodDeclaration,MethodDeclaration.NAME_PROPERTY,subclassAST.newSimpleName(concreteMethodName),null);
    subclassRewriter.set(concreteMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,typeCheckElimination.getTypeCheckMethodReturnType(),null);
    ListRewrite concreteMethodModifiersRewrite=subclassRewriter.getListRewrite(concreteMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
    concreteMethodModifiersRewrite.insertLast(subclassAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
    ListRewrite concreteMethodParametersRewrite=subclassRewriter.getListRewrite(concreteMethodDeclaration,MethodDeclaration.PARAMETERS_PROPERTY);
    for (    SingleVariableDeclaration abstractMethodParameter : typeCheckElimination.getAccessedParameters()) {
      concreteMethodParametersRewrite.insertLast(abstractMethodParameter,null);
    }
    for (    VariableDeclarationFragment fragment : typeCheckElimination.getAccessedLocalVariables()) {
      if (!fragment.equals(returnedVariable)) {
        SingleVariableDeclaration parameter=subclassAST.newSingleVariableDeclaration();
        VariableDeclarationStatement variableDeclarationStatement=(VariableDeclarationStatement)fragment.getParent();
        subclassRewriter.set(parameter,SingleVariableDeclaration.TYPE_PROPERTY,variableDeclarationStatement.getType(),null);
        subclassRewriter.set(parameter,SingleVariableDeclaration.NAME_PROPERTY,fragment.getName(),null);
        concreteMethodParametersRewrite.insertLast(parameter,null);
      }
    }
    Set<VariableDeclarationFragment> accessedFields=typeCheckElimination.getAccessedFields();
    Set<VariableDeclarationFragment> assignedFields=typeCheckElimination.getAssignedFields();
    Set<MethodDeclaration> accessedMethods=typeCheckElimination.getAccessedMethods();
    if (accessedFields.size() > 0 || assignedFields.size() > 0 || accessedMethods.size() > 0) {
      SingleVariableDeclaration parameter=subclassAST.newSingleVariableDeclaration();
      SimpleName parameterType=subclassAST.newSimpleName(sourceTypeDeclaration.getName().getIdentifier());
      subclassRewriter.set(parameter,SingleVariableDeclaration.TYPE_PROPERTY,subclassAST.newSimpleType(parameterType),null);
      String parameterName=sourceTypeDeclaration.getName().getIdentifier();
      parameterName=parameterName.substring(0,1).toLowerCase() + parameterName.substring(1,parameterName.length());
      subclassRewriter.set(parameter,SingleVariableDeclaration.NAME_PROPERTY,subclassAST.newSimpleName(parameterName),null);
      concreteMethodParametersRewrite.insertLast(parameter,null);
    }
    ListRewrite concreteMethodThrownExceptionsRewrite=subclassRewriter.getListRewrite(concreteMethodDeclaration,MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY);
    for (    ITypeBinding typeBinding : thrownExceptions) {
      concreteMethodThrownExceptionsRewrite.insertLast(subclassAST.newSimpleName(typeBinding.getName()),null);
    }
    Block concreteMethodBody=subclassAST.newBlock();
    ListRewrite concreteMethodBodyRewrite=subclassRewriter.getListRewrite(concreteMethodBody,Block.STATEMENTS_PROPERTY);
    ExpressionExtractor expressionExtractor=new ExpressionExtractor();
    ListRewrite ifStatementBodyRewrite=null;
    if (remainingIfStatementExpression != null) {
      IfStatement enclosingIfStatement=subclassAST.newIfStatement();
      Expression enclosingIfStatementExpression=constructExpression(subclassAST,subclassRewriter,remainingIfStatementExpression);
      Expression newEnclosingIfStatementExpression=(Expression)ASTNode.copySubtree(subclassAST,enclosingIfStatementExpression);
      List<Expression> variableInstructions=expressionExtractor.getVariableInstructions(newEnclosingIfStatementExpression);
      modifyVariableInstructionsInSubclass(variableInstructions,subclassAST,subclassRewriter,accessedFields,assignedFields);
      List<Expression> oldMethodInvocations=expressionExtractor.getMethodInvocations(enclosingIfStatementExpression);
      List<Expression> newMethodInvocations=expressionExtractor.getMethodInvocations(newEnclosingIfStatementExpression);
      modifyMethodInvocationsInSubclass(oldMethodInvocations,newMethodInvocations,subclassAST,subclassRewriter,accessedMethods);
      subclassRewriter.set(enclosingIfStatement,IfStatement.EXPRESSION_PROPERTY,newEnclosingIfStatementExpression,null);
      Block ifStatementBody=subclassAST.newBlock();
      ifStatementBodyRewrite=subclassRewriter.getListRewrite(ifStatementBody,Block.STATEMENTS_PROPERTY);
      subclassRewriter.set(enclosingIfStatement,IfStatement.THEN_STATEMENT_PROPERTY,ifStatementBody,null);
      concreteMethodBodyRewrite.insertLast(enclosingIfStatement,null);
    }
    if (returnedVariable != null) {
      VariableDeclarationFragment variableDeclarationFragment=subclassAST.newVariableDeclarationFragment();
      subclassRewriter.set(variableDeclarationFragment,VariableDeclarationFragment.NAME_PROPERTY,returnedVariable.getName(),null);
      subclassRewriter.set(variableDeclarationFragment,VariableDeclarationFragment.INITIALIZER_PROPERTY,returnedVariable.getInitializer(),null);
      VariableDeclarationStatement variableDeclarationStatement=subclassAST.newVariableDeclarationStatement(variableDeclarationFragment);
      subclassRewriter.set(variableDeclarationStatement,VariableDeclarationStatement.TYPE_PROPERTY,typeCheckElimination.getTypeCheckMethodReturnType(),null);
      if (ifStatementBodyRewrite != null)       ifStatementBodyRewrite.insertFirst(variableDeclarationStatement,null);
 else       concreteMethodBodyRewrite.insertFirst(variableDeclarationStatement,null);
    }
    for (    Statement statement : statements) {
      Statement newStatement=(Statement)ASTNode.copySubtree(subclassAST,statement);
      List<Expression> variableInstructions=expressionExtractor.getVariableInstructions(newStatement);
      modifyVariableInstructionsInSubclass(variableInstructions,subclassAST,subclassRewriter,accessedFields,assignedFields);
      List<Expression> oldMethodInvocations=expressionExtractor.getMethodInvocations(statement);
      List<Expression> newMethodInvocations=expressionExtractor.getMethodInvocations(newStatement);
      modifyMethodInvocationsInSubclass(oldMethodInvocations,newMethodInvocations,subclassAST,subclassRewriter,accessedMethods);
      if (ifStatementBodyRewrite != null)       ifStatementBodyRewrite.insertLast(newStatement,null);
 else       concreteMethodBodyRewrite.insertLast(newStatement,null);
    }
    if (returnedVariable != null) {
      ReturnStatement returnStatement=subclassAST.newReturnStatement();
      subclassRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,returnedVariable.getName(),null);
      if (ifStatementBodyRewrite != null)       ifStatementBodyRewrite.insertLast(returnStatement,null);
 else       concreteMethodBodyRewrite.insertLast(returnStatement,null);
    }
    subclassRewriter.set(concreteMethodDeclaration,MethodDeclaration.BODY_PROPERTY,concreteMethodBody,null);
    subclassBodyRewrite.insertLast(concreteMethodDeclaration,null);
    for (    ITypeBinding typeBinding : requiredImportDeclarationsBasedOnSignature) {
      addImportDeclaration(typeBinding,subclassCompilationUnit,subclassRewriter);
    }
    Set<ITypeBinding> requiredImportDeclarationsBasedOnBranch=generateRequiredImportDeclarationsBasedOnBranch(statements);
    for (    ITypeBinding typeBinding : requiredImportDeclarationsBasedOnBranch) {
      if (!requiredImportDeclarationsBasedOnSignature.contains(typeBinding))       addImportDeclaration(typeBinding,subclassCompilationUnit,subclassRewriter);
    }
    if (!subclassAlreadyExists)     subclassTypesRewrite.insertLast(subclassTypeDeclaration,null);
    ITextFileBuffer subclassTextFileBuffer=bufferManager.getTextFileBuffer(subclassFile.getFullPath(),LocationKind.IFILE);
    IDocument subclassDocument=subclassTextFileBuffer.getDocument();
    TextEdit subclassEdit=subclassRewriter.rewriteAST(subclassDocument,null);
    try {
      UndoEdit subclassUndoEdit=subclassEdit.apply(subclassDocument,UndoEdit.CREATE_UNDO);
      undoRefactoring.put(subclassFile,subclassDocument,subclassUndoEdit);
    }
 catch (    MalformedTreeException e) {
      e.printStackTrace();
    }
catch (    BadLocationException e) {
      e.printStackTrace();
    }
    subclassEditor.doSave(null);
  }
}

Fixed version (ground truth):
private void createStateStrategyHierarchy(){
  IContainer contextContainer=(IContainer)sourceFile.getParent();
  IFile stateStrategyFile=null;
  if (contextContainer instanceof IProject) {
    IProject contextProject=(IProject)contextContainer;
    stateStrategyFile=contextProject.getFile(typeCheckElimination.getAbstractClassName() + "String_Node_Str");
  }
 else   if (contextContainer instanceof IFolder) {
    IFolder contextFolder=(IFolder)contextContainer;
    stateStrategyFile=contextFolder.getFile(typeCheckElimination.getAbstractClassName() + "String_Node_Str");
  }
  boolean stateStrategyAlreadyExists=false;
  try {
    stateStrategyFile.create(new ByteArrayInputStream("String_Node_Str".getBytes()),true,null);
    undoRefactoring.addNewlyCreatedFile(stateStrategyFile);
  }
 catch (  CoreException e) {
    stateStrategyAlreadyExists=true;
  }
  IJavaElement stateStrategyJavaElement=JavaCore.create(stateStrategyFile);
  ITextEditor stateStrategyEditor=null;
  try {
    stateStrategyEditor=(ITextEditor)JavaUI.openInEditor(stateStrategyJavaElement);
  }
 catch (  PartInitException e) {
    e.printStackTrace();
  }
catch (  JavaModelException e) {
    e.printStackTrace();
  }
  ICompilationUnit stateStrategyICompilationUnit=(ICompilationUnit)stateStrategyJavaElement;
  ASTParser stateStrategyParser=ASTParser.newParser(AST.JLS3);
  stateStrategyParser.setKind(ASTParser.K_COMPILATION_UNIT);
  stateStrategyParser.setSource(stateStrategyICompilationUnit);
  stateStrategyParser.setResolveBindings(true);
  CompilationUnit stateStrategyCompilationUnit=(CompilationUnit)stateStrategyParser.createAST(null);
  AST stateStrategyAST=stateStrategyCompilationUnit.getAST();
  ASTRewrite stateStrategyRewriter=ASTRewrite.create(stateStrategyAST);
  ListRewrite stateStrategyTypesRewrite=stateStrategyRewriter.getListRewrite(stateStrategyCompilationUnit,CompilationUnit.TYPES_PROPERTY);
  TypeDeclaration stateStrategyTypeDeclaration=null;
  if (stateStrategyAlreadyExists) {
    List<AbstractTypeDeclaration> abstractTypeDeclarations=stateStrategyCompilationUnit.types();
    for (    AbstractTypeDeclaration abstractTypeDeclaration : abstractTypeDeclarations) {
      if (abstractTypeDeclaration instanceof TypeDeclaration) {
        TypeDeclaration typeDeclaration=(TypeDeclaration)abstractTypeDeclaration;
        if (typeDeclaration.getName().getIdentifier().equals(typeCheckElimination.getAbstractClassName())) {
          stateStrategyTypeDeclaration=typeDeclaration;
          int stateStrategyModifiers=stateStrategyTypeDeclaration.getModifiers();
          if ((stateStrategyModifiers & Modifier.ABSTRACT) == 0) {
            ListRewrite stateStrategyModifiersRewrite=stateStrategyRewriter.getListRewrite(stateStrategyTypeDeclaration,TypeDeclaration.MODIFIERS2_PROPERTY);
            stateStrategyModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD),null);
          }
          break;
        }
      }
    }
  }
 else {
    if (sourceCompilationUnit.getPackage() != null) {
      stateStrategyRewriter.set(stateStrategyCompilationUnit,CompilationUnit.PACKAGE_PROPERTY,sourceCompilationUnit.getPackage(),null);
    }
    stateStrategyTypeDeclaration=stateStrategyAST.newTypeDeclaration();
    SimpleName stateStrategyName=stateStrategyAST.newSimpleName(typeCheckElimination.getAbstractClassName());
    stateStrategyRewriter.set(stateStrategyTypeDeclaration,TypeDeclaration.NAME_PROPERTY,stateStrategyName,null);
    ListRewrite stateStrategyModifiersRewrite=stateStrategyRewriter.getListRewrite(stateStrategyTypeDeclaration,TypeDeclaration.MODIFIERS2_PROPERTY);
    stateStrategyModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
    stateStrategyModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD),null);
  }
  ListRewrite stateStrategyBodyRewrite=stateStrategyRewriter.getListRewrite(stateStrategyTypeDeclaration,TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
  MethodDeclaration getterMethod=typeCheckElimination.getTypeFieldGetterMethod();
  if (getterMethod != null) {
    MethodDeclaration abstractGetterMethodDeclaration=stateStrategyAST.newMethodDeclaration();
    stateStrategyRewriter.set(abstractGetterMethodDeclaration,MethodDeclaration.NAME_PROPERTY,getterMethod.getName(),null);
    stateStrategyRewriter.set(abstractGetterMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,getterMethod.getReturnType2(),null);
    ListRewrite abstractGetterMethodModifiersRewrite=stateStrategyRewriter.getListRewrite(abstractGetterMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
    abstractGetterMethodModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
    abstractGetterMethodModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD),null);
    stateStrategyBodyRewrite.insertLast(abstractGetterMethodDeclaration,null);
  }
 else {
    MethodDeclaration abstractGetterMethodDeclaration=stateStrategyAST.newMethodDeclaration();
    stateStrategyRewriter.set(abstractGetterMethodDeclaration,MethodDeclaration.NAME_PROPERTY,stateStrategyAST.newSimpleName("String_Node_Str" + typeCheckElimination.getAbstractClassName()),null);
    VariableDeclarationFragment typeField=typeCheckElimination.getTypeField();
    Type returnType=((FieldDeclaration)typeField.getParent()).getType();
    stateStrategyRewriter.set(abstractGetterMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,returnType,null);
    ListRewrite abstractGetterMethodModifiersRewrite=stateStrategyRewriter.getListRewrite(abstractGetterMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
    abstractGetterMethodModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
    abstractGetterMethodModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD),null);
    stateStrategyBodyRewrite.insertLast(abstractGetterMethodDeclaration,null);
  }
  MethodDeclaration abstractMethodDeclaration=stateStrategyAST.newMethodDeclaration();
  String abstractMethodName=typeCheckElimination.getTypeCheckMethodName();
  stateStrategyRewriter.set(abstractMethodDeclaration,MethodDeclaration.NAME_PROPERTY,stateStrategyAST.newSimpleName(abstractMethodName),null);
  stateStrategyRewriter.set(abstractMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,typeCheckElimination.getTypeCheckMethodReturnType(),null);
  ListRewrite abstractMethodModifiersRewrite=stateStrategyRewriter.getListRewrite(abstractMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
  abstractMethodModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
  abstractMethodModifiersRewrite.insertLast(stateStrategyAST.newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD),null);
  ListRewrite abstractMethodParametersRewrite=stateStrategyRewriter.getListRewrite(abstractMethodDeclaration,MethodDeclaration.PARAMETERS_PROPERTY);
  for (  SingleVariableDeclaration abstractMethodParameter : typeCheckElimination.getAccessedParameters()) {
    abstractMethodParametersRewrite.insertLast(abstractMethodParameter,null);
  }
  for (  VariableDeclarationFragment fragment : typeCheckElimination.getAccessedLocalVariables()) {
    if (!fragment.equals(returnedVariable)) {
      SingleVariableDeclaration parameter=stateStrategyAST.newSingleVariableDeclaration();
      VariableDeclarationStatement variableDeclarationStatement=(VariableDeclarationStatement)fragment.getParent();
      stateStrategyRewriter.set(parameter,SingleVariableDeclaration.TYPE_PROPERTY,variableDeclarationStatement.getType(),null);
      stateStrategyRewriter.set(parameter,SingleVariableDeclaration.NAME_PROPERTY,fragment.getName(),null);
      abstractMethodParametersRewrite.insertLast(parameter,null);
    }
  }
  if (typeCheckElimination.getAccessedFields().size() > 0 || typeCheckElimination.getAssignedFields().size() > 0 || typeCheckElimination.getAccessedMethods().size() > 0) {
    SingleVariableDeclaration parameter=stateStrategyAST.newSingleVariableDeclaration();
    SimpleName parameterType=stateStrategyAST.newSimpleName(sourceTypeDeclaration.getName().getIdentifier());
    stateStrategyRewriter.set(parameter,SingleVariableDeclaration.TYPE_PROPERTY,stateStrategyAST.newSimpleType(parameterType),null);
    String parameterName=sourceTypeDeclaration.getName().getIdentifier();
    parameterName=parameterName.substring(0,1).toLowerCase() + parameterName.substring(1,parameterName.length());
    stateStrategyRewriter.set(parameter,SingleVariableDeclaration.NAME_PROPERTY,stateStrategyAST.newSimpleName(parameterName),null);
    abstractMethodParametersRewrite.insertLast(parameter,null);
  }
  ListRewrite abstractMethodThrownExceptionsRewrite=stateStrategyRewriter.getListRewrite(abstractMethodDeclaration,MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY);
  for (  ITypeBinding typeBinding : thrownExceptions) {
    abstractMethodThrownExceptionsRewrite.insertLast(stateStrategyAST.newSimpleName(typeBinding.getName()),null);
  }
  stateStrategyBodyRewrite.insertLast(abstractMethodDeclaration,null);
  generateRequiredImportDeclarationsBasedOnSignature();
  for (  ITypeBinding typeBinding : requiredImportDeclarationsBasedOnSignature) {
    addImportDeclaration(typeBinding,stateStrategyCompilationUnit,stateStrategyRewriter);
  }
  if (!stateStrategyAlreadyExists)   stateStrategyTypesRewrite.insertLast(stateStrategyTypeDeclaration,null);
  ITextFileBufferManager bufferManager=FileBuffers.getTextFileBufferManager();
  ITextFileBuffer stateStrategyTextFileBuffer=bufferManager.getTextFileBuffer(stateStrategyFile.getFullPath(),LocationKind.IFILE);
  IDocument stateStrategyDocument=stateStrategyTextFileBuffer.getDocument();
  TextEdit stateStrategyEdit=stateStrategyRewriter.rewriteAST(stateStrategyDocument,null);
  try {
    UndoEdit stateStrategyUndoEdit=stateStrategyEdit.apply(stateStrategyDocument,UndoEdit.CREATE_UNDO);
    undoRefactoring.put(stateStrategyFile,stateStrategyDocument,stateStrategyUndoEdit);
  }
 catch (  MalformedTreeException e) {
    e.printStackTrace();
  }
catch (  BadLocationException e) {
    e.printStackTrace();
  }
  stateStrategyEditor.doSave(null);
  List<ArrayList<Statement>> typeCheckStatements=typeCheckElimination.getTypeCheckStatements();
  List<String> subclassNames=typeCheckElimination.getSubclassNames();
  subclassNames.addAll(additionalStaticFields.values());
  List<String> staticFieldNames=typeCheckElimination.getStaticFieldNames();
  staticFieldNames.addAll(additionalStaticFields.keySet());
  List<DefaultMutableTreeNode> remainingIfStatementExpressions=typeCheckElimination.getRemainingIfStatementExpressions();
  for (int i=0; i < staticFieldNames.size(); i++) {
    ArrayList<Statement> statements=null;
    DefaultMutableTreeNode remainingIfStatementExpression=null;
    if (i < typeCheckStatements.size()) {
      statements=typeCheckStatements.get(i);
      if (!remainingIfStatementExpressions.isEmpty())       remainingIfStatementExpression=remainingIfStatementExpressions.get(i);
    }
 else {
      statements=typeCheckElimination.getDefaultCaseStatements();
    }
    IFile subclassFile=null;
    if (contextContainer instanceof IProject) {
      IProject contextProject=(IProject)contextContainer;
      subclassFile=contextProject.getFile(subclassNames.get(i) + "String_Node_Str");
    }
 else     if (contextContainer instanceof IFolder) {
      IFolder contextFolder=(IFolder)contextContainer;
      subclassFile=contextFolder.getFile(subclassNames.get(i) + "String_Node_Str");
    }
    boolean subclassAlreadyExists=false;
    try {
      subclassFile.create(new ByteArrayInputStream("String_Node_Str".getBytes()),true,null);
      undoRefactoring.addNewlyCreatedFile(subclassFile);
    }
 catch (    CoreException e) {
      subclassAlreadyExists=true;
    }
    IJavaElement subclassJavaElement=JavaCore.create(subclassFile);
    ITextEditor subclassEditor=null;
    try {
      subclassEditor=(ITextEditor)JavaUI.openInEditor(subclassJavaElement);
    }
 catch (    PartInitException e) {
      e.printStackTrace();
    }
catch (    JavaModelException e) {
      e.printStackTrace();
    }
    ICompilationUnit subclassICompilationUnit=(ICompilationUnit)subclassJavaElement;
    ASTParser subclassParser=ASTParser.newParser(AST.JLS3);
    subclassParser.setKind(ASTParser.K_COMPILATION_UNIT);
    subclassParser.setSource(subclassICompilationUnit);
    subclassParser.setResolveBindings(true);
    CompilationUnit subclassCompilationUnit=(CompilationUnit)subclassParser.createAST(null);
    AST subclassAST=subclassCompilationUnit.getAST();
    ASTRewrite subclassRewriter=ASTRewrite.create(subclassAST);
    ListRewrite subclassTypesRewrite=subclassRewriter.getListRewrite(subclassCompilationUnit,CompilationUnit.TYPES_PROPERTY);
    TypeDeclaration subclassTypeDeclaration=null;
    if (subclassAlreadyExists) {
      List<AbstractTypeDeclaration> abstractTypeDeclarations=subclassCompilationUnit.types();
      for (      AbstractTypeDeclaration abstractTypeDeclaration : abstractTypeDeclarations) {
        if (abstractTypeDeclaration instanceof TypeDeclaration) {
          TypeDeclaration typeDeclaration=(TypeDeclaration)abstractTypeDeclaration;
          if (typeDeclaration.getName().getIdentifier().equals(subclassNames.get(i))) {
            subclassTypeDeclaration=typeDeclaration;
            break;
          }
        }
      }
    }
 else {
      if (sourceCompilationUnit.getPackage() != null) {
        subclassRewriter.set(subclassCompilationUnit,CompilationUnit.PACKAGE_PROPERTY,sourceCompilationUnit.getPackage(),null);
      }
      subclassTypeDeclaration=subclassAST.newTypeDeclaration();
      SimpleName subclassName=subclassAST.newSimpleName(subclassNames.get(i));
      subclassRewriter.set(subclassTypeDeclaration,TypeDeclaration.NAME_PROPERTY,subclassName,null);
      subclassRewriter.set(subclassTypeDeclaration,TypeDeclaration.SUPERCLASS_TYPE_PROPERTY,subclassAST.newSimpleType(subclassAST.newSimpleName(typeCheckElimination.getAbstractClassName())),null);
      ListRewrite subclassModifiersRewrite=subclassRewriter.getListRewrite(subclassTypeDeclaration,TypeDeclaration.MODIFIERS2_PROPERTY);
      subclassModifiersRewrite.insertLast(subclassAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
    }
    ListRewrite subclassBodyRewrite=subclassRewriter.getListRewrite(subclassTypeDeclaration,TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
    if (getterMethod != null) {
      MethodDeclaration concreteGetterMethodDeclaration=subclassAST.newMethodDeclaration();
      subclassRewriter.set(concreteGetterMethodDeclaration,MethodDeclaration.NAME_PROPERTY,getterMethod.getName(),null);
      subclassRewriter.set(concreteGetterMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,getterMethod.getReturnType2(),null);
      ListRewrite concreteGetterMethodModifiersRewrite=subclassRewriter.getListRewrite(concreteGetterMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
      concreteGetterMethodModifiersRewrite.insertLast(subclassAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
      Block concreteGetterMethodBody=subclassAST.newBlock();
      ListRewrite concreteGetterMethodBodyRewrite=subclassRewriter.getListRewrite(concreteGetterMethodBody,Block.STATEMENTS_PROPERTY);
      ReturnStatement returnStatement=subclassAST.newReturnStatement();
      FieldAccess fieldAccess=subclassAST.newFieldAccess();
      subclassRewriter.set(fieldAccess,FieldAccess.NAME_PROPERTY,subclassAST.newSimpleName(staticFieldNames.get(i)),null);
      subclassRewriter.set(fieldAccess,FieldAccess.EXPRESSION_PROPERTY,sourceTypeDeclaration.getName(),null);
      subclassRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,fieldAccess,null);
      concreteGetterMethodBodyRewrite.insertLast(returnStatement,null);
      subclassRewriter.set(concreteGetterMethodDeclaration,MethodDeclaration.BODY_PROPERTY,concreteGetterMethodBody,null);
      subclassBodyRewrite.insertLast(concreteGetterMethodDeclaration,null);
    }
 else {
      MethodDeclaration concreteGetterMethodDeclaration=subclassAST.newMethodDeclaration();
      subclassRewriter.set(concreteGetterMethodDeclaration,MethodDeclaration.NAME_PROPERTY,subclassAST.newSimpleName("String_Node_Str" + typeCheckElimination.getAbstractClassName()),null);
      VariableDeclarationFragment typeField=typeCheckElimination.getTypeField();
      Type returnType=((FieldDeclaration)typeField.getParent()).getType();
      subclassRewriter.set(concreteGetterMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,returnType,null);
      ListRewrite concreteGetterMethodModifiersRewrite=subclassRewriter.getListRewrite(concreteGetterMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
      concreteGetterMethodModifiersRewrite.insertLast(subclassAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
      Block concreteGetterMethodBody=subclassAST.newBlock();
      ListRewrite concreteGetterMethodBodyRewrite=subclassRewriter.getListRewrite(concreteGetterMethodBody,Block.STATEMENTS_PROPERTY);
      ReturnStatement returnStatement=subclassAST.newReturnStatement();
      FieldAccess fieldAccess=subclassAST.newFieldAccess();
      subclassRewriter.set(fieldAccess,FieldAccess.NAME_PROPERTY,subclassAST.newSimpleName(staticFieldNames.get(i)),null);
      subclassRewriter.set(fieldAccess,FieldAccess.EXPRESSION_PROPERTY,sourceTypeDeclaration.getName(),null);
      subclassRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,fieldAccess,null);
      concreteGetterMethodBodyRewrite.insertLast(returnStatement,null);
      subclassRewriter.set(concreteGetterMethodDeclaration,MethodDeclaration.BODY_PROPERTY,concreteGetterMethodBody,null);
      subclassBodyRewrite.insertLast(concreteGetterMethodDeclaration,null);
    }
    MethodDeclaration concreteMethodDeclaration=subclassAST.newMethodDeclaration();
    String concreteMethodName=typeCheckElimination.getTypeCheckMethodName();
    subclassRewriter.set(concreteMethodDeclaration,MethodDeclaration.NAME_PROPERTY,subclassAST.newSimpleName(concreteMethodName),null);
    subclassRewriter.set(concreteMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,typeCheckElimination.getTypeCheckMethodReturnType(),null);
    ListRewrite concreteMethodModifiersRewrite=subclassRewriter.getListRewrite(concreteMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
    concreteMethodModifiersRewrite.insertLast(subclassAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
    ListRewrite concreteMethodParametersRewrite=subclassRewriter.getListRewrite(concreteMethodDeclaration,MethodDeclaration.PARAMETERS_PROPERTY);
    for (    SingleVariableDeclaration abstractMethodParameter : typeCheckElimination.getAccessedParameters()) {
      concreteMethodParametersRewrite.insertLast(abstractMethodParameter,null);
    }
    for (    VariableDeclarationFragment fragment : typeCheckElimination.getAccessedLocalVariables()) {
      if (!fragment.equals(returnedVariable)) {
        SingleVariableDeclaration parameter=subclassAST.newSingleVariableDeclaration();
        VariableDeclarationStatement variableDeclarationStatement=(VariableDeclarationStatement)fragment.getParent();
        subclassRewriter.set(parameter,SingleVariableDeclaration.TYPE_PROPERTY,variableDeclarationStatement.getType(),null);
        subclassRewriter.set(parameter,SingleVariableDeclaration.NAME_PROPERTY,fragment.getName(),null);
        concreteMethodParametersRewrite.insertLast(parameter,null);
      }
    }
    Set<VariableDeclarationFragment> accessedFields=typeCheckElimination.getAccessedFields();
    Set<VariableDeclarationFragment> assignedFields=typeCheckElimination.getAssignedFields();
    Set<MethodDeclaration> accessedMethods=typeCheckElimination.getAccessedMethods();
    if (accessedFields.size() > 0 || assignedFields.size() > 0 || accessedMethods.size() > 0) {
      SingleVariableDeclaration parameter=subclassAST.newSingleVariableDeclaration();
      SimpleName parameterType=subclassAST.newSimpleName(sourceTypeDeclaration.getName().getIdentifier());
      subclassRewriter.set(parameter,SingleVariableDeclaration.TYPE_PROPERTY,subclassAST.newSimpleType(parameterType),null);
      String parameterName=sourceTypeDeclaration.getName().getIdentifier();
      parameterName=parameterName.substring(0,1).toLowerCase() + parameterName.substring(1,parameterName.length());
      subclassRewriter.set(parameter,SingleVariableDeclaration.NAME_PROPERTY,subclassAST.newSimpleName(parameterName),null);
      concreteMethodParametersRewrite.insertLast(parameter,null);
    }
    ListRewrite concreteMethodThrownExceptionsRewrite=subclassRewriter.getListRewrite(concreteMethodDeclaration,MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY);
    for (    ITypeBinding typeBinding : thrownExceptions) {
      concreteMethodThrownExceptionsRewrite.insertLast(subclassAST.newSimpleName(typeBinding.getName()),null);
    }
    Block concreteMethodBody=subclassAST.newBlock();
    ListRewrite concreteMethodBodyRewrite=subclassRewriter.getListRewrite(concreteMethodBody,Block.STATEMENTS_PROPERTY);
    ExpressionExtractor expressionExtractor=new ExpressionExtractor();
    ListRewrite ifStatementBodyRewrite=null;
    if (remainingIfStatementExpression != null) {
      IfStatement enclosingIfStatement=subclassAST.newIfStatement();
      Expression enclosingIfStatementExpression=constructExpression(subclassAST,subclassRewriter,remainingIfStatementExpression);
      Expression newEnclosingIfStatementExpression=(Expression)ASTNode.copySubtree(subclassAST,enclosingIfStatementExpression);
      List<Expression> variableInstructions=expressionExtractor.getVariableInstructions(newEnclosingIfStatementExpression);
      modifyVariableInstructionsInSubclass(variableInstructions,subclassAST,subclassRewriter,accessedFields,assignedFields);
      List<Expression> oldMethodInvocations=expressionExtractor.getMethodInvocations(enclosingIfStatementExpression);
      List<Expression> newMethodInvocations=expressionExtractor.getMethodInvocations(newEnclosingIfStatementExpression);
      modifyMethodInvocationsInSubclass(oldMethodInvocations,newMethodInvocations,subclassAST,subclassRewriter,accessedMethods);
      subclassRewriter.set(enclosingIfStatement,IfStatement.EXPRESSION_PROPERTY,newEnclosingIfStatementExpression,null);
      Block ifStatementBody=subclassAST.newBlock();
      ifStatementBodyRewrite=subclassRewriter.getListRewrite(ifStatementBody,Block.STATEMENTS_PROPERTY);
      subclassRewriter.set(enclosingIfStatement,IfStatement.THEN_STATEMENT_PROPERTY,ifStatementBody,null);
      concreteMethodBodyRewrite.insertLast(enclosingIfStatement,null);
    }
    if (returnedVariable != null) {
      VariableDeclarationFragment variableDeclarationFragment=subclassAST.newVariableDeclarationFragment();
      subclassRewriter.set(variableDeclarationFragment,VariableDeclarationFragment.NAME_PROPERTY,returnedVariable.getName(),null);
      subclassRewriter.set(variableDeclarationFragment,VariableDeclarationFragment.INITIALIZER_PROPERTY,returnedVariable.getInitializer(),null);
      VariableDeclarationStatement variableDeclarationStatement=subclassAST.newVariableDeclarationStatement(variableDeclarationFragment);
      subclassRewriter.set(variableDeclarationStatement,VariableDeclarationStatement.TYPE_PROPERTY,typeCheckElimination.getTypeCheckMethodReturnType(),null);
      if (ifStatementBodyRewrite != null)       ifStatementBodyRewrite.insertFirst(variableDeclarationStatement,null);
 else       concreteMethodBodyRewrite.insertFirst(variableDeclarationStatement,null);
    }
    for (    Statement statement : statements) {
      Statement newStatement=(Statement)ASTNode.copySubtree(subclassAST,statement);
      List<Expression> variableInstructions=expressionExtractor.getVariableInstructions(newStatement);
      modifyVariableInstructionsInSubclass(variableInstructions,subclassAST,subclassRewriter,accessedFields,assignedFields);
      List<Expression> oldMethodInvocations=expressionExtractor.getMethodInvocations(statement);
      List<Expression> newMethodInvocations=expressionExtractor.getMethodInvocations(newStatement);
      modifyMethodInvocationsInSubclass(oldMethodInvocations,newMethodInvocations,subclassAST,subclassRewriter,accessedMethods);
      if (ifStatementBodyRewrite != null)       ifStatementBodyRewrite.insertLast(newStatement,null);
 else       concreteMethodBodyRewrite.insertLast(newStatement,null);
    }
    if (returnedVariable != null) {
      ReturnStatement returnStatement=subclassAST.newReturnStatement();
      subclassRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,returnedVariable.getName(),null);
      if (ifStatementBodyRewrite != null)       ifStatementBodyRewrite.insertLast(returnStatement,null);
 else       concreteMethodBodyRewrite.insertLast(returnStatement,null);
    }
    subclassRewriter.set(concreteMethodDeclaration,MethodDeclaration.BODY_PROPERTY,concreteMethodBody,null);
    subclassBodyRewrite.insertLast(concreteMethodDeclaration,null);
    for (    ITypeBinding typeBinding : requiredImportDeclarationsBasedOnSignature) {
      addImportDeclaration(typeBinding,subclassCompilationUnit,subclassRewriter);
    }
    Set<ITypeBinding> requiredImportDeclarationsBasedOnBranch=generateRequiredImportDeclarationsBasedOnBranch(statements);
    for (    ITypeBinding typeBinding : requiredImportDeclarationsBasedOnBranch) {
      if (!requiredImportDeclarationsBasedOnSignature.contains(typeBinding))       addImportDeclaration(typeBinding,subclassCompilationUnit,subclassRewriter);
    }
    if (!subclassAlreadyExists)     subclassTypesRewrite.insertLast(subclassTypeDeclaration,null);
    ITextFileBuffer subclassTextFileBuffer=bufferManager.getTextFileBuffer(subclassFile.getFullPath(),LocationKind.IFILE);
    IDocument subclassDocument=subclassTextFileBuffer.getDocument();
    TextEdit subclassEdit=subclassRewriter.rewriteAST(subclassDocument,null);
    try {
      UndoEdit subclassUndoEdit=subclassEdit.apply(subclassDocument,UndoEdit.CREATE_UNDO);
      undoRefactoring.put(subclassFile,subclassDocument,subclassUndoEdit);
    }
 catch (    MalformedTreeException e) {
      e.printStackTrace();
    }
catch (    BadLocationException e) {
      e.printStackTrace();
    }
    subclassEditor.doSave(null);
  }
}