private Statement getCatchBody(String type, String name, String lineSeparator)
     throws CoreException {
   String s =
       StubUtility.getCatchBodyContent(fCUnit, type, name, fSelectedNodes[0], lineSeparator);
   if (s == null) {
     return null;
   } else {
     return (Statement) fRewriter.createStringPlaceholder(s, ASTNode.RETURN_STATEMENT);
   }
 }
  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.andmore.android.model.java.JavaClass#addComments()
   */
  @Override
  protected void addComments() throws AndroidException {
    ASTNode todoComment;

    ASTParser parser = ASTParser.newParser(AST.JLS3);
    parser.setSource(document.get().toCharArray());

    compUnit = (CompilationUnit) parser.createAST(null);
    ast = compUnit.getAST();
    rewrite = ASTRewrite.create(ast);

    todoComment =
        rewrite.createStringPlaceholder(
            CodeUtilsNLS.MODEL_Common_ToDoPutYourCodeHere, ASTNode.EMPTY_STATEMENT);

    TypeDeclaration receiverClass = (TypeDeclaration) compUnit.types().get(0);
    MethodDeclaration method;
    Block block;

    // Adds the Override annotation and ToDo comment to all overridden
    // methods
    for (int i = 0; i < receiverClass.bodyDeclarations().size(); i++) {
      method = (MethodDeclaration) receiverClass.bodyDeclarations().get(i);

      // Adds the Override annotation
      rewrite
          .getListRewrite(method, method.getModifiersProperty())
          .insertFirst(OVERRIDE_ANNOTATION, null);

      // Adds the ToDo comment
      block = method.getBody();
      rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY).insertFirst(todoComment, null);
    }

    try {
      // Writes the modifications
      TextEdit modifications = rewrite.rewriteAST(document, null);
      modifications.apply(document);
    } catch (IllegalArgumentException e) {
      String errMsg = NLS.bind(CodeUtilsNLS.EXC_JavaClass_ErrorApplyingCommentsToCode, className);

      AndmoreLogger.error(BroadcastReceiverClass.class, errMsg, e);
      throw new AndroidException(errMsg);
    } catch (MalformedTreeException e) {
      String errMsg = NLS.bind(CodeUtilsNLS.EXC_JavaClass_ErrorApplyingCommentsToCode, className);

      AndmoreLogger.error(BroadcastReceiverClass.class, errMsg, e);
      throw new AndroidException(errMsg);
    } catch (BadLocationException e) {
      String errMsg = NLS.bind(CodeUtilsNLS.EXC_JavaClass_ErrorApplyingCommentsToCode, className);

      AndmoreLogger.error(BroadcastReceiverClass.class, errMsg, e);
      throw new AndroidException(errMsg);
    }
  }
 /**
  * Creates a place holder ASTNode for the given element.
  *
  * @param rewriter
  * @param element
  * @param delimiter the line delimiter
  * @param project
  * @return a ASTNode or null
  * @throws CoreException
  */
 private ASTNode createASTNode(
     ASTRewrite rewriter, ITypedElement element, String delimiter, IJavaProject project)
     throws CoreException {
   if (element instanceof IStreamContentAccessor) {
     String content = JavaCompareUtilities.readString((IStreamContentAccessor) element);
     if (content != null) {
       content = trimTextBlock(content, delimiter, project);
       if (content != null) {
         int type = getPlaceHolderType(element);
         if (type != -1) return rewriter.createStringPlaceholder(content, type);
       }
     }
   }
   return null;
 }
  /**
   * Removes the current variable declaration from the AST and inserts it into the lowest possible
   * scope where the variable is first used. Returns the modification to the AST within a Change
   * object.
   */
  private Change recordASTModifications() {
    AST ast = compilationUnit.getAST();
    ASTRewrite rewriter = ASTRewrite.create(ast);

    // duplicate the original variable declaration in lower scope before getting rid of it
    VariableDeclarationStatement oldDeclaration =
        (VariableDeclarationStatement) variableVisitor.getDeclaration();

    assert variableVisitor.getFirstAssignment() instanceof Assignment;
    Assignment variableAssignment = (Assignment) variableVisitor.getFirstAssignment();
    ASTNode newScopeParent = variableAssignment.getParent().getParent();

    String codeString = oldDeclaration.toString();
    ASTNode newDeclaration =
        rewriter.createStringPlaceholder(
            codeString.substring(0, codeString.length() - 1),
            ASTNode.VARIABLE_DECLARATION_STATEMENT);

    ListRewrite listRewrite = rewriter.getListRewrite(newScopeParent, Block.STATEMENTS_PROPERTY);
    listRewrite.insertAt(newDeclaration, 0, null);

    // get rid of the higher scope declaration
    rewriter.remove(oldDeclaration, null);

    ICompilationUnit iCompUnit = method.getCompilationUnit();

    final String description = "ReduceScopeOfVariable";
    final String comment = "ReduceScopeOfVariable does blah...";

    // record the change
    CompilationUnitChange change =
        new CompilationUnitChange("Reduce scope of variable", iCompUnit) {
          public ChangeDescriptor getDescriptor() {
            Map<Object, Object> arguments = new HashMap<Object, Object>();
            arguments.put("method", method);
            arguments.put("var", varName);
            return new RefactoringChangeDescriptor(
                new ReduceScopeOfVariableDescriptor(
                    method.getJavaProject().getElementName(), description, comment, arguments));
          }
        };
    try {
      change.setEdit(rewriter.rewriteAST());
    } catch (Exception e) {
    }

    return change;
  }
 private void updatePackageStatement(
     CompilationUnit astCU, String[] pkgName, ASTRewrite rewriter, ICompilationUnit cu)
     throws JavaModelException {
   boolean defaultPackage = pkgName.length == 0;
   AST ast = astCU.getAST();
   if (defaultPackage) {
     // remove existing package statement
     PackageDeclaration pkg = astCU.getPackage();
     if (pkg != null) {
       int pkgStart;
       Javadoc javadoc = pkg.getJavadoc();
       if (javadoc != null) {
         pkgStart = javadoc.getStartPosition() + javadoc.getLength() + 1;
       } else {
         pkgStart = pkg.getStartPosition();
       }
       int extendedStart = astCU.getExtendedStartPosition(pkg);
       if (pkgStart != extendedStart) {
         // keep the comments associated with package declaration
         // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=247757
         String commentSource = cu.getSource().substring(extendedStart, pkgStart);
         ASTNode comment =
             rewriter.createStringPlaceholder(commentSource, ASTNode.PACKAGE_DECLARATION);
         rewriter.set(astCU, CompilationUnit.PACKAGE_PROPERTY, comment, null);
       } else {
         rewriter.set(astCU, CompilationUnit.PACKAGE_PROPERTY, null, null);
       }
     }
   } else {
     org.eclipse.jdt.core.dom.PackageDeclaration pkg = astCU.getPackage();
     if (pkg != null) {
       // rename package statement
       Name name = ast.newName(pkgName);
       rewriter.set(pkg, PackageDeclaration.NAME_PROPERTY, name, null);
     } else {
       // create new package statement
       pkg = ast.newPackageDeclaration();
       pkg.setName(ast.newName(pkgName));
       rewriter.set(astCU, CompilationUnit.PACKAGE_PROPERTY, pkg, null);
     }
   }
 }
  private void createTryCatchStatement(org.eclipse.jdt.core.IBuffer buffer, String lineDelimiter)
      throws CoreException {
    List<Statement> result = new ArrayList<>(1);
    TryStatement tryStatement = getAST().newTryStatement();
    ITypeBinding[] exceptions = fAnalyzer.getExceptions();
    ImportRewriteContext context =
        new ContextSensitiveImportRewriteContext(
            fAnalyzer.getEnclosingBodyDeclaration(), fImportRewrite);

    if (!fIsMultiCatch) {
      for (int i = 0; i < exceptions.length; i++) {
        ITypeBinding exception = exceptions[i];
        CatchClause catchClause = getAST().newCatchClause();
        tryStatement.catchClauses().add(catchClause);
        SingleVariableDeclaration decl = getAST().newSingleVariableDeclaration();
        String varName = StubUtility.getExceptionVariableName(fCUnit.getJavaProject());

        String name = fScope.createName(varName, false);
        decl.setName(getAST().newSimpleName(name));
        Type type = fImportRewrite.addImport(exception, getAST(), context);
        decl.setType(type);
        catchClause.setException(decl);
        Statement st = getCatchBody(ASTNodes.getQualifiedTypeName(type), name, lineDelimiter);
        if (st != null) {
          catchClause.getBody().statements().add(st);
        }
        fLinkedProposalModel
            .getPositionGroup(GROUP_EXC_TYPE + i, true)
            .addPosition(fRewriter.track(decl.getType()), i == 0);
        fLinkedProposalModel
            .getPositionGroup(GROUP_EXC_NAME + i, true)
            .addPosition(fRewriter.track(decl.getName()), false);
      }
    } else {
      List<ITypeBinding> filteredExceptions = filterSubtypeExceptions(exceptions);
      CatchClause catchClause = getAST().newCatchClause();
      SingleVariableDeclaration decl = getAST().newSingleVariableDeclaration();
      String varName = StubUtility.getExceptionVariableName(fCUnit.getJavaProject());
      String name = fScope.createName(varName, false);
      decl.setName(getAST().newSimpleName(name));

      UnionType unionType = getAST().newUnionType();
      List<Type> types = unionType.types();
      int i = 0;
      for (ITypeBinding exception : filteredExceptions) {
        Type type = fImportRewrite.addImport(exception, getAST(), context);
        types.add(type);
        fLinkedProposalModel
            .getPositionGroup(GROUP_EXC_TYPE + i, true)
            .addPosition(fRewriter.track(type), i == 0);
        i++;
      }

      decl.setType(unionType);
      catchClause.setException(decl);
      fLinkedProposalModel
          .getPositionGroup(GROUP_EXC_NAME + 0, true)
          .addPosition(fRewriter.track(decl.getName()), false);
      Statement st = getCatchBody("Exception", name, lineDelimiter); // $NON-NLS-1$
      if (st != null) {
        catchClause.getBody().statements().add(st);
      }
      tryStatement.catchClauses().add(catchClause);
    }
    List<ASTNode> variableDeclarations = getSpecialVariableDeclarationStatements();
    ListRewrite statements =
        fRewriter.getListRewrite(tryStatement.getBody(), Block.STATEMENTS_PROPERTY);
    boolean selectedNodeRemoved = false;
    ASTNode expressionStatement = null;
    for (int i = 0; i < fSelectedNodes.length; i++) {
      ASTNode node = fSelectedNodes[i];
      if (node instanceof VariableDeclarationStatement && variableDeclarations.contains(node)) {
        AST ast = getAST();
        VariableDeclarationStatement statement = (VariableDeclarationStatement) node;
        // Create a copy and remove the initializer
        VariableDeclarationStatement copy =
            (VariableDeclarationStatement) ASTNode.copySubtree(ast, statement);
        List<IExtendedModifier> modifiers = copy.modifiers();
        for (Iterator<IExtendedModifier> iter = modifiers.iterator(); iter.hasNext(); ) {
          IExtendedModifier modifier = iter.next();
          if (modifier.isModifier()
              && Modifier.isFinal(((Modifier) modifier).getKeyword().toFlagValue())) {
            iter.remove();
          }
        }
        List<VariableDeclarationFragment> fragments = copy.fragments();
        for (Iterator<VariableDeclarationFragment> iter = fragments.iterator(); iter.hasNext(); ) {
          VariableDeclarationFragment fragment = iter.next();
          fragment.setInitializer(null);
        }
        CompilationUnit root = (CompilationUnit) statement.getRoot();
        int extendedStart = root.getExtendedStartPosition(statement);
        // we have a leading comment and the comment is covered by the selection
        if (extendedStart != statement.getStartPosition()
            && extendedStart >= fSelection.getOffset()) {
          String commentToken =
              buffer.getText(extendedStart, statement.getStartPosition() - extendedStart);
          commentToken = Strings.trimTrailingTabsAndSpaces(commentToken);
          Type type = statement.getType();
          String typeName = buffer.getText(type.getStartPosition(), type.getLength());
          copy.setType(
              (Type)
                  fRewriter.createStringPlaceholder(commentToken + typeName, type.getNodeType()));
        }
        result.add(copy);
        // convert the fragments into expression statements
        fragments = statement.fragments();
        if (!fragments.isEmpty()) {
          List<ExpressionStatement> newExpressionStatements = new ArrayList<>();
          for (Iterator<VariableDeclarationFragment> iter = fragments.iterator();
              iter.hasNext(); ) {
            VariableDeclarationFragment fragment = iter.next();
            Expression initializer = fragment.getInitializer();
            if (initializer != null) {
              Assignment assignment = ast.newAssignment();
              assignment.setLeftHandSide(
                  (Expression) fRewriter.createCopyTarget(fragment.getName()));
              assignment.setRightHandSide((Expression) fRewriter.createCopyTarget(initializer));
              newExpressionStatements.add(ast.newExpressionStatement(assignment));
            }
          }
          if (!newExpressionStatements.isEmpty()) {
            if (fSelectedNodes.length == 1) {
              expressionStatement =
                  fRewriter.createGroupNode(
                      newExpressionStatements.toArray(new ASTNode[newExpressionStatements.size()]));
            } else {
              fRewriter.replace(
                  statement,
                  fRewriter.createGroupNode(
                      newExpressionStatements.toArray(new ASTNode[newExpressionStatements.size()])),
                  null);
            }
          } else {
            fRewriter.remove(statement, null);
            selectedNodeRemoved = true;
          }
        } else {
          fRewriter.remove(statement, null);
          selectedNodeRemoved = true;
        }
      }
    }
    result.add(tryStatement);
    ASTNode replacementNode;
    if (result.size() == 1) {
      replacementNode = result.get(0);
    } else {
      replacementNode = fRewriter.createGroupNode(result.toArray(new ASTNode[result.size()]));
    }
    if (fSelectedNodes.length == 1) {
      ASTNode selectedNode = fSelectedNodes[0];

      if (selectedNode instanceof MethodReference) {
        MethodReference methodReference = (MethodReference) selectedNode;
        IMethodBinding functionalMethod =
            QuickAssistProcessor.getFunctionalMethodForMethodReference(methodReference);
        // functionalMethod is non-null and non-generic. See
        // ExceptionAnalyzer.handleMethodReference(MethodReference node).
        Assert.isTrue(functionalMethod != null && !functionalMethod.isGenericMethod());
        LambdaExpression lambda =
            QuickAssistProcessor.convertMethodRefernceToLambda(
                methodReference, functionalMethod, fRootNode, fRewriter, null, true);
        ASTNode statementInBlock = (ASTNode) ((Block) lambda.getBody()).statements().get(0);
        fRewriter.replace(statementInBlock, replacementNode, null);
        statements.insertLast(statementInBlock, null);
        return;
      }

      LambdaExpression enclosingLambda = ASTResolving.findEnclosingLambdaExpression(selectedNode);
      if (enclosingLambda != null
          && selectedNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY
          && enclosingLambda.resolveMethodBinding() != null) {
        QuickAssistProcessor.changeLambdaBodyToBlock(enclosingLambda, getAST(), fRewriter);
        Block blockBody = (Block) fRewriter.get(enclosingLambda, LambdaExpression.BODY_PROPERTY);
        ASTNode statementInBlock = (ASTNode) blockBody.statements().get(0);
        fRewriter.replace(statementInBlock, replacementNode, null);
        statements.insertLast(statementInBlock, null);
        return;
      }

      if (expressionStatement != null) {
        statements.insertLast(expressionStatement, null);
      } else {
        if (!selectedNodeRemoved)
          statements.insertLast(fRewriter.createMoveTarget(selectedNode), null);
      }
      fRewriter.replace(selectedNode, replacementNode, null);
    } else {
      ListRewrite source =
          fRewriter.getListRewrite(
              fSelectedNodes[0].getParent(),
              (ChildListPropertyDescriptor) fSelectedNodes[0].getLocationInParent());
      ASTNode toMove =
          source.createMoveTarget(
              fSelectedNodes[0], fSelectedNodes[fSelectedNodes.length - 1], replacementNode, null);
      statements.insertLast(toMove, null);
    }
  }