void (final UsageInfo @NotNull [] usages) { final PsiManager manager = PsiManager.getInstance(myProject); final PsiElementFactory factory = JavaPsiFacade.getElementFactory(manager.getProject()); final RefactoringElementListener elementListener = getTransaction().getElementListener(myInnerClass); try { PsiField field = null; if (myParameterNameOuterClass != null) { // pass outer as a parameter field = createOuterField(factory); field = addOuterField(field); myInnerClass = field.getContainingClass(); addFieldInitializationToConstructors(Objects.requireNonNull(myInnerClass), field, myParameterNameOuterClass); } ChangeContextUtil.encodeContextInfo(myInnerClass, false); myInnerClass = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(myInnerClass); final MoveInnerOptions moveInnerOptions = new MoveInnerOptions(myInnerClass, myOuterClass, myTargetContainer, myNewClassName); final MoveInnerHandler handler = MoveInnerHandler.EP_NAME.forLanguage(myInnerClass.getLanguage()); final PsiClass newClass; try { newClass = handler.copyClass(moveInnerOptions); } catch (IncorrectOperationException e) { RefactoringUIUtil.processIncorrectOperation(myProject, e); return; } // replace references in a new class to old inner class with references to itself for (PsiReference ref : ReferencesSearch.search(myInnerClass, new LocalSearchScope(newClass.getContainingFile()), true)) { PsiElement element = ref.getElement(); if (element.getParent() instanceof PsiJavaCodeReferenceElement parentRef) { PsiElement parentRefElement = parentRef.resolve(); if (parentRefElement instanceof PsiClass) { // reference to inner class inside our inner PsiImportStatementBase insertedImport = PsiTreeUtil.getParentOfType(parentRef, PsiImportStatementBase.class); if (insertedImport != null) { insertedImport.delete(); continue; } final PsiReferenceList referenceList = PsiTreeUtil.getTopmostParentOfType(parentRef, PsiReferenceList.class); if (referenceList == null || referenceList.getParent() != newClass) { parentRef.getQualifier().delete(); continue; } } } ref.bindToElement(newClass); } List<PsiReference> referencesToRebind = new ArrayList<>(); for (UsageInfo usage : usages) { if (usage.isNonCodeUsage) continue; PsiElement refElement = usage.getElement(); if (refElement != null) { PsiReference[] references = refElement.getReferences(); for (PsiReference reference : references) { if (reference.isReferenceTo(myInnerClass)) { referencesToRebind.add(reference); } } } } myInnerClass.delete(); // correct references in usages for (UsageInfo usage : usages) { if (usage.isNonCodeUsage) continue; // should pass outer as parameter PsiElement element = usage.getElement(); if (element == null) continue; MoveInnerClassUsagesHandler usagesHandler = MoveInnerClassUsagesHandler.EP_NAME.forLanguage(element.getLanguage()); if (usagesHandler != null) { usagesHandler.correctInnerClassUsage(usage, myOuterClass, myParameterNameOuterClass); } } for (PsiReference reference : referencesToRebind) { reference.bindToElement(newClass); } for (UsageInfo usage : usages) { final PsiElement element = usage.getElement(); final PsiElement parent = element != null ? element.getParent() : null; if (parent instanceof PsiNewExpression) { final PsiMethod resolveConstructor = ((PsiNewExpression)parent).resolveConstructor(); for (PsiMethod method : newClass.getConstructors()) { if (resolveConstructor == method) { final PsiElement place = usage.getElement(); if (place != null) { VisibilityUtil.escalateVisibility(method, place); } break; } } } } if (field != null) { final PsiExpression paramAccessExpression = factory.createExpressionFromText(myParameterNameOuterClass, null); for (final PsiMethod constructor : newClass.getConstructors()) { final PsiStatement[] statements = Objects.requireNonNull(constructor.getBody()).getStatements(); if (statements.length > 0) { if (statements[0] instanceof PsiExpressionStatement) { PsiExpression expression = ((PsiExpressionStatement)statements[0]).getExpression(); if (expression instanceof PsiMethodCallExpression) { @NonNls String text = ((PsiMethodCallExpression)expression).getMethodExpression().getText(); if ("this".equals(text) || "super".equals(text)) { ChangeContextUtil.decodeContextInfo(expression, myOuterClass, paramAccessExpression); } } } } } PsiExpression accessExpression = factory.createExpressionFromText(myFieldNameOuterClass, null); ChangeContextUtil.decodeContextInfo(newClass, myOuterClass, accessExpression); } else { ChangeContextUtil.decodeContextInfo(newClass, null, null); } if (myOpenInEditor) { EditorHelper.openInEditor(newClass); } if (myMoveCallback != null) { myMoveCallback.refactoringCompleted(); } elementListener.elementMoved(newClass); List<NonCodeUsageInfo> nonCodeUsages = new ArrayList<>(); for (UsageInfo usage : usages) { if (usage instanceof NonCodeUsageInfo) { nonCodeUsages.add((NonCodeUsageInfo)usage); } } myNonCodeUsages = nonCodeUsages.toArray(new NonCodeUsageInfo[0]); } catch (IncorrectOperationException e) { LOG.error(e); } }