void (@NotNull Project project, @NotNull PsiElement tailCallToken, @NotNull ModPsiUpdater updater) { final PsiMethod method = PsiTreeUtil.getParentOfType(tailCallToken, PsiMethod.class, true, PsiClass.class, PsiLambdaExpression.class); if (method == null) { return; } final PsiCodeBlock body = method.getBody(); if (body == null) { return; } @NonNls final StringBuilder builder = new StringBuilder(); builder.append('{'); final PsiClass containingClass = method.getContainingClass(); if (containingClass == null) { return; } final String thisVariableName; final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(project); if (methodReturnsContainingClassType(method, containingClass)) { builder.append(containingClass.getName()); thisVariableName = styleManager.suggestUniqueVariableName("result", method, false); builder.append(' ').append(thisVariableName).append(" = this;"); } else if (methodContainsCallOnOtherInstance(method)) { builder.append(containingClass.getName()); thisVariableName = styleManager.suggestUniqueVariableName("other", method, false); builder.append(' ').append(thisVariableName).append(" = this;"); } else { thisVariableName = null; } final boolean tailCallIsContainedInLoop; if (ControlFlowUtils.isInLoop(tailCallToken)) { tailCallIsContainedInLoop = true; builder.append(method.getName()).append(':'); } else { tailCallIsContainedInLoop = false; } builder.append("while(true)"); final boolean methodMayCompleteNormally = ControlFlowUtils.methodMayCompleteNormally(method); replaceTailCalls(body, method, thisVariableName, tailCallIsContainedInLoop, methodMayCompleteNormally, builder); if (methodMayCompleteNormally) { builder.insert(builder.length() - 1, "return;"); } builder.append('}'); final PsiCodeBlock block = JavaPsiFacade.getElementFactory(project).createCodeBlockFromText(builder.toString(), method); removeEmptyElse(block); CodeStyleManager.getInstance(project).reformat(body.replace(block)); }