private void visitBackwards(List<? extends ASTNode> list) {
      if (fBreak) return;

      for (int i = list.size() - 1; i >= 0; i--) {
        ASTNode curr = list.get(i);
        if (curr.getStartPosition() < fPosition) {
          curr.accept(this);
        }
      }
    }
 private void removeStatement(ASTRewrite rewrite, ASTNode statementNode, TextEditGroup group) {
   if (ASTNodes.isControlStatementBody(statementNode.getLocationInParent())) {
     rewrite.replace(statementNode, rewrite.getAST().newBlock(), group);
   } else {
     rewrite.remove(statementNode, group);
   }
 }
 private static ITypeBinding getQualifier(SimpleName selector) {
   ASTNode parent = selector.getParent();
   switch (parent.getNodeType()) {
     case ASTNode.METHOD_INVOCATION:
       MethodInvocation decl = (MethodInvocation) parent;
       if (selector == decl.getName()) {
         return getBinding(decl.getExpression());
       }
       return null;
     case ASTNode.QUALIFIED_NAME:
       QualifiedName qualifiedName = (QualifiedName) parent;
       if (selector == qualifiedName.getName()) {
         return getBinding(qualifiedName.getQualifier());
       }
       return null;
     case ASTNode.FIELD_ACCESS:
       FieldAccess fieldAccess = (FieldAccess) parent;
       if (selector == fieldAccess.getName()) {
         return getBinding(fieldAccess.getExpression());
       }
       return null;
     case ASTNode.SUPER_FIELD_ACCESS:
       {
         ITypeBinding curr = Bindings.getBindingOfParentType(parent);
         return curr.getSuperclass();
       }
     case ASTNode.SUPER_METHOD_INVOCATION:
       {
         SuperMethodInvocation superInv = (SuperMethodInvocation) parent;
         if (selector == superInv.getName()) {
           ITypeBinding curr = Bindings.getBindingOfParentType(parent);
           return curr.getSuperclass();
         }
         return null;
       }
     default:
       if (parent instanceof Type) {
         // bug 67644: in 'a.new X()', all member types of A are visible as location of X.
         ASTNode normalizedNode = ASTNodes.getNormalizedNode(parent);
         if (normalizedNode.getLocationInParent() == ClassInstanceCreation.TYPE_PROPERTY) {
           ClassInstanceCreation creation = (ClassInstanceCreation) normalizedNode.getParent();
           return getBinding(creation.getExpression());
         }
       }
       return null;
   }
 }
  private boolean addOuterDeclarationsForLocalType(
      ITypeBinding localBinding, int flags, IBindingRequestor requestor) {
    ASTNode node = fRoot.findDeclaringNode(localBinding);
    if (node == null) {
      return false;
    }

    if (node instanceof AbstractTypeDeclaration || node instanceof AnonymousClassDeclaration) {
      if (addLocalDeclarations(node.getParent(), flags, requestor)) return true;

      ITypeBinding parentTypeBinding = Bindings.getBindingOfParentType(node.getParent());
      if (parentTypeBinding != null) {
        if (addTypeDeclarations(parentTypeBinding, flags, requestor)) return true;
      }
    }
    return false;
  }
 public static Statement findParentStatement(ASTNode node) {
   while ((node != null) && (!(node instanceof Statement))) {
     node = node.getParent();
     if (node instanceof BodyDeclaration) {
       return null;
     }
   }
   return (Statement) node;
 }
  public IBinding[] getDeclarationsAfter(int offset, int flags) {
    try {
      org.eclipse.che.ide.ext.java.jdt.core.dom.NodeFinder finder =
          new org.eclipse.che.ide.ext.java.jdt.core.dom.NodeFinder(fRoot, offset, 0);
      ASTNode node = finder.getCoveringNode();
      if (node == null) {
        return null;
      }

      ASTNode declaration = findParentStatement(node);
      while (declaration instanceof Statement && declaration.getNodeType() != ASTNode.BLOCK) {
        declaration = declaration.getParent();
      }

      if (declaration instanceof Block) {
        DefaultBindingRequestor requestor = new DefaultBindingRequestor();
        DeclarationsAfterVisitor visitor =
            new DeclarationsAfterVisitor(node.getStartPosition(), flags, requestor);
        declaration.accept(visitor);
        List<IBinding> result = requestor.getResult();
        return result.toArray(new IBinding[result.size()]);
      }
      return NO_BINDING;
    } finally {
      clearLists();
    }
  }
  private static boolean hasSideEffect(SimpleName reference) {
    ASTNode parent = reference.getParent();
    while (parent instanceof QualifiedName) {
      parent = parent.getParent();
    }
    if (parent instanceof FieldAccess) {
      parent = parent.getParent();
    }

    ASTNode node = null;
    int nameParentType = parent.getNodeType();
    if (nameParentType == ASTNode.ASSIGNMENT) {
      Assignment assignment = (Assignment) parent;
      node = assignment.getRightHandSide();
    } else if (nameParentType == ASTNode.SINGLE_VARIABLE_DECLARATION) {
      SingleVariableDeclaration decl = (SingleVariableDeclaration) parent;
      node = decl.getInitializer();
      if (node == null) return false;
    } else if (nameParentType == ASTNode.VARIABLE_DECLARATION_FRAGMENT) {
      node = parent;
    } else {
      return false;
    }

    ArrayList<Expression> sideEffects = new ArrayList<Expression>();
    node.accept(new SideEffectFinder(sideEffects));
    return sideEffects.size() > 0;
  }
    private void removeUnusedName(CompilationUnitRewrite cuRewrite, SimpleName simpleName) {
      ASTRewrite rewrite = cuRewrite.getASTRewrite();
      CompilationUnit completeRoot = cuRewrite.getRoot();

      IBinding binding = simpleName.resolveBinding();
      CompilationUnit root = (CompilationUnit) simpleName.getRoot();
      String displayString = getDisplayString(binding);
      TextEditGroup group = createTextEditGroup(displayString, cuRewrite);
      if (binding.getKind() == IBinding.METHOD) {
        IMethodBinding decl = ((IMethodBinding) binding).getMethodDeclaration();
        ASTNode declaration = root.findDeclaringNode(decl);
        rewrite.remove(declaration, group);
      } else if (binding.getKind() == IBinding.TYPE) {
        ITypeBinding decl = ((ITypeBinding) binding).getTypeDeclaration();
        ASTNode declaration = root.findDeclaringNode(decl);
        if (declaration.getParent() instanceof TypeDeclarationStatement) {
          declaration = declaration.getParent();
        }
        rewrite.remove(declaration, group);
      } else if (binding.getKind() == IBinding.VARIABLE) {
        SimpleName nameNode =
            (SimpleName)
                NodeFinder.perform(
                    completeRoot, simpleName.getStartPosition(), simpleName.getLength());
        SimpleName[] references =
            LinkedNodeFinder.findByBinding(completeRoot, nameNode.resolveBinding());
        for (int i = 0; i < references.length; i++) {
          removeVariableReferences(rewrite, references[i], group);
        }

        IVariableBinding bindingDecl =
            ((IVariableBinding) nameNode.resolveBinding()).getVariableDeclaration();
        ASTNode declaringNode = completeRoot.findDeclaringNode(bindingDecl);
        if (declaringNode instanceof SingleVariableDeclaration) {
          removeParamTag(rewrite, (SingleVariableDeclaration) declaringNode, group);
        }
      } else {
        // unexpected
      }
    }
 private void removeVariableWithInitializer(
     ASTRewrite rewrite, ASTNode initializerNode, ASTNode statementNode, TextEditGroup group) {
   boolean performRemove = fForceRemove;
   if (!performRemove) {
     ArrayList<Expression> sideEffectNodes = new ArrayList<Expression>();
     initializerNode.accept(new SideEffectFinder(sideEffectNodes));
     performRemove = sideEffectNodes.isEmpty();
   }
   if (performRemove) {
     removeStatement(rewrite, statementNode, group);
     fRemovedAssignmentsCount++;
   } else {
     ASTNode initNode = rewrite.createMoveTarget(initializerNode);
     ExpressionStatement statement =
         rewrite.getAST().newExpressionStatement((Expression) initNode);
     rewrite.replace(statementNode, statement, null);
     fAlteredAssignmentsCount++;
   }
 }
 public static BodyDeclaration findParentBodyDeclaration(ASTNode node) {
   while ((node != null) && (!(node instanceof BodyDeclaration))) {
     node = node.getParent();
   }
   return (BodyDeclaration) node;
 }
 private boolean addLocalDeclarations(ASTNode node, int flags, IBindingRequestor requestor) {
   return addLocalDeclarations(node, node.getStartPosition(), flags, requestor);
 }
    private boolean isInside(ASTNode node) {
      int start = node.getStartPosition();
      int end = start + node.getLength();

      return start <= fPosition && fPosition < end;
    }
    /**
     * Remove the field or variable declaration including the initializer.
     *
     * @param rewrite the AST rewriter to use
     * @param reference a reference to the variable to remove
     * @param group the text edit group to use
     */
    private void removeVariableReferences(
        ASTRewrite rewrite, SimpleName reference, TextEditGroup group) {
      ASTNode parent = reference.getParent();
      while (parent instanceof QualifiedName) {
        parent = parent.getParent();
      }
      if (parent instanceof FieldAccess) {
        parent = parent.getParent();
      }

      int nameParentType = parent.getNodeType();
      if (nameParentType == ASTNode.ASSIGNMENT) {
        Assignment assignment = (Assignment) parent;
        Expression rightHand = assignment.getRightHandSide();

        ASTNode assignParent = assignment.getParent();
        if (assignParent.getNodeType() == ASTNode.EXPRESSION_STATEMENT
            && rightHand.getNodeType() != ASTNode.ASSIGNMENT) {
          removeVariableWithInitializer(rewrite, rightHand, assignParent, group);
        } else {
          rewrite.replace(assignment, rewrite.createCopyTarget(rightHand), group);
        }
      } else if (nameParentType == ASTNode.SINGLE_VARIABLE_DECLARATION) {
        rewrite.remove(parent, group);
      } else if (nameParentType == ASTNode.VARIABLE_DECLARATION_FRAGMENT) {
        VariableDeclarationFragment frag = (VariableDeclarationFragment) parent;
        ASTNode varDecl = frag.getParent();
        List<VariableDeclarationFragment> fragments;
        if (varDecl instanceof VariableDeclarationExpression) {
          fragments = ((VariableDeclarationExpression) varDecl).fragments();
        } else if (varDecl instanceof FieldDeclaration) {
          fragments = ((FieldDeclaration) varDecl).fragments();
        } else {
          fragments = ((VariableDeclarationStatement) varDecl).fragments();
        }
        Expression initializer = frag.getInitializer();
        if (initializer instanceof CastExpression) {
          initializer = ((CastExpression) initializer).getExpression();
        }
        boolean sideEffectInitializer =
            initializer instanceof MethodInvocation || initializer instanceof ClassInstanceCreation;
        if (fragments.size() == fUnusedNames.length) {
          if (fForceRemove) {
            rewrite.remove(varDecl, group);
            return;
          }
          if (parent.getParent() instanceof FieldDeclaration) {
            rewrite.remove(varDecl, group);
            return;
          }
          if (sideEffectInitializer) {
            Expression movedInit = (Expression) rewrite.createMoveTarget(initializer);
            ExpressionStatement wrapped = rewrite.getAST().newExpressionStatement(movedInit);
            rewrite.replace(varDecl, wrapped, group);
          } else {
            rewrite.remove(varDecl, group);
          }
        } else {
          if (fForceRemove) {
            rewrite.remove(frag, group);
            return;
          }
          // multiple declarations in one line
          ASTNode declaration = parent.getParent();
          if (declaration instanceof FieldDeclaration) {
            rewrite.remove(frag, group);
            return;
          }
          if (declaration instanceof VariableDeclarationStatement) {
            ASTNode lst = declaration.getParent();
            ListRewrite listRewrite = null;
            if (lst instanceof Block) {
              listRewrite = rewrite.getListRewrite(lst, Block.STATEMENTS_PROPERTY);
            } else if (lst instanceof SwitchStatement) {
              listRewrite = rewrite.getListRewrite(lst, SwitchStatement.STATEMENTS_PROPERTY);
            } else {
              Assert.isTrue(false);
            }
            splitUpDeclarations(
                rewrite, group, frag, listRewrite, (VariableDeclarationStatement) declaration);
            rewrite.remove(frag, group);
            return;
          }
          if (declaration instanceof VariableDeclarationExpression) {
            // keep constructors and method invocations
            if (!sideEffectInitializer) {
              rewrite.remove(frag, group);
            }
          }
        }
      } else if (nameParentType == ASTNode.POSTFIX_EXPRESSION
          || nameParentType == ASTNode.PREFIX_EXPRESSION) {
        Expression expression = (Expression) parent;
        ASTNode expressionParent = expression.getParent();
        if (expressionParent.getNodeType() == ASTNode.EXPRESSION_STATEMENT) {
          removeStatement(rewrite, expressionParent, group);
        } else {
          rewrite.remove(expression, group);
        }
      }
    }