private static boolean canAddFinal(IBinding binding, ASTNode declNode) {
    if (!(binding instanceof IVariableBinding)) return false;

    IVariableBinding varbinding = (IVariableBinding) binding;
    int modifiers = varbinding.getModifiers();
    if (Modifier.isFinal(modifiers)
        || Modifier.isVolatile(modifiers)
        || Modifier.isTransient(modifiers)) return false;

    ASTNode parent = ASTNodes.getParent(declNode, VariableDeclarationExpression.class);
    if (parent != null && ((VariableDeclarationExpression) parent).fragments().size() > 1)
      return false;

    if (varbinding.isField() && !Modifier.isPrivate(modifiers)) return false;

    if (varbinding.isParameter()) {
      ASTNode varDecl = declNode.getParent();
      if (varDecl instanceof MethodDeclaration) {
        MethodDeclaration declaration = (MethodDeclaration) varDecl;
        if (declaration.getBody() == null) return false;
      }
    }

    return true;
  }
 /**
  * Returns the type to which the new constant will be added to. It is the first non-anonymous
  * parent.
  *
  * @return the type to add the new constant to
  * @throws JavaModelException shouldn't happen
  */
 private AbstractTypeDeclaration getContainingTypeDeclarationNode() throws JavaModelException {
   AbstractTypeDeclaration result =
       (AbstractTypeDeclaration)
           ASTNodes.getParent(
               getSelectedExpression().getAssociatedNode(), AbstractTypeDeclaration.class);
   Assert.isNotNull(result);
   return result;
 }
  private static VariableDeclaration getVariableDeclaration(Name node) {
    IBinding binding = node.resolveBinding();
    if (binding == null && node.getParent() instanceof VariableDeclaration)
      return (VariableDeclaration) node.getParent();

    if (binding != null && binding.getKind() == IBinding.VARIABLE) {
      CompilationUnit cu = (CompilationUnit) ASTNodes.getParent(node, CompilationUnit.class);
      return ASTNodes.findVariableDeclaration(((IVariableBinding) binding), cu);
    }
    return null;
  }
 public static ASTNode getEnclosingNode(ASTNode firstSelectedNode) {
   ASTNode enclosingNode;
   if (firstSelectedNode instanceof MethodReference) {
     enclosingNode = firstSelectedNode;
   } else {
     enclosingNode = ASTResolving.findEnclosingLambdaExpression(firstSelectedNode);
     if (enclosingNode != null) {
       enclosingNode = ((LambdaExpression) enclosingNode).getBody();
     } else {
       enclosingNode = ASTNodes.getParent(firstSelectedNode, BodyDeclaration.class);
     }
   }
   return enclosingNode;
 }
    private MethodDeclaration getWritingConstructor(SimpleName name) {
      Assignment assignement = (Assignment) ASTNodes.getParent(name, Assignment.class);
      if (assignement == null) return null;

      ASTNode expression = assignement.getParent();
      if (!(expression instanceof ExpressionStatement)) return null;

      ASTNode block = expression.getParent();
      if (!(block instanceof Block)) return null;

      ASTNode methodDeclaration = block.getParent();
      if (!(methodDeclaration instanceof MethodDeclaration)) return null;

      return (MethodDeclaration) methodDeclaration;
    }
 private void checkExpression(RefactoringStatus status) {
   ASTNode[] nodes = getSelectedNodes();
   if (nodes != null && nodes.length == 1) {
     ASTNode node = nodes[0];
     if (node instanceof Type) {
       status.addFatalError(
           RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_type_reference,
           JavaStatusContext.create(fCUnit, node));
     } else if (node.getLocationInParent() == SwitchCase.EXPRESSION_PROPERTY) {
       status.addFatalError(
           RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_switch_case,
           JavaStatusContext.create(fCUnit, node));
     } else if (node instanceof Annotation || ASTNodes.getParent(node, Annotation.class) != null) {
       status.addFatalError(
           RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_from_annotation,
           JavaStatusContext.create(fCUnit, node));
     }
   }
 }
    private boolean fieldCanBeFinal(
        VariableDeclarationFragment fragment, IVariableBinding binding) {
      if (Modifier.isStatic(((FieldDeclaration) fragment.getParent()).getModifiers())) return false;

      if (!fWrittenVariables.containsKey(binding)) {
        // variable is not written
        if (fragment.getInitializer() == null) { // variable is not initialized
          return false;
        } else {
          return true;
        }
      }

      if (fragment.getInitializer() != null) // variable is initialized and written
      return false;

      ITypeBinding declaringClass = binding.getDeclaringClass();
      if (declaringClass == null) return false;

      ArrayList writes = (ArrayList) fWrittenVariables.get(binding);
      if (!isWrittenInTypeConstructors(writes, declaringClass)) return false;

      HashSet writingConstructorBindings = new HashSet();
      ArrayList writingConstructors = new ArrayList();
      for (int i = 0; i < writes.size(); i++) {
        SimpleName name = (SimpleName) writes.get(i);
        MethodDeclaration constructor = getWritingConstructor(name);
        if (writingConstructors.contains(
            constructor)) // variable is written twice or more in constructor
        return false;

        if (canReturn(constructor)) return false;

        writingConstructors.add(constructor);
        IMethodBinding constructorBinding = constructor.resolveBinding();
        if (constructorBinding == null) return false;

        writingConstructorBindings.add(constructorBinding);
      }

      for (int i = 0; i < writingConstructors.size(); i++) {
        MethodDeclaration constructor = (MethodDeclaration) writingConstructors.get(i);
        if (callsWritingConstructor(
            constructor,
            writingConstructorBindings)) // writing constructor calls other writing constructor
        return false;
      }

      MethodDeclaration constructor = (MethodDeclaration) writingConstructors.get(0);
      TypeDeclaration typeDecl =
          (TypeDeclaration) ASTNodes.getParent(constructor, TypeDeclaration.class);
      if (typeDecl == null) return false;

      MethodDeclaration[] methods = typeDecl.getMethods();
      for (int i = 0; i < methods.length; i++) {
        if (methods[i].isConstructor()) {
          IMethodBinding methodBinding = methods[i].resolveBinding();
          if (methodBinding == null) return false;

          if (!writingConstructorBindings.contains(methodBinding)) {
            if (!callsWritingConstructor(
                methods[i],
                writingConstructorBindings)) // non writing constructor does not call a writing
              // constructor
              return false;
          }
        }
      }

      return true;
    }
 @Override
 public void endVisit(CompilationUnit node) {
   RefactoringStatus status = getStatus();
   superCall:
   {
     if (status.hasFatalError()) break superCall;
     if (!hasSelectedNodes()) {
       ASTNode coveringNode = getLastCoveringNode();
       if (coveringNode instanceof Block
           && coveringNode.getParent() instanceof MethodDeclaration) {
         MethodDeclaration methodDecl = (MethodDeclaration) coveringNode.getParent();
         Message[] messages = ASTNodes.getMessages(methodDecl, ASTNodes.NODE_ONLY);
         if (messages.length > 0) {
           status.addFatalError(
               Messages.format(
                   RefactoringCoreMessages.ExtractMethodAnalyzer_compile_errors,
                   BasicElementLabels.getJavaElementName(methodDecl.getName().getIdentifier())),
               JavaStatusContext.create(fCUnit, methodDecl));
           break superCall;
         }
       }
       status.addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_invalid_selection);
       break superCall;
     }
     fEnclosingBodyDeclaration =
         (BodyDeclaration) ASTNodes.getParent(getFirstSelectedNode(), BodyDeclaration.class);
     if (fEnclosingBodyDeclaration == null
         || (fEnclosingBodyDeclaration.getNodeType() != ASTNode.METHOD_DECLARATION
             && fEnclosingBodyDeclaration.getNodeType() != ASTNode.FIELD_DECLARATION
             && fEnclosingBodyDeclaration.getNodeType() != ASTNode.INITIALIZER)) {
       status.addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_invalid_selection);
       break superCall;
     } else if (ASTNodes.getEnclosingType(fEnclosingBodyDeclaration) == null) {
       status.addFatalError(
           RefactoringCoreMessages.ExtractMethodAnalyzer_compile_errors_no_parent_binding);
       break superCall;
     } else if (fEnclosingBodyDeclaration.getNodeType() == ASTNode.METHOD_DECLARATION) {
       fEnclosingMethodBinding = ((MethodDeclaration) fEnclosingBodyDeclaration).resolveBinding();
     }
     if (!isSingleExpressionOrStatementSet()) {
       status.addFatalError(
           RefactoringCoreMessages.ExtractMethodAnalyzer_single_expression_or_set);
       break superCall;
     }
     if (isExpressionSelected()) {
       ASTNode expression = getFirstSelectedNode();
       if (expression instanceof Name) {
         Name name = (Name) expression;
         if (name.resolveBinding() instanceof ITypeBinding) {
           status.addFatalError(
               RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_type_reference);
           break superCall;
         }
         if (name.resolveBinding() instanceof IMethodBinding) {
           status.addFatalError(
               RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_method_name_reference);
           break superCall;
         }
         if (name.resolveBinding() instanceof IVariableBinding) {
           StructuralPropertyDescriptor locationInParent = name.getLocationInParent();
           if (locationInParent == QualifiedName.NAME_PROPERTY
               || (locationInParent == FieldAccess.NAME_PROPERTY
                   && !(((FieldAccess) name.getParent()).getExpression()
                       instanceof ThisExpression))) {
             status.addFatalError(
                 RefactoringCoreMessages
                     .ExtractMethodAnalyzer_cannot_extract_part_of_qualified_name);
             break superCall;
           }
         }
         if (name.isSimpleName() && ((SimpleName) name).isDeclaration()) {
           status.addFatalError(
               RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_name_in_declaration);
           break superCall;
         }
       }
       fForceStatic =
           ASTNodes.getParent(expression, ASTNode.SUPER_CONSTRUCTOR_INVOCATION) != null
               || ASTNodes.getParent(expression, ASTNode.CONSTRUCTOR_INVOCATION) != null;
     }
     status.merge(LocalTypeAnalyzer.perform(fEnclosingBodyDeclaration, getSelection()));
     computeLastStatementSelected();
   }
   super.endVisit(node);
 }
 private boolean isInTypeDeclarationAnnotation(ASTNode node) throws JavaModelException {
   ASTNode enclosingAnnotation = ASTNodes.getParent(node, Annotation.class);
   return enclosingAnnotation != null
       && enclosingAnnotation.getParent() == getContainingTypeDeclarationNode();
 }
 public BodyDeclaration getEnclosingBodyDeclaration() {
   ASTNode node = getFirstSelectedNode();
   if (node == null) return null;
   return (BodyDeclaration) ASTNodes.getParent(node, BodyDeclaration.class);
 }