private ASTRewrite doAddField(CompilationUnit astRoot) {
    SimpleName node = fOriginalNode;
    boolean isInDifferentCU = false;

    ASTNode newTypeDecl = astRoot.findDeclaringNode(fSenderBinding);
    if (newTypeDecl == null) {
      astRoot = ASTResolving.createQuickFixAST(getCompilationUnit(), null);
      newTypeDecl = astRoot.findDeclaringNode(fSenderBinding.getKey());
      isInDifferentCU = true;
    }
    ImportRewrite imports = createImportRewrite(astRoot);
    ImportRewriteContext importRewriteContext =
        new ContextSensitiveImportRewriteContext(
            ASTResolving.findParentBodyDeclaration(node), imports);

    if (newTypeDecl != null) {
      AST ast = newTypeDecl.getAST();

      ASTRewrite rewrite = ASTRewrite.create(ast);

      VariableDeclarationFragment fragment = ast.newVariableDeclarationFragment();
      fragment.setName(ast.newSimpleName(node.getIdentifier()));

      Type type = evaluateVariableType(ast, imports, importRewriteContext, fSenderBinding);

      FieldDeclaration newDecl = ast.newFieldDeclaration(fragment);
      newDecl.setType(type);
      newDecl
          .modifiers()
          .addAll(ASTNodeFactory.newModifiers(ast, evaluateFieldModifiers(newTypeDecl)));

      if (fSenderBinding.isInterface() || fVariableKind == CONST_FIELD) {
        fragment.setInitializer(ASTNodeFactory.newDefaultExpression(ast, type, 0));
      }

      ChildListPropertyDescriptor property = ASTNodes.getBodyDeclarationsProperty(newTypeDecl);
      List<BodyDeclaration> decls =
          ASTNodes.<BodyDeclaration>getChildListProperty(newTypeDecl, property);

      int maxOffset = isInDifferentCU ? -1 : node.getStartPosition();

      int insertIndex = findFieldInsertIndex(decls, newDecl, maxOffset);

      ListRewrite listRewriter = rewrite.getListRewrite(newTypeDecl, property);
      listRewriter.insertAt(newDecl, insertIndex, null);

      ModifierCorrectionSubProcessor.installLinkedVisibilityProposals(
          getLinkedProposalModel(), rewrite, newDecl.modifiers(), fSenderBinding.isInterface());

      addLinkedPosition(rewrite.track(newDecl.getType()), false, KEY_TYPE);
      if (!isInDifferentCU) {
        addLinkedPosition(rewrite.track(node), true, KEY_NAME);
      }
      addLinkedPosition(rewrite.track(fragment.getName()), false, KEY_NAME);

      if (fragment.getInitializer() != null) {
        addLinkedPosition(rewrite.track(fragment.getInitializer()), false, KEY_INITIALIZER);
      }
      return rewrite;
    }
    return null;
  }
  private void createConstantDeclaration() throws CoreException {
    Type type = getConstantType();

    IExpressionFragment fragment = getSelectedExpression();
    Expression initializer =
        getSelectedExpression().createCopyTarget(fCuRewrite.getASTRewrite(), true);

    AST ast = fCuRewrite.getAST();
    VariableDeclarationFragment variableDeclarationFragment = ast.newVariableDeclarationFragment();
    variableDeclarationFragment.setName(ast.newSimpleName(fConstantName));
    variableDeclarationFragment.setInitializer(initializer);

    FieldDeclaration fieldDeclaration = ast.newFieldDeclaration(variableDeclarationFragment);
    fieldDeclaration.setType(type);
    Modifier.ModifierKeyword accessModifier = Modifier.ModifierKeyword.toKeyword(fVisibility);
    if (accessModifier != null) fieldDeclaration.modifiers().add(ast.newModifier(accessModifier));
    fieldDeclaration.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.STATIC_KEYWORD));
    fieldDeclaration.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD));

    boolean createComments =
        JavaPreferencesSettings.getCodeGenerationSettings(fCu.getJavaProject()).createComments;
    if (createComments) {
      String comment =
          CodeGeneration.getFieldComment(
              fCu, getConstantTypeName(), fConstantName, StubUtility.getLineDelimiterUsed(fCu));
      if (comment != null && comment.length() > 0) {
        Javadoc doc =
            (Javadoc) fCuRewrite.getASTRewrite().createStringPlaceholder(comment, ASTNode.JAVADOC);
        fieldDeclaration.setJavadoc(doc);
      }
    }

    AbstractTypeDeclaration parent = getContainingTypeDeclarationNode();
    ListRewrite listRewrite =
        fCuRewrite.getASTRewrite().getListRewrite(parent, parent.getBodyDeclarationsProperty());
    TextEditGroup msg =
        fCuRewrite.createGroupDescription(
            RefactoringCoreMessages.ExtractConstantRefactoring_declare_constant);
    if (insertFirst()) {
      listRewrite.insertFirst(fieldDeclaration, msg);
    } else {
      listRewrite.insertAfter(fieldDeclaration, getNodeToInsertConstantDeclarationAfter(), msg);
    }

    if (fLinkedProposalModel != null) {
      ASTRewrite rewrite = fCuRewrite.getASTRewrite();
      LinkedProposalPositionGroup nameGroup = fLinkedProposalModel.getPositionGroup(KEY_NAME, true);
      nameGroup.addPosition(rewrite.track(variableDeclarationFragment.getName()), true);

      String[] nameSuggestions = guessConstantNames();
      if (nameSuggestions.length > 0 && !nameSuggestions[0].equals(fConstantName)) {
        nameGroup.addProposal(fConstantName, null, nameSuggestions.length + 1);
      }
      for (int i = 0; i < nameSuggestions.length; i++) {
        nameGroup.addProposal(nameSuggestions[i], null, nameSuggestions.length - i);
      }

      LinkedProposalPositionGroup typeGroup = fLinkedProposalModel.getPositionGroup(KEY_TYPE, true);
      typeGroup.addPosition(rewrite.track(type), true);

      ITypeBinding typeBinding = guessBindingForReference(fragment.getAssociatedExpression());
      if (typeBinding != null) {
        ITypeBinding[] relaxingTypes = ASTResolving.getNarrowingTypes(ast, typeBinding);
        for (int i = 0; i < relaxingTypes.length; i++) {
          typeGroup.addProposal(relaxingTypes[i], fCuRewrite.getCu(), relaxingTypes.length - i);
        }
      }
      boolean isInterface =
          parent.resolveBinding() != null && parent.resolveBinding().isInterface();
      ModifierCorrectionSubProcessor.installLinkedVisibilityProposals(
          fLinkedProposalModel, rewrite, fieldDeclaration.modifiers(), isInterface);
    }
  }