private RefactoringStatus checkExpression() throws JavaModelException {
    RefactoringStatus result = new RefactoringStatus();
    result.merge(checkExpressionBinding());
    if (result.hasFatalError()) return result;
    checkAllStaticFinal();

    IExpressionFragment selectedExpression = getSelectedExpression();
    Expression associatedExpression = selectedExpression.getAssociatedExpression();
    if (associatedExpression instanceof NullLiteral)
      result.merge(
          RefactoringStatus.createFatalErrorStatus(
              RefactoringCoreMessages.ExtractConstantRefactoring_null_literals));
    else if (!ConstantChecks.isLoadTimeConstant(selectedExpression))
      result.merge(
          RefactoringStatus.createFatalErrorStatus(
              RefactoringCoreMessages.ExtractConstantRefactoring_not_load_time_constant));
    else if (associatedExpression instanceof SimpleName) {
      if (associatedExpression.getParent() instanceof QualifiedName
              && associatedExpression.getLocationInParent() == QualifiedName.NAME_PROPERTY
          || associatedExpression.getParent() instanceof FieldAccess
              && associatedExpression.getLocationInParent() == FieldAccess.NAME_PROPERTY)
        return RefactoringStatus.createFatalErrorStatus(
            RefactoringCoreMessages.ExtractConstantRefactoring_select_expression);
    }

    return result;
  }
 private Type getConstantType() throws JavaModelException {
   if (fConstantTypeCache == null) {
     IExpressionFragment fragment = getSelectedExpression();
     ITypeBinding typeBinding = guessBindingForReference(fragment.getAssociatedExpression());
     AST ast = fCuRewrite.getAST();
     typeBinding = Bindings.normalizeForDeclarationUse(typeBinding, ast);
     ImportRewrite importRewrite = fCuRewrite.getImportRewrite();
     ImportRewriteContext context =
         new ContextSensitiveImportRewriteContext(
             fCuRewrite.getRoot(), fSelectionStart, importRewrite);
     fConstantTypeCache = importRewrite.addImport(typeBinding, ast, context);
   }
   return fConstantTypeCache;
 }
 private String[] getExcludedVariableNames() {
   if (fExcludedVariableNames == null) {
     try {
       IExpressionFragment expr = getSelectedExpression();
       Collection<String> takenNames =
           new ScopeAnalyzer(fCuRewrite.getRoot())
               .getUsedVariableNames(expr.getStartPosition(), expr.getLength());
       fExcludedVariableNames = takenNames.toArray(new String[takenNames.size()]);
     } catch (JavaModelException e) {
       fExcludedVariableNames = new String[0];
     }
   }
   return fExcludedVariableNames;
 }
  /* bd is a static field declaration or static initializer */
  private static boolean depends(IExpressionFragment selected, BodyDeclaration bd) {
    /* We currently consider selected to depend on bd only if db includes a declaration
     * of a static field on which selected depends.
     *
     * A more accurate strategy might be to also check if bd contains (or is) a
     * static initializer containing code which changes the value of a static field on
     * which selected depends.  However, if a static is written to multiple times within
     * during class initialization, it is difficult to predict which value should be used.
     * This would depend on which value is used by expressions instances for which the new
     * constant will be substituted, and there may be many of these; in each, the
     * static field in question may have taken on a different value (if some of these uses
     * occur within static initializers).
     */

    if (bd instanceof FieldDeclaration) {
      FieldDeclaration fieldDecl = (FieldDeclaration) bd;
      for (Iterator<VariableDeclarationFragment> fragments = fieldDecl.fragments().iterator();
          fragments.hasNext(); ) {
        VariableDeclarationFragment fragment = fragments.next();
        SimpleName staticFieldName = fragment.getName();
        if (selected.getSubFragmentsMatching(
                    ASTFragmentFactory.createFragmentForFullSubtree(staticFieldName))
                .length
            != 0) return true;
      }
    }
    return false;
  }
  //	 !!! -- same as in ExtractTempRefactoring
  private boolean isLiteralNodeSelected() throws JavaModelException {
    IExpressionFragment fragment = getSelectedExpression();
    if (fragment == null) return false;
    Expression expression = fragment.getAssociatedExpression();
    if (expression == null) return false;
    switch (expression.getNodeType()) {
      case ASTNode.BOOLEAN_LITERAL:
      case ASTNode.CHARACTER_LITERAL:
      case ASTNode.NULL_LITERAL:
      case ASTNode.NUMBER_LITERAL:
        return true;

      default:
        return false;
    }
  }
  private IExpressionFragment getSelectedExpression() throws JavaModelException {
    if (fSelectedExpression != null) return fSelectedExpression;

    IASTFragment selectedFragment =
        ASTFragmentFactory.createFragmentForSourceRange(
            new SourceRange(fSelectionStart, fSelectionLength), fCuRewrite.getRoot(), fCu);

    if (selectedFragment instanceof IExpressionFragment
        && !Checks.isInsideJavadoc(selectedFragment.getAssociatedNode())) {
      fSelectedExpression = (IExpressionFragment) selectedFragment;
    }

    if (fSelectedExpression != null
        && Checks.isEnumCase(fSelectedExpression.getAssociatedExpression().getParent())) {
      fSelectedExpression = null;
    }

    return fSelectedExpression;
  }
  private ExtractConstantDescriptor createRefactoringDescriptor() {
    final Map<String, String> arguments = new HashMap<>();
    String project = null;
    IJavaProject javaProject = fCu.getJavaProject();
    if (javaProject != null) project = javaProject.getElementName();
    int flags =
        JavaRefactoringDescriptor.JAR_REFACTORING | JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
    if (JdtFlags.getVisibilityCode(fVisibility) != Modifier.PRIVATE)
      flags |= RefactoringDescriptor.STRUCTURAL_CHANGE;

    final String expression = ASTNodes.asString(fSelectedExpression.getAssociatedExpression());
    final String description =
        Messages.format(
            RefactoringCoreMessages.ExtractConstantRefactoring_descriptor_description_short,
            BasicElementLabels.getJavaElementName(fConstantName));
    final String header =
        Messages.format(
            RefactoringCoreMessages.ExtractConstantRefactoring_descriptor_description,
            new String[] {
              BasicElementLabels.getJavaElementName(fConstantName),
              BasicElementLabels.getJavaCodeString(expression)
            });
    final JDTRefactoringDescriptorComment comment =
        new JDTRefactoringDescriptorComment(project, this, header);
    comment.addSetting(
        Messages.format(
            RefactoringCoreMessages.ExtractConstantRefactoring_constant_name_pattern,
            BasicElementLabels.getJavaElementName(fConstantName)));
    comment.addSetting(
        Messages.format(
            RefactoringCoreMessages.ExtractConstantRefactoring_constant_expression_pattern,
            BasicElementLabels.getJavaCodeString(expression)));
    String visibility = fVisibility;
    if ("".equals(visibility)) // $NON-NLS-1$
    visibility = RefactoringCoreMessages.ExtractConstantRefactoring_default_visibility;
    comment.addSetting(
        Messages.format(
            RefactoringCoreMessages.ExtractConstantRefactoring_visibility_pattern, visibility));
    if (fReplaceAllOccurrences)
      comment.addSetting(RefactoringCoreMessages.ExtractConstantRefactoring_replace_occurrences);
    if (fQualifyReferencesWithDeclaringClassName)
      comment.addSetting(RefactoringCoreMessages.ExtractConstantRefactoring_qualify_references);
    arguments.put(
        JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT,
        JavaRefactoringDescriptorUtil.elementToHandle(project, fCu));
    arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME, fConstantName);
    arguments.put(
        JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION,
        new Integer(fSelectionStart).toString()
            + " "
            + new Integer(fSelectionLength).toString()); // $NON-NLS-1$
    arguments.put(ATTRIBUTE_REPLACE, Boolean.valueOf(fReplaceAllOccurrences).toString());
    arguments.put(
        ATTRIBUTE_QUALIFY, Boolean.valueOf(fQualifyReferencesWithDeclaringClassName).toString());
    arguments.put(
        ATTRIBUTE_VISIBILITY, new Integer(JdtFlags.getVisibilityCode(fVisibility)).toString());

    ExtractConstantDescriptor descriptor =
        RefactoringSignatureDescriptorFactory.createExtractConstantDescriptor(
            project, description, comment.asString(), arguments, flags);
    return descriptor;
  }
  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);
    }
  }