@Override
  public void performRefactoring(UsageInfo @NotNull [] usages) {
    logScopeStatistics(RenameUsagesCollector.executed);

    List<Runnable> postRenameCallbacks = new ArrayList<>();

    MultiMap<RefactoringElementListener, SmartPsiElementPointer<PsiElement>> renameEvents = MultiMap.createLinked();

    List<UsageInfo> usagesList = Arrays.asList(usages);
    MultiMap<PsiElement, UsageInfo> classified = classifyUsages(myAllRenames.keySet(), usagesList);

    NonCodeUsageInfo[] nonCodeUsages =
      ContainerUtil.filterIsInstance(usagesList, NonCodeUsageInfo.class).toArray(new NonCodeUsageInfo[0]);

    for (final PsiElement element : myAllRenames.keySet()) {
      if (!element.isValid()) {
        LOG.error(new PsiInvalidElementAccessException(element));
        continue;
      }
      String newName = myAllRenames.get(element);

      final RefactoringElementListener elementListener = getTransaction().getElementListener(element);
      final RenamePsiElementProcessor renamePsiElementProcessor = RenamePsiElementProcessor.forElement(element);
      Runnable postRenameCallback = renamePsiElementProcessor.getPostRenameCallback(element, newName, elementListener);
      Collection<UsageInfo> infos = classified.get(element);
      try {
        RenameUtil.registerUndoableRename(element, elementListener);
        renamePsiElementProcessor.renameElement(element, newName, infos.toArray(UsageInfo.EMPTY_ARRAY), new RefactoringElementListener() {
          @Override
          public void elementMoved(@NotNull PsiElement newElement) {
            throw new UnsupportedOperationException();
          }

          @Override
          public void elementRenamed(@NotNull PsiElement newElement) {
            if (!newElement.isValid()) return;
            renameEvents.putValue(elementListener, SmartPointerManager.createPointer(newElement));
          }
        });
      }
      catch (final IncorrectOperationException e) {
        RenameUtil.showErrorMessage(e, element, myProject);
        return;
      }
      if (postRenameCallback != null) {
        postRenameCallbacks.add(postRenameCallback);
      }
    }

    myNonCodeUsages = nonCodeUsages;

    afterRename(postRenameCallbacks, renameEvents);
  }
@Override
  public void performRefactoring(UsageInfo @NotNull [] usages)