void (@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; @NonNls final 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) { final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)collection; final String collectionName = referenceElement.getReferenceName(); contentVariableName = ForCanBeForeachInspection.createNewVariableName(whileStatement, iteratorContentType, collectionName); } else { contentVariableName = ForCanBeForeachInspection.createNewVariableName(whileStatement, iteratorContentType, null); } statementToSkip = null; } CommentTracker ct = new CommentTracker(); @NonNls final 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); final Query<PsiReference> query = ReferencesSearch.search(iterator); boolean deleteIterator = true; for (PsiReference usage : query) { final PsiElement element = usage.getElement(); 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.moveTo(result); }