void (@NotNull Project project, @NotNull PsiElement startElement, @NotNull ModPsiUpdater updater) { PsiExpression expression = PsiTreeUtil.getParentOfType(startElement, PsiExpression.class); if (expression == null) return; PsiVariable variable = getAppendedVariable(expression); if (variable == null) return; PsiLoopStatement loop = getOutermostCommonLoop(expression, variable); if (loop == null) return; ControlFlowUtils.InitializerUsageStatus status = ControlFlowUtils.getInitializerUsageStatus(variable, loop); JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project); String newName = javaCodeStyleManager.suggestUniqueVariableName(variable.getName() + "Builder", loop, true); String newStringBuilder = myTargetType + " " + newName + "=new " + myTargetType + "(" + variable.getName() + ");"; PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); Object marker = new Object(); PsiTreeUtil.mark(loop, marker); PsiDeclarationStatement declaration = (PsiDeclarationStatement)BlockUtils.addBefore(loop, factory.createStatementFromText(newStringBuilder, loop)); if (!loop.isValid()) { loop = (PsiLoopStatement)PsiTreeUtil.releaseMark(declaration.getParent(), marker); if (loop == null) return; } PsiVariable builderVariable = (PsiVariable)declaration.getDeclaredElements()[0]; PsiExpression builderInitializer = Objects.requireNonNull(builderVariable.getInitializer()); CommentTracker ct = new CommentTracker(); StringBuilderReplacer replacer = new StringBuilderReplacer(myTargetType, myNullSafe); replacer.replaceAll(variable, builderVariable, loop, ct); String convertToString = myNullSafe ? CommonClassNames.JAVA_LANG_STRING + ".valueOf(" + newName + ")" : newName + ".toString()"; @NonNls String toString = variable.getName() + " = " + convertToString + ";"; PsiExpression initializer = variable.getInitializer(); switch (status) { case DECLARED_JUST_BEFORE -> { // Put original variable declaration after the loop and use its original initializer in StringBuilder constructor PsiTypeElement typeElement = variable.getTypeElement(); if (typeElement != null && initializer != null) { javaCodeStyleManager.shortenClassReferences(ct.replace(builderInitializer, replacer.generateNewStringBuilder(initializer, ct))); ct.replace(initializer, convertToString); toString = variable.getText(); ct.delete(variable); } } case AT_WANTED_PLACE_ONLY -> { // Move original initializer to the StringBuilder constructor if (initializer != null) { javaCodeStyleManager.shortenClassReferences(ct.replace(builderInitializer, replacer.generateNewStringBuilder(initializer, ct))); initializer.delete(); } } case AT_WANTED_PLACE -> { // Copy original initializer to the StringBuilder constructor if possible if (ExpressionUtils.isSafelyRecomputableExpression(initializer)) { javaCodeStyleManager.shortenClassReferences(ct.replace(builderInitializer, replacer.generateNewStringBuilder(initializer, ct))); } } case UNKNOWN -> { PsiElement prevStatement = PsiTreeUtil.skipWhitespacesAndCommentsBackward(declaration); PsiExpression prevAssignment = ExpressionUtils.getAssignmentTo(prevStatement, variable); if (prevAssignment != null) { javaCodeStyleManager .shortenClassReferences(ct.replace(builderInitializer, replacer.generateNewStringBuilder(prevAssignment, ct))); ct.delete(prevStatement); } } } BlockUtils.addAfter(loop, factory.createStatementFromText(toString, loop)); ct.insertCommentsBefore(loop); }