@Override
    protected void applyFix(@NotNull Project project, @NotNull PsiElement whileElement, @NotNull ModPsiUpdater updater) {
      final PsiWhileStatement whileStatement = (PsiWhileStatement)whileElement.getParent();
      final PsiStatement body = whileStatement.getBody();
      if (body == null) {
        return;
      }
      final PsiStatement initialization = getPreviousStatement(whileStatement);
      final PsiDeclarationStatement declaration = (PsiDeclarationStatement)initialization;
      if (declaration == null) {
        return;
      }
      final PsiElement declaredElement = declaration.getDeclaredElements()[0];
      if (!(declaredElement instanceof PsiLocalVariable iterator)) {
        return;
      }
      final PsiMethodCallExpression initializer = (PsiMethodCallExpression)PsiUtil.skipParenthesizedExprDown(iterator.getInitializer());
      if (initializer == null) {
        return;
      }
      final PsiReferenceExpression methodExpression = initializer.getMethodExpression();
      final PsiExpression collection = PsiUtil.skipParenthesizedExprDown(ExpressionUtils.getEffectiveQualifier(methodExpression));
      if (collection == null) {
        return;
      }
      final PsiType collectionType = collection.getType();
      if (collectionType == null) {
        return;
      }
      final PsiType contentType = ForCanBeForeachInspection.getContentType(collectionType, CommonClassNames.JAVA_LANG_ITERABLE);
      if (contentType == null) {
        return;
      }
      PsiType iteratorContentType = ForCanBeForeachInspection.getContentType(iterator.getType(), CommonClassNames.JAVA_UTIL_ITERATOR);
      if (TypeUtils.isJavaLangObject(iteratorContentType)) {
        iteratorContentType = ForCanBeForeachInspection.getContentType(initializer.getType(), CommonClassNames.JAVA_UTIL_ITERATOR);
      }
      if (iteratorContentType == null) {
        return;
      }
      final PsiStatement firstStatement = ForCanBeForeachInspection.getFirstStatement(body);
      final boolean isDeclaration = ForCanBeForeachInspection.isIteratorNextDeclaration(firstStatement, iterator, contentType);
      final PsiStatement statementToSkip;
      final @NonNls String contentVariableName;
      if (isDeclaration) {
        final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)firstStatement;
        final PsiElement[] declaredElements = declarationStatement.getDeclaredElements();
        final PsiLocalVariable localVariable = (PsiLocalVariable)declaredElements[0];
        contentVariableName = localVariable.getName();
        iteratorContentType = localVariable.getType();
        statementToSkip = declarationStatement;
      }
      else {
        if (collection instanceof PsiReferenceExpression referenceElement) {
          final String collectionName = referenceElement.getReferenceName();
          contentVariableName = ForCanBeForeachInspection.createNewVariableName(whileStatement, iteratorContentType, collectionName);
        }
        else {
          contentVariableName = ForCanBeForeachInspection.createNewVariableName(whileStatement, iteratorContentType, null);
        }
        statementToSkip = null;
      }
      CommentTracker ct = new CommentTracker();
      final @NonNls StringBuilder newStatement = new StringBuilder();
      newStatement.append("for(");
      if (JavaCodeStyleSettings.getInstance(whileStatement.getContainingFile()).GENERATE_FINAL_PARAMETERS) {
        newStatement.append("final ");
      }
      final String canonicalText = iteratorContentType.getCanonicalText();
      newStatement.append(canonicalText).append(' ').append(contentVariableName).append(": ");
      if (!TypeConversionUtil.isAssignable(iteratorContentType, contentType)) {
        newStatement.append("(java.lang.Iterable<").append(canonicalText).append(">)");
      }
      newStatement.append(ct.text(collection)).append(')');

      ForCanBeForeachInspection.replaceIteratorNext(body, contentVariableName, iterator, contentType, statementToSkip, ct, newStatement);
      boolean deleteIterator = true;
      for (PsiReferenceExpression element : VariableAccessUtils.getVariableReferences(iterator)) {
        if (PsiTreeUtil.isAncestor(whileStatement, element, true)) {
          continue;
        }
        final PsiAssignmentExpression assignment = PsiTreeUtil.getParentOfType(element, PsiAssignmentExpression.class);
        if (assignment == null) {
          // iterator is read after while loop,
          // so cannot be deleted
          deleteIterator = false;
          break;
        }
        final PsiExpression expression = assignment.getRExpression();
        final PsiTypeElement typeElement = iterator.getTypeElement();
        if (typeElement.isInferredType() &&
            (expression == null ||
             PsiTypes.nullType().equals(expression.getType()) ||
             expression instanceof PsiArrayInitializerExpression ||
             expression instanceof PsiFunctionalExpression) &&     
            PsiTypesUtil.replaceWithExplicitType(typeElement) == null) {
          deleteIterator = false;
          break;
        }
        iterator.setInitializer(expression);
        final PsiElement statement = assignment.getParent();
        final PsiElement lastChild = statement.getLastChild();
        if (lastChild instanceof PsiComment) {
          iterator.add(lastChild);
        }
        statement.replace(iterator);
        break;
      }
      if (deleteIterator) {
        new CommentTracker().deleteAndRestoreComments(iterator);
      }
      PsiElement result = ct.replaceAndRestoreComments(whileStatement, newStatement.toString());
      updater.moveCaretTo(result);
    }
@Override
    protected void applyFix(@NotNull Project project, @NotNull PsiElement whileElement, @NotNull ModPsiUpdater updater)