private static void retargetReferences(
     final PsiElementFactory elementFactory,
     final String localName,
     final Set<PsiReference> refs)
     throws IncorrectOperationException {
   final PsiReferenceExpression refExpr =
       (PsiReferenceExpression) elementFactory.createExpressionFromText(localName, null);
   for (PsiReference ref : refs) {
     if (ref instanceof PsiReferenceExpression) {
       ((PsiReferenceExpression) ref).replace(refExpr);
     }
   }
 }
    private PsiElement addDeclarationWithFieldInitializerAndRetargetReferences(
        final PsiElementFactory elementFactory,
        final String localName,
        final PsiCodeBlock anchorBlock,
        final PsiElement anchor,
        final Set<PsiReference> refs)
        throws IncorrectOperationException {
      final PsiDeclarationStatement decl =
          elementFactory.createVariableDeclarationStatement(
              localName, myField.getType(), myField.getInitializer());
      final PsiElement newDeclaration = anchorBlock.addBefore(decl, anchor);

      retargetReferences(elementFactory, localName, refs);
      return newDeclaration;
    }
    @Override
    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
      final PsiForeachStatement foreachStatement =
          PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiForeachStatement.class);
      if (foreachStatement != null) {
        if (!FileModificationService.getInstance().preparePsiElementForWrite(foreachStatement))
          return;
        final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
        PsiStatement body = foreachStatement.getBody();
        final PsiExpression iteratedValue = foreachStatement.getIteratedValue();
        if (body != null && iteratedValue != null) {
          final PsiParameter parameter = foreachStatement.getIterationParameter();
          final PsiIfStatement ifStatement = extractIfStatement(body);
          final PsiMethodCallExpression methodCallExpression = extractAddCall(body, ifStatement);

          if (methodCallExpression == null) return;

          if (isAddAllCall(foreachStatement, body)) {
            restoreComments(foreachStatement, body);
            final PsiExpression qualifierExpression =
                methodCallExpression.getMethodExpression().getQualifierExpression();
            final String qualifierText =
                qualifierExpression != null ? qualifierExpression.getText() : "";
            final String callText =
                StringUtil.getQualifiedName(
                    qualifierText, "addAll(" + getIteratedValueText(iteratedValue) + ");");
            PsiElement result =
                foreachStatement.replace(
                    elementFactory.createStatementFromText(callText, foreachStatement));
            reformatWhenNeeded(project, result);
            return;
          }
          final StringBuilder builder =
              new StringBuilder(getIteratedValueText(iteratedValue) + ".stream()");

          builder.append(createFiltersChainText(body, parameter, ifStatement));
          builder.append(
              createMapperFunctionalExpressionText(
                  parameter, methodCallExpression.getArgumentList().getExpressions()[0]));

          builder.append(".collect(java.util.stream.Collectors.");
          PsiElement result = null;
          try {
            final PsiExpression qualifierExpression =
                methodCallExpression.getMethodExpression().getQualifierExpression();
            if (qualifierExpression instanceof PsiReferenceExpression) {
              final PsiElement resolve = ((PsiReferenceExpression) qualifierExpression).resolve();
              if (resolve instanceof PsiVariable) {
                if (resolve instanceof PsiLocalVariable
                    && foreachStatement.equals(
                        PsiTreeUtil.skipSiblingsForward(
                            resolve.getParent(), PsiWhiteSpace.class))) {
                  final PsiExpression initializer = ((PsiVariable) resolve).getInitializer();
                  if (initializer instanceof PsiNewExpression) {
                    final PsiExpressionList argumentList =
                        ((PsiNewExpression) initializer).getArgumentList();
                    if (argumentList != null && argumentList.getExpressions().length == 0) {
                      restoreComments(foreachStatement, body);
                      final String callText =
                          builder.toString()
                              + createInitializerReplacementText(
                                  ((PsiVariable) resolve).getType(), initializer)
                              + ")";
                      result =
                          initializer.replace(
                              elementFactory.createExpressionFromText(callText, null));
                      simplifyRedundantCast(result);
                      foreachStatement.delete();
                      return;
                    }
                  }
                }
              }
            }
            restoreComments(foreachStatement, body);
            final String qualifierText =
                qualifierExpression != null ? qualifierExpression.getText() : "";
            final String callText =
                StringUtil.getQualifiedName(
                    qualifierText, "addAll(" + builder.toString() + "toList()));");
            result =
                foreachStatement.replace(
                    elementFactory.createStatementFromText(callText, foreachStatement));
            simplifyRedundantCast(result);
          } finally {
            reformatWhenNeeded(project, result);
          }
        }
      }
    }
    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
      if (!myField.isValid()) return; // weird. should not get here when field becomes invalid

      final Collection<PsiReference> refs = ReferencesSearch.search(myField).findAll();
      if (refs.isEmpty()) return;
      Set<PsiReference> refsSet = new HashSet<PsiReference>(refs);
      PsiCodeBlock anchorBlock = findAnchorBlock(refs);
      if (anchorBlock == null)
        return; // was assert, but need to fix the case when obsolete inspection highlighting is
                // left
      if (!CodeInsightUtil.preparePsiElementsForWrite(anchorBlock)) return;
      final PsiElementFactory elementFactory =
          JavaPsiFacade.getInstance(project).getElementFactory();
      final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(project);
      final String propertyName =
          styleManager.variableNameToPropertyName(myField.getName(), VariableKind.FIELD);
      String localName =
          styleManager.propertyNameToVariableName(propertyName, VariableKind.LOCAL_VARIABLE);
      localName = RefactoringUtil.suggestUniqueVariableName(localName, anchorBlock, myField);
      PsiElement firstElement = getFirstElement(refs);
      boolean mayBeFinal = mayBeFinal(refsSet, firstElement);
      PsiElement newDeclaration = null;
      try {
        final PsiElement anchor = getAnchorElement(anchorBlock, firstElement);
        if (anchor instanceof PsiExpressionStatement
            && ((PsiExpressionStatement) anchor).getExpression()
                instanceof PsiAssignmentExpression) {
          final PsiAssignmentExpression expression =
              (PsiAssignmentExpression) ((PsiExpressionStatement) anchor).getExpression();
          if (expression.getOperationTokenType() == JavaTokenType.EQ
              && expression.getLExpression() instanceof PsiReferenceExpression
              && ((PsiReference) expression.getLExpression()).isReferenceTo(myField)) {
            final PsiExpression initializer = expression.getRExpression();
            final PsiDeclarationStatement decl =
                elementFactory.createVariableDeclarationStatement(
                    localName, myField.getType(), initializer);
            if (!mayBeFinal) {
              PsiUtil.setModifierProperty(
                  ((PsiModifierListOwner) decl.getDeclaredElements()[0]), PsiModifier.FINAL, false);
            }
            newDeclaration = anchor.replace(decl);
            refsSet.remove(expression.getLExpression());
            retargetReferences(elementFactory, localName, refsSet);
          } else {
            newDeclaration =
                addDeclarationWithFieldInitializerAndRetargetReferences(
                    elementFactory, localName, anchorBlock, anchor, refsSet);
          }
        } else {
          newDeclaration =
              addDeclarationWithFieldInitializerAndRetargetReferences(
                  elementFactory, localName, anchorBlock, anchor, refsSet);
        }
      } catch (IncorrectOperationException e) {
        LOG.error(e);
      }

      if (newDeclaration != null) {
        final PsiFile psiFile = myField.getContainingFile();
        final Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
        if (editor != null && IJSwingUtilities.hasFocus(editor.getComponent())) {
          final PsiFile file =
              PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
          if (file == psiFile) {
            editor.getCaretModel().moveToOffset(newDeclaration.getTextOffset());
            editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
          }
        }
      }

      try {
        myField.normalizeDeclaration();
        myField.delete();
      } catch (IncorrectOperationException e) {
        LOG.error(e);
      }
    }
    @Override
    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
      final PsiForeachStatement foreachStatement =
          PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiForeachStatement.class);
      if (foreachStatement != null) {
        if (!FileModificationService.getInstance().preparePsiElementForWrite(foreachStatement))
          return;
        PsiStatement body = foreachStatement.getBody();
        final PsiExpression iteratedValue = foreachStatement.getIteratedValue();
        if (body != null && iteratedValue != null) {
          restoreComments(foreachStatement, body);

          final PsiParameter parameter = foreachStatement.getIterationParameter();
          final PsiIfStatement ifStmt = extractIfStatement(body);

          StringBuilder buffer = new StringBuilder(getIteratedValueText(iteratedValue));
          if (ifStmt != null) {
            final PsiStatement thenBranch = ifStmt.getThenBranch();
            LOG.assertTrue(thenBranch != null);
            buffer.append(".stream()");
            buffer.append(createFiltersChainText(body, parameter, ifStmt));
            body = thenBranch;
          }

          buffer.append(".").append(getForEachMethodName()).append("(");

          final String functionalExpressionText =
              createForEachFunctionalExpressionText(project, body, parameter);
          final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
          PsiExpressionStatement callStatement =
              (PsiExpressionStatement)
                  elementFactory.createStatementFromText(
                      buffer.toString() + functionalExpressionText + ");", foreachStatement);
          callStatement = (PsiExpressionStatement) foreachStatement.replace(callStatement);

          final PsiExpressionList argumentList =
              ((PsiCallExpression) callStatement.getExpression()).getArgumentList();
          LOG.assertTrue(argumentList != null, callStatement.getText());
          final PsiExpression[] expressions = argumentList.getExpressions();
          LOG.assertTrue(expressions.length == 1);

          if (expressions[0] instanceof PsiFunctionalExpression
              && ((PsiFunctionalExpression) expressions[0]).getFunctionalInterfaceType() == null) {
            callStatement =
                (PsiExpressionStatement)
                    callStatement.replace(
                        elementFactory.createStatementFromText(
                            buffer.toString()
                                + "("
                                + parameter.getText()
                                + ") -> "
                                + wrapInBlock(body)
                                + ");",
                            callStatement));
          }

          simplifyRedundantCast(callStatement);

          CodeStyleManager.getInstance(project)
              .reformat(
                  JavaCodeStyleManager.getInstance(project).shortenClassReferences(callStatement));
        }
      }
    }