public static String buildCollectionText(PsiForStatement forStatement) {
   PsiStatement body = forStatement.getBody();
   while (body instanceof PsiBlockStatement) {
     final PsiBlockStatement blockStatement = (PsiBlockStatement) body;
     final PsiCodeBlock codeBlock = blockStatement.getCodeBlock();
     final PsiStatement[] statements = codeBlock.getStatements();
     if (statements.length == 2) {
       body = statements[1];
     } else if (statements.length == 1) {
       body = statements[0];
     } else {
       return null;
     }
   }
   if (!(body instanceof PsiExpressionStatement)) {
     return null;
   }
   final PsiExpressionStatement expressionStatement = (PsiExpressionStatement) body;
   final PsiExpression expression = expressionStatement.getExpression();
   if (!(expression instanceof PsiMethodCallExpression)) {
     return null;
   }
   final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) expression;
   final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
   final PsiElement qualifier = methodExpression.getQualifier();
   if (qualifier == null) {
     // fixme for when the array is added to 'this'
     return null;
   }
   return qualifier.getText();
 }
 @Nullable
 private static PsiStatement getBody(PsiLoopStatement forStatement) {
   PsiStatement body = forStatement.getBody();
   while (body instanceof PsiBlockStatement) {
     final PsiBlockStatement blockStatement = (PsiBlockStatement) body;
     final PsiCodeBlock codeBlock = blockStatement.getCodeBlock();
     final PsiStatement[] statements = codeBlock.getStatements();
     body = statements.length == 0 ? null : statements[0];
   }
   return body;
 }
 @Nullable
 private PsiStatement getFirstStatement(PsiStatement body) {
   if (!(body instanceof PsiBlockStatement)) {
     return body;
   }
   final PsiBlockStatement block = (PsiBlockStatement) body;
   final PsiCodeBlock codeBlock = block.getCodeBlock();
   final PsiStatement[] statements = codeBlock.getStatements();
   if (statements.length <= 0) {
     return null;
   }
   return statements[0];
 }
  private void surroundWithCodeBlock(@NotNull final MoveInfo info, final boolean down) {
    try {
      final Document document =
          PsiDocumentManager.getInstance(statementToSurroundWithCodeBlock.getProject())
              .getDocument(statementToSurroundWithCodeBlock.getContainingFile());
      int startOffset = document.getLineStartOffset(info.toMove.startLine);
      int endOffset = getLineStartSafeOffset(document, info.toMove.endLine);
      if (document.getText().charAt(endOffset - 1) == '\n') endOffset--;
      final RangeMarker lineRangeMarker = document.createRangeMarker(startOffset, endOffset);

      final PsiElementFactory factory =
          JavaPsiFacade.getInstance(statementToSurroundWithCodeBlock.getProject())
              .getElementFactory();
      PsiCodeBlock codeBlock = factory.createCodeBlock();
      codeBlock.add(statementToSurroundWithCodeBlock);
      final PsiBlockStatement blockStatement =
          (PsiBlockStatement)
              factory.createStatementFromText("{}", statementToSurroundWithCodeBlock);
      blockStatement.getCodeBlock().replace(codeBlock);
      PsiBlockStatement newStatement =
          (PsiBlockStatement) statementToSurroundWithCodeBlock.replace(blockStatement);
      newStatement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(newStatement);
      info.toMove =
          new LineRange(
              document.getLineNumber(lineRangeMarker.getStartOffset()),
              document.getLineNumber(lineRangeMarker.getEndOffset()) + 1);
      PsiCodeBlock newCodeBlock = newStatement.getCodeBlock();
      if (down) {
        PsiElement blockChild = firstNonWhiteElement(newCodeBlock.getFirstBodyElement(), true);
        if (blockChild == null) blockChild = newCodeBlock.getRBrace();
        info.toMove2 =
            new LineRange(
                info.toMove2
                    .startLine, // document.getLineNumber(newCodeBlock.getParent().getTextRange().getStartOffset()),
                document.getLineNumber(blockChild.getTextRange().getStartOffset()));
      } else {
        int start =
            document.getLineNumber(newCodeBlock.getRBrace().getTextRange().getStartOffset());
        int end = info.toMove.startLine;
        if (start > end) end = start;
        info.toMove2 = new LineRange(start, end);
      }
    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
  }
 @Override
 public void visitBlockStatement(PsiBlockStatement statement) {
   final PsiElement parent = statement.getParent();
   final boolean isAlreadyCounted =
       parent instanceof PsiDoWhileStatement
           || parent instanceof PsiWhileStatement
           || parent instanceof PsiForStatement
           || parent instanceof PsiIfStatement
           || parent instanceof PsiSynchronizedStatement;
   if (!isAlreadyCounted) {
     enterScope(statement);
   }
   super.visitBlockStatement(statement);
 }
 private static boolean bodyIsArrayToCollectionCopy(
     PsiStatement body, PsiVariable variable, boolean shouldBeOffsetArrayAccess) {
   if (body instanceof PsiExpressionStatement) {
     final PsiExpressionStatement expressionStatement = (PsiExpressionStatement) body;
     final PsiExpression expression = expressionStatement.getExpression();
     return expressionIsArrayToCollectionCopy(expression, variable, shouldBeOffsetArrayAccess);
   } else if (body instanceof PsiBlockStatement) {
     final PsiBlockStatement blockStatement = (PsiBlockStatement) body;
     final PsiCodeBlock codeBlock = blockStatement.getCodeBlock();
     final PsiStatement[] statements = codeBlock.getStatements();
     if (statements.length == 1) {
       return bodyIsArrayToCollectionCopy(statements[0], variable, shouldBeOffsetArrayAccess);
     } else if (statements.length == 2) {
       final PsiStatement statement = statements[0];
       if (!(statement instanceof PsiDeclarationStatement)) {
         return false;
       }
       final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement) statement;
       final PsiElement[] declaredElements = declarationStatement.getDeclaredElements();
       if (declaredElements.length != 1) {
         return false;
       }
       final PsiElement declaredElement = declaredElements[0];
       if (!(declaredElement instanceof PsiVariable)) {
         return false;
       }
       final PsiVariable localVariable = (PsiVariable) declaredElement;
       final PsiExpression initializer = localVariable.getInitializer();
       if (!ExpressionUtils.isOffsetArrayAccess(initializer, variable)) {
         return false;
       }
       return bodyIsArrayToCollectionCopy(statements[1], localVariable, false);
     }
   }
   return false;
 }
 public static boolean statementsAreEquivalent(
     @Nullable PsiStatement statement1, @Nullable PsiStatement statement2) {
   if (statement1 == null) {
     return statement2 == null;
   } else if (statement2 == null) {
     return false;
   }
   if (statement1.getClass() != statement2.getClass()) {
     if (statement1 instanceof PsiBlockStatement && !(statement2 instanceof PsiBlockStatement)) {
       final PsiBlockStatement blockStatement = (PsiBlockStatement) statement1;
       final PsiStatement[] statements = blockStatement.getCodeBlock().getStatements();
       if (statements.length != 1) {
         return false;
       }
       statement1 = statements[0];
     } else if (!(statement1 instanceof PsiBlockStatement)
         && statement2 instanceof PsiBlockStatement) {
       final PsiBlockStatement blockStatement = (PsiBlockStatement) statement2;
       final PsiStatement[] statements = blockStatement.getCodeBlock().getStatements();
       if (statements.length != 1) {
         return false;
       }
       statement2 = statements[0];
     } else {
       return false;
     }
     if (statement1.getClass() != statement2.getClass()) {
       return false;
     }
   }
   if (statement1 instanceof PsiAssertStatement) {
     return assertStatementsAreEquivalent(
         (PsiAssertStatement) statement1, (PsiAssertStatement) statement2);
   }
   if (statement1 instanceof PsiBlockStatement) {
     return blockStatementsAreEquivalent(
         (PsiBlockStatement) statement1, (PsiBlockStatement) statement2);
   }
   if (statement1 instanceof PsiBreakStatement) {
     return breakStatementsAreEquivalent(
         (PsiBreakStatement) statement1, (PsiBreakStatement) statement2);
   }
   if (statement1 instanceof PsiContinueStatement) {
     return continueStatementsAreEquivalent(
         (PsiContinueStatement) statement1, (PsiContinueStatement) statement2);
   }
   if (statement1 instanceof PsiDeclarationStatement) {
     return declarationStatementsAreEquivalent(
         (PsiDeclarationStatement) statement1, (PsiDeclarationStatement) statement2);
   }
   if (statement1 instanceof PsiDoWhileStatement) {
     return doWhileStatementsAreEquivalent(
         (PsiDoWhileStatement) statement1, (PsiDoWhileStatement) statement2);
   }
   if (statement1 instanceof PsiEmptyStatement) {
     return true;
   }
   if (statement1 instanceof PsiExpressionListStatement) {
     return expressionListStatementsAreEquivalent(
         (PsiExpressionListStatement) statement1, (PsiExpressionListStatement) statement2);
   }
   if (statement1 instanceof PsiExpressionStatement) {
     return expressionStatementsAreEquivalent(
         (PsiExpressionStatement) statement1, (PsiExpressionStatement) statement2);
   }
   if (statement1 instanceof PsiForStatement) {
     return forStatementsAreEquivalent((PsiForStatement) statement1, (PsiForStatement) statement2);
   }
   if (statement1 instanceof PsiForeachStatement) {
     return forEachStatementsAreEquivalent(
         (PsiForeachStatement) statement1, (PsiForeachStatement) statement2);
   }
   if (statement1 instanceof PsiIfStatement) {
     return ifStatementsAreEquivalent((PsiIfStatement) statement1, (PsiIfStatement) statement2);
   }
   if (statement1 instanceof PsiLabeledStatement) {
     return labeledStatementsAreEquivalent(
         (PsiLabeledStatement) statement1, (PsiLabeledStatement) statement2);
   }
   if (statement1 instanceof PsiReturnStatement) {
     return returnStatementsAreEquivalent(
         (PsiReturnStatement) statement1, (PsiReturnStatement) statement2);
   }
   if (statement1 instanceof PsiSwitchStatement) {
     return switchStatementsAreEquivalent(
         (PsiSwitchStatement) statement1, (PsiSwitchStatement) statement2);
   }
   if (statement1 instanceof PsiSwitchLabelStatement) {
     return switchLabelStatementsAreEquivalent(
         (PsiSwitchLabelStatement) statement1, (PsiSwitchLabelStatement) statement2);
   }
   if (statement1 instanceof PsiSynchronizedStatement) {
     return synchronizedStatementsAreEquivalent(
         (PsiSynchronizedStatement) statement1, (PsiSynchronizedStatement) statement2);
   }
   if (statement1 instanceof PsiThrowStatement) {
     return throwStatementsAreEquivalent(
         (PsiThrowStatement) statement1, (PsiThrowStatement) statement2);
   }
   if (statement1 instanceof PsiTryStatement) {
     return tryStatementsAreEquivalent((PsiTryStatement) statement1, (PsiTryStatement) statement2);
   }
   if (statement1 instanceof PsiWhileStatement) {
     return whileStatementsAreEquivalent(
         (PsiWhileStatement) statement1, (PsiWhileStatement) statement2);
   }
   final String text1 = statement1.getText();
   final String text2 = statement2.getText();
   return text1.equals(text2);
 }
 private static boolean blockStatementsAreEquivalent(
     @NotNull PsiBlockStatement statement1, @NotNull PsiBlockStatement statement2) {
   final PsiCodeBlock block1 = statement1.getCodeBlock();
   final PsiCodeBlock block2 = statement2.getCodeBlock();
   return codeBlocksAreEquivalent(block1, block2);
 }
 @Override
 public void doFix(Project project, ProblemDescriptor descriptor)
     throws IncorrectOperationException {
   final PsiReferenceExpression parameterReference =
       (PsiReferenceExpression) descriptor.getPsiElement();
   final PsiElement target = parameterReference.resolve();
   if (!(target instanceof PsiParameter)) {
     return;
   }
   final PsiParameter parameter = (PsiParameter) target;
   final PsiElement declarationScope = parameter.getDeclarationScope();
   final PsiElement body;
   if (declarationScope instanceof PsiMethod) {
     final PsiMethod method = (PsiMethod) declarationScope;
     body = method.getBody();
   } else if (declarationScope instanceof PsiCatchSection) {
     final PsiCatchSection catchSection = (PsiCatchSection) declarationScope;
     body = catchSection.getCatchBlock();
   } else if (declarationScope instanceof PsiLoopStatement) {
     final PsiLoopStatement forStatement = (PsiLoopStatement) declarationScope;
     final PsiStatement forBody = forStatement.getBody();
     if (forBody instanceof PsiBlockStatement) {
       final PsiBlockStatement blockStatement = (PsiBlockStatement) forBody;
       body = blockStatement.getCodeBlock();
     } else {
       body = forBody;
     }
   } else {
     return;
   }
   if (body == null) {
     return;
   }
   final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
   final String parameterName = parameterReference.getText();
   final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project);
   final String variableName =
       javaCodeStyleManager.suggestUniqueVariableName(parameterName, parameterReference, true);
   final SearchScope scope = parameter.getUseScope();
   final Query<PsiReference> search = ReferencesSearch.search(parameter, scope);
   final PsiReference reference = search.findFirst();
   if (reference == null) {
     return;
   }
   final PsiElement element = reference.getElement();
   if (!(element instanceof PsiReferenceExpression)) {
     return;
   }
   final PsiReferenceExpression firstReference = (PsiReferenceExpression) element;
   final PsiElement[] children = body.getChildren();
   final int startIndex;
   final int endIndex;
   if (body instanceof PsiCodeBlock) {
     startIndex = 1;
     endIndex = children.length - 1;
   } else {
     startIndex = 0;
     endIndex = children.length;
   }
   boolean newDeclarationCreated = false;
   final StringBuilder buffer = new StringBuilder();
   for (int i = startIndex; i < endIndex; i++) {
     final PsiElement child = children[i];
     newDeclarationCreated |=
         replaceVariableName(child, firstReference, variableName, parameterName, buffer);
   }
   final String replacementText;
   if (newDeclarationCreated) {
     replacementText = "{" + buffer + '}';
   } else {
     final PsiType type = parameterReference.getType();
     if (type == null) {
       return;
     }
     final String className = type.getCanonicalText();
     replacementText =
         '{' + className + ' ' + variableName + " = " + parameterName + ';' + buffer + '}';
   }
   final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
   final PsiCodeBlock block = elementFactory.createCodeBlockFromText(replacementText, null);
   body.replace(block);
   codeStyleManager.reformat(declarationScope);
 }