Program: 12179
Project: 12179
Buggy source:
private void modifyContext(){
  AST contextAST=sourceTypeDeclaration.getAST();
  ListRewrite contextBodyRewrite=sourceRewriter.getListRewrite(sourceTypeDeclaration,TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
  VariableDeclarationFragment typeFragment=contextAST.newVariableDeclarationFragment();
  sourceRewriter.set(typeFragment,VariableDeclarationFragment.NAME_PROPERTY,typeCheckElimination.getTypeField().getName(),null);
  FieldDeclaration typeFieldDeclaration=contextAST.newFieldDeclaration(typeFragment);
  sourceRewriter.set(typeFieldDeclaration,FieldDeclaration.TYPE_PROPERTY,contextAST.newSimpleName(typeCheckElimination.getAbstractClassName()),null);
  ListRewrite typeFieldDeclrationModifiersRewrite=sourceRewriter.getListRewrite(typeFieldDeclaration,FieldDeclaration.MODIFIERS2_PROPERTY);
  typeFieldDeclrationModifiersRewrite.insertLast(contextAST.newModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD),null);
  contextBodyRewrite.insertFirst(typeFieldDeclaration,null);
  FieldDeclaration[] fieldDeclarations=sourceTypeDeclaration.getFields();
  for (  FieldDeclaration fieldDeclaration : fieldDeclarations) {
    List<VariableDeclarationFragment> fragments=fieldDeclaration.fragments();
    for (    VariableDeclarationFragment fragment : fragments) {
      if (fragment.equals(typeCheckElimination.getTypeField())) {
        if (fragments.size() == 1) {
          contextBodyRewrite.remove(fragment.getParent(),null);
        }
 else {
          ListRewrite fragmentRewrite=sourceRewriter.getListRewrite(fragment.getParent(),FieldDeclaration.FRAGMENTS_PROPERTY);
          fragmentRewrite.remove(fragment,null);
        }
      }
    }
  }
  modifyTypeFieldAssignmentsInContextClass();
  modifyTypeFieldAccessesInContextClass();
  MethodDeclaration setterMethod=typeCheckElimination.getTypeFieldSetterMethod();
  SwitchStatement switchStatement=contextAST.newSwitchStatement();
  List<SimpleName> staticFieldNames=typeCheckElimination.getStaticFields();
  List<String> subclassNames=typeCheckElimination.getSubclassNames();
  ListRewrite switchStatementStatementsRewrite=sourceRewriter.getListRewrite(switchStatement,SwitchStatement.STATEMENTS_PROPERTY);
  int i=0;
  for (  SimpleName staticFieldName : staticFieldNames) {
    SwitchCase switchCase=contextAST.newSwitchCase();
    IBinding staticFieldNameBinding=staticFieldName.resolveBinding();
    String staticFieldNameDeclaringClass=null;
    boolean isEnumConstant=false;
    if (staticFieldNameBinding.getKind() == IBinding.VARIABLE) {
      IVariableBinding staticFieldNameVariableBinding=(IVariableBinding)staticFieldNameBinding;
      isEnumConstant=staticFieldNameVariableBinding.isEnumConstant();
      if (!sourceTypeDeclaration.resolveBinding().isEqualTo(staticFieldNameVariableBinding.getDeclaringClass())) {
        staticFieldNameDeclaringClass=staticFieldNameVariableBinding.getDeclaringClass().getName();
      }
    }
    if (staticFieldNameDeclaringClass == null || isEnumConstant) {
      sourceRewriter.set(switchCase,SwitchCase.EXPRESSION_PROPERTY,staticFieldName,null);
    }
 else {
      FieldAccess fieldAccess=contextAST.newFieldAccess();
      sourceRewriter.set(fieldAccess,FieldAccess.EXPRESSION_PROPERTY,contextAST.newSimpleName(staticFieldNameDeclaringClass),null);
      sourceRewriter.set(fieldAccess,FieldAccess.NAME_PROPERTY,staticFieldName,null);
      sourceRewriter.set(switchCase,SwitchCase.EXPRESSION_PROPERTY,fieldAccess,null);
    }
    switchStatementStatementsRewrite.insertLast(switchCase,null);
    Assignment assignment=contextAST.newAssignment();
    sourceRewriter.set(assignment,Assignment.OPERATOR_PROPERTY,Assignment.Operator.ASSIGN,null);
    FieldAccess typeFieldAccess=contextAST.newFieldAccess();
    sourceRewriter.set(typeFieldAccess,FieldAccess.EXPRESSION_PROPERTY,contextAST.newThisExpression(),null);
    sourceRewriter.set(typeFieldAccess,FieldAccess.NAME_PROPERTY,typeCheckElimination.getTypeField().getName(),null);
    sourceRewriter.set(assignment,Assignment.LEFT_HAND_SIDE_PROPERTY,typeFieldAccess,null);
    ClassInstanceCreation classInstanceCreation=contextAST.newClassInstanceCreation();
    sourceRewriter.set(classInstanceCreation,ClassInstanceCreation.TYPE_PROPERTY,contextAST.newSimpleName(subclassNames.get(i)),null);
    sourceRewriter.set(assignment,Assignment.RIGHT_HAND_SIDE_PROPERTY,classInstanceCreation,null);
    switchStatementStatementsRewrite.insertLast(contextAST.newExpressionStatement(assignment),null);
    switchStatementStatementsRewrite.insertLast(contextAST.newBreakStatement(),null);
    i++;
  }
  for (  SimpleName staticFieldName : additionalStaticFields.keySet()) {
    SwitchCase switchCase=contextAST.newSwitchCase();
    IBinding staticFieldNameBinding=staticFieldName.resolveBinding();
    String staticFieldNameDeclaringClass=null;
    boolean isEnumConstant=false;
    if (staticFieldNameBinding.getKind() == IBinding.VARIABLE) {
      IVariableBinding staticFieldNameVariableBinding=(IVariableBinding)staticFieldNameBinding;
      isEnumConstant=staticFieldNameVariableBinding.isEnumConstant();
      if (!sourceTypeDeclaration.resolveBinding().isEqualTo(staticFieldNameVariableBinding.getDeclaringClass())) {
        staticFieldNameDeclaringClass=staticFieldNameVariableBinding.getDeclaringClass().getName();
      }
    }
    if (staticFieldNameDeclaringClass == null || isEnumConstant) {
      sourceRewriter.set(switchCase,SwitchCase.EXPRESSION_PROPERTY,staticFieldName,null);
    }
 else {
      FieldAccess fieldAccess=contextAST.newFieldAccess();
      sourceRewriter.set(fieldAccess,FieldAccess.EXPRESSION_PROPERTY,contextAST.newSimpleName(staticFieldNameDeclaringClass),null);
      sourceRewriter.set(fieldAccess,FieldAccess.NAME_PROPERTY,staticFieldName,null);
      sourceRewriter.set(switchCase,SwitchCase.EXPRESSION_PROPERTY,fieldAccess,null);
    }
    switchStatementStatementsRewrite.insertLast(switchCase,null);
    Assignment assignment=contextAST.newAssignment();
    sourceRewriter.set(assignment,Assignment.OPERATOR_PROPERTY,Assignment.Operator.ASSIGN,null);
    FieldAccess typeFieldAccess=contextAST.newFieldAccess();
    sourceRewriter.set(typeFieldAccess,FieldAccess.EXPRESSION_PROPERTY,contextAST.newThisExpression(),null);
    sourceRewriter.set(typeFieldAccess,FieldAccess.NAME_PROPERTY,typeCheckElimination.getTypeField().getName(),null);
    sourceRewriter.set(assignment,Assignment.LEFT_HAND_SIDE_PROPERTY,typeFieldAccess,null);
    ClassInstanceCreation classInstanceCreation=contextAST.newClassInstanceCreation();
    sourceRewriter.set(classInstanceCreation,ClassInstanceCreation.TYPE_PROPERTY,contextAST.newSimpleName(additionalStaticFields.get(staticFieldName)),null);
    sourceRewriter.set(assignment,Assignment.RIGHT_HAND_SIDE_PROPERTY,classInstanceCreation,null);
    switchStatementStatementsRewrite.insertLast(contextAST.newExpressionStatement(assignment),null);
    switchStatementStatementsRewrite.insertLast(contextAST.newBreakStatement(),null);
  }
  if (setterMethod != null) {
    List<SingleVariableDeclaration> setterMethodParameters=setterMethod.parameters();
    if (setterMethodParameters.size() == 1) {
      sourceRewriter.set(switchStatement,SwitchStatement.EXPRESSION_PROPERTY,setterMethodParameters.get(0).getName(),null);
    }
    Block setterMethodBody=setterMethod.getBody();
    List<Statement> setterMethodBodyStatements=setterMethodBody.statements();
    ListRewrite setterMethodBodyRewrite=sourceRewriter.getListRewrite(setterMethodBody,Block.STATEMENTS_PROPERTY);
    if (setterMethodBodyStatements.size() == 1) {
      setterMethodBodyRewrite.replace(setterMethodBodyStatements.get(0),switchStatement,null);
    }
  }
 else {
    MethodDeclaration setterMethodDeclaration=contextAST.newMethodDeclaration();
    sourceRewriter.set(setterMethodDeclaration,MethodDeclaration.NAME_PROPERTY,contextAST.newSimpleName("String_Node_Str" + typeCheckElimination.getAbstractClassName()),null);
    sourceRewriter.set(setterMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,contextAST.newPrimitiveType(PrimitiveType.VOID),null);
    ListRewrite setterMethodModifiersRewrite=sourceRewriter.getListRewrite(setterMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
    setterMethodModifiersRewrite.insertLast(contextAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
    ListRewrite setterMethodParameterRewrite=sourceRewriter.getListRewrite(setterMethodDeclaration,MethodDeclaration.PARAMETERS_PROPERTY);
    SingleVariableDeclaration parameter=contextAST.newSingleVariableDeclaration();
    VariableDeclarationFragment typeField=typeCheckElimination.getTypeField();
    Type parameterType=((FieldDeclaration)typeField.getParent()).getType();
    sourceRewriter.set(parameter,SingleVariableDeclaration.TYPE_PROPERTY,parameterType,null);
    sourceRewriter.set(parameter,SingleVariableDeclaration.NAME_PROPERTY,typeField.getName(),null);
    setterMethodParameterRewrite.insertLast(parameter,null);
    sourceRewriter.set(switchStatement,SwitchStatement.EXPRESSION_PROPERTY,typeField.getName(),null);
    Block setterMethodBody=contextAST.newBlock();
    ListRewrite setterMethodBodyRewrite=sourceRewriter.getListRewrite(setterMethodBody,Block.STATEMENTS_PROPERTY);
    setterMethodBodyRewrite.insertLast(switchStatement,null);
    sourceRewriter.set(setterMethodDeclaration,MethodDeclaration.BODY_PROPERTY,setterMethodBody,null);
    contextBodyRewrite.insertLast(setterMethodDeclaration,null);
  }
  MethodDeclaration getterMethod=typeCheckElimination.getTypeFieldGetterMethod();
  if (getterMethod != null) {
    Block getterMethodBody=getterMethod.getBody();
    List<Statement> getterMethodBodyStatements=getterMethodBody.statements();
    ListRewrite getterMethodBodyRewrite=sourceRewriter.getListRewrite(getterMethodBody,Block.STATEMENTS_PROPERTY);
    if (getterMethodBodyStatements.size() == 1) {
      ReturnStatement returnStatement=contextAST.newReturnStatement();
      MethodInvocation abstractGetterMethodInvocation=contextAST.newMethodInvocation();
      sourceRewriter.set(abstractGetterMethodInvocation,MethodInvocation.NAME_PROPERTY,getterMethod.getName(),null);
      sourceRewriter.set(abstractGetterMethodInvocation,MethodInvocation.EXPRESSION_PROPERTY,typeCheckElimination.getTypeField().getName(),null);
      sourceRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,abstractGetterMethodInvocation,null);
      getterMethodBodyRewrite.replace(getterMethodBodyStatements.get(0),returnStatement,null);
    }
  }
 else {
    MethodDeclaration getterMethodDeclaration=contextAST.newMethodDeclaration();
    sourceRewriter.set(getterMethodDeclaration,MethodDeclaration.NAME_PROPERTY,contextAST.newSimpleName("String_Node_Str" + typeCheckElimination.getAbstractClassName()),null);
    VariableDeclarationFragment typeField=typeCheckElimination.getTypeField();
    Type returnType=((FieldDeclaration)typeField.getParent()).getType();
    sourceRewriter.set(getterMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,returnType,null);
    ListRewrite getterMethodModifiersRewrite=sourceRewriter.getListRewrite(getterMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
    getterMethodModifiersRewrite.insertLast(contextAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
    ReturnStatement returnStatement=contextAST.newReturnStatement();
    MethodInvocation abstractGetterMethodInvocation=contextAST.newMethodInvocation();
    sourceRewriter.set(abstractGetterMethodInvocation,MethodInvocation.NAME_PROPERTY,contextAST.newSimpleName("String_Node_Str" + typeCheckElimination.getAbstractClassName()),null);
    sourceRewriter.set(abstractGetterMethodInvocation,MethodInvocation.EXPRESSION_PROPERTY,typeCheckElimination.getTypeField().getName(),null);
    sourceRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,abstractGetterMethodInvocation,null);
    Block getterMethodBody=contextAST.newBlock();
    ListRewrite getterMethodBodyRewrite=sourceRewriter.getListRewrite(getterMethodBody,Block.STATEMENTS_PROPERTY);
    getterMethodBodyRewrite.insertLast(returnStatement,null);
    sourceRewriter.set(getterMethodDeclaration,MethodDeclaration.BODY_PROPERTY,getterMethodBody,null);
    contextBodyRewrite.insertLast(getterMethodDeclaration,null);
  }
  Block typeCheckCodeFragmentParentBlock=(Block)typeCheckElimination.getTypeCheckCodeFragment().getParent();
  ListRewrite typeCheckCodeFragmentParentBlockStatementsRewrite=sourceRewriter.getListRewrite(typeCheckCodeFragmentParentBlock,Block.STATEMENTS_PROPERTY);
  if (returnedVariable == null && !typeCheckElimination.typeCheckCodeFragmentContainsReturnStatement()) {
    MethodInvocation abstractMethodInvocation=contextAST.newMethodInvocation();
    sourceRewriter.set(abstractMethodInvocation,MethodInvocation.NAME_PROPERTY,contextAST.newSimpleName(abstractMethodName),null);
    sourceRewriter.set(abstractMethodInvocation,MethodInvocation.EXPRESSION_PROPERTY,contextAST.newSimpleName(typeCheckElimination.getTypeField().getName().getIdentifier()),null);
    ListRewrite methodInvocationArgumentsRewrite=sourceRewriter.getListRewrite(abstractMethodInvocation,MethodInvocation.ARGUMENTS_PROPERTY);
    for (    SingleVariableDeclaration abstractMethodParameter : typeCheckElimination.getAccessedParameters()) {
      if (!abstractMethodParameter.equals(returnedVariable)) {
        methodInvocationArgumentsRewrite.insertLast(abstractMethodParameter.getName(),null);
      }
    }
    for (    VariableDeclarationFragment fragment : typeCheckElimination.getAccessedLocalVariables()) {
      if (!fragment.equals(returnedVariable)) {
        methodInvocationArgumentsRewrite.insertLast(fragment.getName(),null);
      }
    }
    if (typeCheckElimination.getAccessedFields().size() > 0 || typeCheckElimination.getAssignedFields().size() > 0 || typeCheckElimination.getAccessedMethods().size() > 0 || typeCheckElimination.getSuperAccessedMethods().size() > 0) {
      methodInvocationArgumentsRewrite.insertLast(contextAST.newThisExpression(),null);
    }
    ExpressionStatement expressionStatement=contextAST.newExpressionStatement(abstractMethodInvocation);
    typeCheckCodeFragmentParentBlockStatementsRewrite.replace(typeCheckElimination.getTypeCheckCodeFragment(),expressionStatement,null);
  }
 else {
    MethodInvocation abstractMethodInvocation=contextAST.newMethodInvocation();
    sourceRewriter.set(abstractMethodInvocation,MethodInvocation.NAME_PROPERTY,contextAST.newSimpleName(abstractMethodName),null);
    sourceRewriter.set(abstractMethodInvocation,MethodInvocation.EXPRESSION_PROPERTY,contextAST.newSimpleName(typeCheckElimination.getTypeField().getName().getIdentifier()),null);
    ListRewrite methodInvocationArgumentsRewrite=sourceRewriter.getListRewrite(abstractMethodInvocation,MethodInvocation.ARGUMENTS_PROPERTY);
    if (returnedVariable != null) {
      if (returnedVariable instanceof SingleVariableDeclaration) {
        SingleVariableDeclaration singleVariableDeclaration=(SingleVariableDeclaration)returnedVariable;
        methodInvocationArgumentsRewrite.insertLast(singleVariableDeclaration.getName(),null);
      }
 else       if (returnedVariable instanceof VariableDeclarationFragment) {
        VariableDeclarationFragment variableDeclarationFragment=(VariableDeclarationFragment)returnedVariable;
        methodInvocationArgumentsRewrite.insertLast(variableDeclarationFragment.getName(),null);
      }
    }
    for (    SingleVariableDeclaration abstractMethodParameter : typeCheckElimination.getAccessedParameters()) {
      if (!abstractMethodParameter.equals(returnedVariable)) {
        methodInvocationArgumentsRewrite.insertLast(abstractMethodParameter.getName(),null);
      }
    }
    for (    VariableDeclarationFragment fragment : typeCheckElimination.getAccessedLocalVariables()) {
      if (!fragment.equals(returnedVariable)) {
        methodInvocationArgumentsRewrite.insertLast(fragment.getName(),null);
      }
    }
    if (typeCheckElimination.getAccessedFields().size() > 0 || typeCheckElimination.getAssignedFields().size() > 0 || typeCheckElimination.getAccessedMethods().size() > 0 || typeCheckElimination.getSuperAccessedMethods().size() > 0) {
      methodInvocationArgumentsRewrite.insertLast(contextAST.newThisExpression(),null);
    }
    if (returnedVariable != null) {
      Assignment assignment=contextAST.newAssignment();
      sourceRewriter.set(assignment,Assignment.OPERATOR_PROPERTY,Assignment.Operator.ASSIGN,null);
      sourceRewriter.set(assignment,Assignment.LEFT_HAND_SIDE_PROPERTY,returnedVariable.getName(),null);
      sourceRewriter.set(assignment,Assignment.RIGHT_HAND_SIDE_PROPERTY,abstractMethodInvocation,null);
      ExpressionStatement expressionStatement=contextAST.newExpressionStatement(assignment);
      typeCheckCodeFragmentParentBlockStatementsRewrite.replace(typeCheckElimination.getTypeCheckCodeFragment(),expressionStatement,null);
    }
 else {
      ReturnStatement returnStatement=contextAST.newReturnStatement();
      sourceRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,abstractMethodInvocation,null);
      typeCheckCodeFragmentParentBlockStatementsRewrite.replace(typeCheckElimination.getTypeCheckCodeFragment(),returnStatement,null);
    }
  }
  generateGettersForAccessedFields();
  generateSettersForAssignedFields();
  setPublicModifierToStaticFields();
  setPublicModifierToAccessedMethods();
  ITextFileBufferManager bufferManager=FileBuffers.getTextFileBufferManager();
  ITextFileBuffer sourceTextFileBuffer=bufferManager.getTextFileBuffer(sourceFile.getFullPath(),LocationKind.IFILE);
  IDocument sourceDocument=sourceTextFileBuffer.getDocument();
  TextEdit sourceEdit=sourceRewriter.rewriteAST(sourceDocument,null);
  try {
    UndoEdit sourceUndoEdit=sourceEdit.apply(sourceDocument,UndoEdit.CREATE_UNDO);
    undoRefactoring.put(sourceFile,sourceDocument,sourceUndoEdit);
  }
 catch (  MalformedTreeException e) {
    e.printStackTrace();
  }
catch (  BadLocationException e) {
    e.printStackTrace();
  }
}

Fixed version (ground truth):
private void modifyContext(){
  AST contextAST=sourceTypeDeclaration.getAST();
  ListRewrite contextBodyRewrite=sourceRewriter.getListRewrite(sourceTypeDeclaration,TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
  VariableDeclarationFragment typeFragment=contextAST.newVariableDeclarationFragment();
  sourceRewriter.set(typeFragment,VariableDeclarationFragment.NAME_PROPERTY,typeCheckElimination.getTypeField().getName(),null);
  FieldDeclaration typeFieldDeclaration=contextAST.newFieldDeclaration(typeFragment);
  sourceRewriter.set(typeFieldDeclaration,FieldDeclaration.TYPE_PROPERTY,contextAST.newSimpleName(typeCheckElimination.getAbstractClassName()),null);
  ListRewrite typeFieldDeclrationModifiersRewrite=sourceRewriter.getListRewrite(typeFieldDeclaration,FieldDeclaration.MODIFIERS2_PROPERTY);
  typeFieldDeclrationModifiersRewrite.insertLast(contextAST.newModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD),null);
  contextBodyRewrite.insertFirst(typeFieldDeclaration,null);
  FieldDeclaration[] fieldDeclarations=sourceTypeDeclaration.getFields();
  for (  FieldDeclaration fieldDeclaration : fieldDeclarations) {
    List<VariableDeclarationFragment> fragments=fieldDeclaration.fragments();
    for (    VariableDeclarationFragment fragment : fragments) {
      if (fragment.equals(typeCheckElimination.getTypeField())) {
        if (fragments.size() == 1) {
          contextBodyRewrite.remove(fragment.getParent(),null);
        }
 else {
          ListRewrite fragmentRewrite=sourceRewriter.getListRewrite(fragment.getParent(),FieldDeclaration.FRAGMENTS_PROPERTY);
          fragmentRewrite.remove(fragment,null);
        }
      }
    }
  }
  modifyTypeFieldAssignmentsInContextClass();
  modifyTypeFieldAccessesInContextClass();
  MethodDeclaration setterMethod=typeCheckElimination.getTypeFieldSetterMethod();
  SwitchStatement switchStatement=contextAST.newSwitchStatement();
  List<SimpleName> staticFieldNames=typeCheckElimination.getStaticFields();
  List<String> subclassNames=typeCheckElimination.getSubclassNames();
  ListRewrite switchStatementStatementsRewrite=sourceRewriter.getListRewrite(switchStatement,SwitchStatement.STATEMENTS_PROPERTY);
  int i=0;
  for (  SimpleName staticFieldName : staticFieldNames) {
    SwitchCase switchCase=contextAST.newSwitchCase();
    IBinding staticFieldNameBinding=staticFieldName.resolveBinding();
    String staticFieldNameDeclaringClass=null;
    boolean isEnumConstant=false;
    if (staticFieldNameBinding.getKind() == IBinding.VARIABLE) {
      IVariableBinding staticFieldNameVariableBinding=(IVariableBinding)staticFieldNameBinding;
      isEnumConstant=staticFieldNameVariableBinding.isEnumConstant();
      if (!sourceTypeDeclaration.resolveBinding().isEqualTo(staticFieldNameVariableBinding.getDeclaringClass())) {
        staticFieldNameDeclaringClass=staticFieldNameVariableBinding.getDeclaringClass().getName();
      }
    }
    if (staticFieldNameDeclaringClass == null || isEnumConstant) {
      sourceRewriter.set(switchCase,SwitchCase.EXPRESSION_PROPERTY,staticFieldName,null);
    }
 else {
      FieldAccess fieldAccess=contextAST.newFieldAccess();
      sourceRewriter.set(fieldAccess,FieldAccess.EXPRESSION_PROPERTY,contextAST.newSimpleName(staticFieldNameDeclaringClass),null);
      sourceRewriter.set(fieldAccess,FieldAccess.NAME_PROPERTY,staticFieldName,null);
      sourceRewriter.set(switchCase,SwitchCase.EXPRESSION_PROPERTY,fieldAccess,null);
    }
    switchStatementStatementsRewrite.insertLast(switchCase,null);
    Assignment assignment=contextAST.newAssignment();
    sourceRewriter.set(assignment,Assignment.OPERATOR_PROPERTY,Assignment.Operator.ASSIGN,null);
    FieldAccess typeFieldAccess=contextAST.newFieldAccess();
    sourceRewriter.set(typeFieldAccess,FieldAccess.EXPRESSION_PROPERTY,contextAST.newThisExpression(),null);
    sourceRewriter.set(typeFieldAccess,FieldAccess.NAME_PROPERTY,typeCheckElimination.getTypeField().getName(),null);
    sourceRewriter.set(assignment,Assignment.LEFT_HAND_SIDE_PROPERTY,typeFieldAccess,null);
    ClassInstanceCreation classInstanceCreation=contextAST.newClassInstanceCreation();
    sourceRewriter.set(classInstanceCreation,ClassInstanceCreation.TYPE_PROPERTY,contextAST.newSimpleName(subclassNames.get(i)),null);
    sourceRewriter.set(assignment,Assignment.RIGHT_HAND_SIDE_PROPERTY,classInstanceCreation,null);
    switchStatementStatementsRewrite.insertLast(contextAST.newExpressionStatement(assignment),null);
    switchStatementStatementsRewrite.insertLast(contextAST.newBreakStatement(),null);
    i++;
  }
  for (  SimpleName staticFieldName : additionalStaticFields.keySet()) {
    SwitchCase switchCase=contextAST.newSwitchCase();
    IBinding staticFieldNameBinding=staticFieldName.resolveBinding();
    String staticFieldNameDeclaringClass=null;
    boolean isEnumConstant=false;
    if (staticFieldNameBinding.getKind() == IBinding.VARIABLE) {
      IVariableBinding staticFieldNameVariableBinding=(IVariableBinding)staticFieldNameBinding;
      isEnumConstant=staticFieldNameVariableBinding.isEnumConstant();
      if (!sourceTypeDeclaration.resolveBinding().isEqualTo(staticFieldNameVariableBinding.getDeclaringClass())) {
        staticFieldNameDeclaringClass=staticFieldNameVariableBinding.getDeclaringClass().getName();
      }
    }
    if (staticFieldNameDeclaringClass == null || isEnumConstant) {
      sourceRewriter.set(switchCase,SwitchCase.EXPRESSION_PROPERTY,staticFieldName,null);
    }
 else {
      FieldAccess fieldAccess=contextAST.newFieldAccess();
      sourceRewriter.set(fieldAccess,FieldAccess.EXPRESSION_PROPERTY,contextAST.newSimpleName(staticFieldNameDeclaringClass),null);
      sourceRewriter.set(fieldAccess,FieldAccess.NAME_PROPERTY,staticFieldName,null);
      sourceRewriter.set(switchCase,SwitchCase.EXPRESSION_PROPERTY,fieldAccess,null);
    }
    switchStatementStatementsRewrite.insertLast(switchCase,null);
    Assignment assignment=contextAST.newAssignment();
    sourceRewriter.set(assignment,Assignment.OPERATOR_PROPERTY,Assignment.Operator.ASSIGN,null);
    FieldAccess typeFieldAccess=contextAST.newFieldAccess();
    sourceRewriter.set(typeFieldAccess,FieldAccess.EXPRESSION_PROPERTY,contextAST.newThisExpression(),null);
    sourceRewriter.set(typeFieldAccess,FieldAccess.NAME_PROPERTY,typeCheckElimination.getTypeField().getName(),null);
    sourceRewriter.set(assignment,Assignment.LEFT_HAND_SIDE_PROPERTY,typeFieldAccess,null);
    ClassInstanceCreation classInstanceCreation=contextAST.newClassInstanceCreation();
    sourceRewriter.set(classInstanceCreation,ClassInstanceCreation.TYPE_PROPERTY,contextAST.newSimpleName(additionalStaticFields.get(staticFieldName)),null);
    sourceRewriter.set(assignment,Assignment.RIGHT_HAND_SIDE_PROPERTY,classInstanceCreation,null);
    switchStatementStatementsRewrite.insertLast(contextAST.newExpressionStatement(assignment),null);
    switchStatementStatementsRewrite.insertLast(contextAST.newBreakStatement(),null);
  }
  SwitchCase switchCase=contextAST.newSwitchCase();
  sourceRewriter.set(switchCase,SwitchCase.EXPRESSION_PROPERTY,null,null);
  switchStatementStatementsRewrite.insertLast(switchCase,null);
  Assignment nullAssignment=contextAST.newAssignment();
  sourceRewriter.set(nullAssignment,Assignment.OPERATOR_PROPERTY,Assignment.Operator.ASSIGN,null);
  FieldAccess typeFieldAccess=contextAST.newFieldAccess();
  sourceRewriter.set(typeFieldAccess,FieldAccess.EXPRESSION_PROPERTY,contextAST.newThisExpression(),null);
  sourceRewriter.set(typeFieldAccess,FieldAccess.NAME_PROPERTY,typeCheckElimination.getTypeField().getName(),null);
  sourceRewriter.set(nullAssignment,Assignment.LEFT_HAND_SIDE_PROPERTY,typeFieldAccess,null);
  sourceRewriter.set(nullAssignment,Assignment.RIGHT_HAND_SIDE_PROPERTY,contextAST.newNullLiteral(),null);
  switchStatementStatementsRewrite.insertLast(contextAST.newExpressionStatement(nullAssignment),null);
  switchStatementStatementsRewrite.insertLast(contextAST.newBreakStatement(),null);
  if (setterMethod != null) {
    List<SingleVariableDeclaration> setterMethodParameters=setterMethod.parameters();
    if (setterMethodParameters.size() == 1) {
      sourceRewriter.set(switchStatement,SwitchStatement.EXPRESSION_PROPERTY,setterMethodParameters.get(0).getName(),null);
    }
    Block setterMethodBody=setterMethod.getBody();
    List<Statement> setterMethodBodyStatements=setterMethodBody.statements();
    ListRewrite setterMethodBodyRewrite=sourceRewriter.getListRewrite(setterMethodBody,Block.STATEMENTS_PROPERTY);
    if (setterMethodBodyStatements.size() == 1) {
      setterMethodBodyRewrite.replace(setterMethodBodyStatements.get(0),switchStatement,null);
    }
  }
 else {
    MethodDeclaration setterMethodDeclaration=contextAST.newMethodDeclaration();
    sourceRewriter.set(setterMethodDeclaration,MethodDeclaration.NAME_PROPERTY,contextAST.newSimpleName("String_Node_Str" + typeCheckElimination.getAbstractClassName()),null);
    sourceRewriter.set(setterMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,contextAST.newPrimitiveType(PrimitiveType.VOID),null);
    ListRewrite setterMethodModifiersRewrite=sourceRewriter.getListRewrite(setterMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
    setterMethodModifiersRewrite.insertLast(contextAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
    ListRewrite setterMethodParameterRewrite=sourceRewriter.getListRewrite(setterMethodDeclaration,MethodDeclaration.PARAMETERS_PROPERTY);
    SingleVariableDeclaration parameter=contextAST.newSingleVariableDeclaration();
    VariableDeclarationFragment typeField=typeCheckElimination.getTypeField();
    Type parameterType=((FieldDeclaration)typeField.getParent()).getType();
    sourceRewriter.set(parameter,SingleVariableDeclaration.TYPE_PROPERTY,parameterType,null);
    sourceRewriter.set(parameter,SingleVariableDeclaration.NAME_PROPERTY,typeField.getName(),null);
    setterMethodParameterRewrite.insertLast(parameter,null);
    sourceRewriter.set(switchStatement,SwitchStatement.EXPRESSION_PROPERTY,typeField.getName(),null);
    Block setterMethodBody=contextAST.newBlock();
    ListRewrite setterMethodBodyRewrite=sourceRewriter.getListRewrite(setterMethodBody,Block.STATEMENTS_PROPERTY);
    setterMethodBodyRewrite.insertLast(switchStatement,null);
    sourceRewriter.set(setterMethodDeclaration,MethodDeclaration.BODY_PROPERTY,setterMethodBody,null);
    contextBodyRewrite.insertLast(setterMethodDeclaration,null);
  }
  MethodDeclaration getterMethod=typeCheckElimination.getTypeFieldGetterMethod();
  if (getterMethod != null) {
    Block getterMethodBody=getterMethod.getBody();
    List<Statement> getterMethodBodyStatements=getterMethodBody.statements();
    ListRewrite getterMethodBodyRewrite=sourceRewriter.getListRewrite(getterMethodBody,Block.STATEMENTS_PROPERTY);
    if (getterMethodBodyStatements.size() == 1) {
      ReturnStatement returnStatement=contextAST.newReturnStatement();
      MethodInvocation abstractGetterMethodInvocation=contextAST.newMethodInvocation();
      sourceRewriter.set(abstractGetterMethodInvocation,MethodInvocation.NAME_PROPERTY,getterMethod.getName(),null);
      sourceRewriter.set(abstractGetterMethodInvocation,MethodInvocation.EXPRESSION_PROPERTY,typeCheckElimination.getTypeField().getName(),null);
      sourceRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,abstractGetterMethodInvocation,null);
      getterMethodBodyRewrite.replace(getterMethodBodyStatements.get(0),returnStatement,null);
    }
  }
 else {
    MethodDeclaration getterMethodDeclaration=contextAST.newMethodDeclaration();
    sourceRewriter.set(getterMethodDeclaration,MethodDeclaration.NAME_PROPERTY,contextAST.newSimpleName("String_Node_Str" + typeCheckElimination.getAbstractClassName()),null);
    VariableDeclarationFragment typeField=typeCheckElimination.getTypeField();
    Type returnType=((FieldDeclaration)typeField.getParent()).getType();
    sourceRewriter.set(getterMethodDeclaration,MethodDeclaration.RETURN_TYPE2_PROPERTY,returnType,null);
    ListRewrite getterMethodModifiersRewrite=sourceRewriter.getListRewrite(getterMethodDeclaration,MethodDeclaration.MODIFIERS2_PROPERTY);
    getterMethodModifiersRewrite.insertLast(contextAST.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD),null);
    ReturnStatement returnStatement=contextAST.newReturnStatement();
    MethodInvocation abstractGetterMethodInvocation=contextAST.newMethodInvocation();
    sourceRewriter.set(abstractGetterMethodInvocation,MethodInvocation.NAME_PROPERTY,contextAST.newSimpleName("String_Node_Str" + typeCheckElimination.getAbstractClassName()),null);
    sourceRewriter.set(abstractGetterMethodInvocation,MethodInvocation.EXPRESSION_PROPERTY,typeCheckElimination.getTypeField().getName(),null);
    sourceRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,abstractGetterMethodInvocation,null);
    Block getterMethodBody=contextAST.newBlock();
    ListRewrite getterMethodBodyRewrite=sourceRewriter.getListRewrite(getterMethodBody,Block.STATEMENTS_PROPERTY);
    getterMethodBodyRewrite.insertLast(returnStatement,null);
    sourceRewriter.set(getterMethodDeclaration,MethodDeclaration.BODY_PROPERTY,getterMethodBody,null);
    contextBodyRewrite.insertLast(getterMethodDeclaration,null);
  }
  Block typeCheckCodeFragmentParentBlock=(Block)typeCheckElimination.getTypeCheckCodeFragment().getParent();
  ListRewrite typeCheckCodeFragmentParentBlockStatementsRewrite=sourceRewriter.getListRewrite(typeCheckCodeFragmentParentBlock,Block.STATEMENTS_PROPERTY);
  if (returnedVariable == null && !typeCheckElimination.typeCheckCodeFragmentContainsReturnStatement()) {
    MethodInvocation abstractMethodInvocation=contextAST.newMethodInvocation();
    sourceRewriter.set(abstractMethodInvocation,MethodInvocation.NAME_PROPERTY,contextAST.newSimpleName(abstractMethodName),null);
    sourceRewriter.set(abstractMethodInvocation,MethodInvocation.EXPRESSION_PROPERTY,contextAST.newSimpleName(typeCheckElimination.getTypeField().getName().getIdentifier()),null);
    ListRewrite methodInvocationArgumentsRewrite=sourceRewriter.getListRewrite(abstractMethodInvocation,MethodInvocation.ARGUMENTS_PROPERTY);
    for (    SingleVariableDeclaration abstractMethodParameter : typeCheckElimination.getAccessedParameters()) {
      if (!abstractMethodParameter.equals(returnedVariable)) {
        methodInvocationArgumentsRewrite.insertLast(abstractMethodParameter.getName(),null);
      }
    }
    for (    VariableDeclarationFragment fragment : typeCheckElimination.getAccessedLocalVariables()) {
      if (!fragment.equals(returnedVariable)) {
        methodInvocationArgumentsRewrite.insertLast(fragment.getName(),null);
      }
    }
    if (typeCheckElimination.getAccessedFields().size() > 0 || typeCheckElimination.getAssignedFields().size() > 0 || typeCheckElimination.getAccessedMethods().size() > 0 || typeCheckElimination.getSuperAccessedMethods().size() > 0) {
      methodInvocationArgumentsRewrite.insertLast(contextAST.newThisExpression(),null);
    }
    ExpressionStatement expressionStatement=contextAST.newExpressionStatement(abstractMethodInvocation);
    typeCheckCodeFragmentParentBlockStatementsRewrite.replace(typeCheckElimination.getTypeCheckCodeFragment(),expressionStatement,null);
  }
 else {
    MethodInvocation abstractMethodInvocation=contextAST.newMethodInvocation();
    sourceRewriter.set(abstractMethodInvocation,MethodInvocation.NAME_PROPERTY,contextAST.newSimpleName(abstractMethodName),null);
    sourceRewriter.set(abstractMethodInvocation,MethodInvocation.EXPRESSION_PROPERTY,contextAST.newSimpleName(typeCheckElimination.getTypeField().getName().getIdentifier()),null);
    ListRewrite methodInvocationArgumentsRewrite=sourceRewriter.getListRewrite(abstractMethodInvocation,MethodInvocation.ARGUMENTS_PROPERTY);
    if (returnedVariable != null) {
      if (returnedVariable instanceof SingleVariableDeclaration) {
        SingleVariableDeclaration singleVariableDeclaration=(SingleVariableDeclaration)returnedVariable;
        methodInvocationArgumentsRewrite.insertLast(singleVariableDeclaration.getName(),null);
      }
 else       if (returnedVariable instanceof VariableDeclarationFragment) {
        VariableDeclarationFragment variableDeclarationFragment=(VariableDeclarationFragment)returnedVariable;
        methodInvocationArgumentsRewrite.insertLast(variableDeclarationFragment.getName(),null);
      }
    }
    for (    SingleVariableDeclaration abstractMethodParameter : typeCheckElimination.getAccessedParameters()) {
      if (!abstractMethodParameter.equals(returnedVariable)) {
        methodInvocationArgumentsRewrite.insertLast(abstractMethodParameter.getName(),null);
      }
    }
    for (    VariableDeclarationFragment fragment : typeCheckElimination.getAccessedLocalVariables()) {
      if (!fragment.equals(returnedVariable)) {
        methodInvocationArgumentsRewrite.insertLast(fragment.getName(),null);
      }
    }
    if (typeCheckElimination.getAccessedFields().size() > 0 || typeCheckElimination.getAssignedFields().size() > 0 || typeCheckElimination.getAccessedMethods().size() > 0 || typeCheckElimination.getSuperAccessedMethods().size() > 0) {
      methodInvocationArgumentsRewrite.insertLast(contextAST.newThisExpression(),null);
    }
    if (returnedVariable != null) {
      Assignment assignment=contextAST.newAssignment();
      sourceRewriter.set(assignment,Assignment.OPERATOR_PROPERTY,Assignment.Operator.ASSIGN,null);
      sourceRewriter.set(assignment,Assignment.LEFT_HAND_SIDE_PROPERTY,returnedVariable.getName(),null);
      sourceRewriter.set(assignment,Assignment.RIGHT_HAND_SIDE_PROPERTY,abstractMethodInvocation,null);
      ExpressionStatement expressionStatement=contextAST.newExpressionStatement(assignment);
      typeCheckCodeFragmentParentBlockStatementsRewrite.replace(typeCheckElimination.getTypeCheckCodeFragment(),expressionStatement,null);
    }
 else {
      ReturnStatement returnStatement=contextAST.newReturnStatement();
      sourceRewriter.set(returnStatement,ReturnStatement.EXPRESSION_PROPERTY,abstractMethodInvocation,null);
      typeCheckCodeFragmentParentBlockStatementsRewrite.replace(typeCheckElimination.getTypeCheckCodeFragment(),returnStatement,null);
    }
  }
  generateGettersForAccessedFields();
  generateSettersForAssignedFields();
  setPublicModifierToStaticFields();
  setPublicModifierToAccessedMethods();
  ITextFileBufferManager bufferManager=FileBuffers.getTextFileBufferManager();
  ITextFileBuffer sourceTextFileBuffer=bufferManager.getTextFileBuffer(sourceFile.getFullPath(),LocationKind.IFILE);
  IDocument sourceDocument=sourceTextFileBuffer.getDocument();
  TextEdit sourceEdit=sourceRewriter.rewriteAST(sourceDocument,null);
  try {
    UndoEdit sourceUndoEdit=sourceEdit.apply(sourceDocument,UndoEdit.CREATE_UNDO);
    undoRefactoring.put(sourceFile,sourceDocument,sourceUndoEdit);
  }
 catch (  MalformedTreeException e) {
    e.printStackTrace();
  }
catch (  BadLocationException e) {
    e.printStackTrace();
  }
}