@NotNull
  public UsageInfo[] findUsages() {
    myRenamers.clear();
    ArrayList<UsageInfo> result = new ArrayList<UsageInfo>();

    List<PsiElement> elements = new ArrayList<PsiElement>(myAllRenames.keySet());
    //noinspection ForLoopReplaceableByForEach
    for (int i = 0; i < elements.size(); i++) {
      PsiElement element = elements.get(i);
      final String newName = myAllRenames.get(element);
      final UsageInfo[] usages =
          RenameUtil.findUsages(
              element, newName, mySearchInComments, mySearchTextOccurrences, myAllRenames);
      final List<UsageInfo> usagesList = Arrays.asList(usages);
      result.addAll(usagesList);

      for (AutomaticRenamerFactory factory : myRenamerFactories) {
        if (factory.isApplicable(element)) {
          myRenamers.add(factory.createRenamer(element, newName, usagesList));
        }
      }

      for (AutomaticRenamerFactory factory :
          Extensions.getExtensions(AutomaticRenamerFactory.EP_NAME)) {
        if (factory.getOptionName() == null && factory.isApplicable(element)) {
          myRenamers.add(factory.createRenamer(element, newName, usagesList));
        }
      }
    }
    UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]);
    usageInfos = UsageViewUtil.removeDuplicatedUsages(usageInfos);
    return usageInfos;
  }
 protected void performPsiSpoilingRefactoring() {
   RenameUtil.renameNonCodeUsages(myProject, myNonCodeUsages);
 }
  public void performRefactoring(UsageInfo[] usages) {
    final int[] choice = myAllRenames.size() > 1 ? new int[] {-1} : null;
    String message = null;
    try {
      for (Iterator<Map.Entry<PsiElement, String>> iterator = myAllRenames.entrySet().iterator();
          iterator.hasNext(); ) {
        Map.Entry<PsiElement, String> entry = iterator.next();
        if (entry.getKey() instanceof PsiFile) {
          final PsiFile file = (PsiFile) entry.getKey();
          final PsiDirectory containingDirectory = file.getContainingDirectory();
          if (CopyFilesOrDirectoriesHandler.checkFileExist(
              containingDirectory, choice, file, entry.getValue(), "Rename")) {
            iterator.remove();
            continue;
          }
        }
        RenameUtil.checkRename(entry.getKey(), entry.getValue());
      }
    } catch (IncorrectOperationException e) {
      message = e.getMessage();
    }

    if (message != null) {
      CommonRefactoringUtil.showErrorMessage(
          RefactoringBundle.message("rename.title"), message, getHelpID(), myProject);
      return;
    }

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

    final MultiMap<PsiElement, UsageInfo> classified =
        classifyUsages(myAllRenames.keySet(), usages);
    for (final PsiElement element : myAllRenames.keySet()) {
      String newName = myAllRenames.get(element);

      final RefactoringElementListener elementListener =
          getTransaction().getElementListener(element);
      final RenamePsiElementProcessor renamePsiElementProcessor =
          RenamePsiElementProcessor.forElement(element);
      Runnable postRenameCallback =
          renamePsiElementProcessor.getPostRenameCallback(element, newName, elementListener);
      final Collection<UsageInfo> infos = classified.get(element);
      try {
        RenameUtil.doRename(
            element,
            newName,
            infos.toArray(new UsageInfo[infos.size()]),
            myProject,
            elementListener);
      } catch (final IncorrectOperationException e) {
        RenameUtil.showErrorMessage(e, element, myProject);
        return;
      }
      if (postRenameCallback != null) {
        postRenameCallbacks.add(postRenameCallback);
      }
    }

    for (Runnable runnable : postRenameCallbacks) {
      runnable.run();
    }

    List<NonCodeUsageInfo> nonCodeUsages = new ArrayList<NonCodeUsageInfo>();
    for (UsageInfo usage : usages) {
      if (usage instanceof NonCodeUsageInfo) {
        nonCodeUsages.add((NonCodeUsageInfo) usage);
      }
    }
    myNonCodeUsages = nonCodeUsages.toArray(new NonCodeUsageInfo[nonCodeUsages.size()]);
    if (!mySkippedUsages.isEmpty()) {
      if (!ApplicationManager.getApplication().isUnitTestMode()
          && !ApplicationManager.getApplication().isHeadlessEnvironment()) {
        ApplicationManager.getApplication()
            .invokeLater(
                new Runnable() {
                  public void run() {
                    final IdeFrame ideFrame = WindowManager.getInstance().getIdeFrame(myProject);
                    if (ideFrame != null) {

                      StatusBarEx statusBar = (StatusBarEx) ideFrame.getStatusBar();
                      HyperlinkListener listener =
                          new HyperlinkListener() {
                            public void hyperlinkUpdate(HyperlinkEvent e) {
                              if (e.getEventType() != HyperlinkEvent.EventType.ACTIVATED) return;
                              Messages.showMessageDialog(
                                  "<html>"
                                      + StringUtil.join(
                                          mySkippedUsages,
                                          new Function<UnresolvableCollisionUsageInfo, String>() {
                                            public String fun(
                                                UnresolvableCollisionUsageInfo
                                                    unresolvableCollisionUsageInfo) {
                                              return unresolvableCollisionUsageInfo
                                                  .getDescription();
                                            }
                                          },
                                          "<br>")
                                      + "</html>",
                                  "Don't panic! They are safe to skip",
                                  null);
                            }
                          };
                      statusBar.notifyProgressByBalloon(
                          MessageType.WARNING,
                          "<html><body>Unable to rename certain usages. <a href=\"\">Browse</a></body></html>",
                          null,
                          listener);
                    }
                  }
                },
                ModalityState.NON_MODAL);
      }
    }
  }
  public boolean preprocessUsages(final Ref<UsageInfo[]> refUsages) {
    UsageInfo[] usagesIn = refUsages.get();
    MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();

    RenameUtil.addConflictDescriptions(usagesIn, conflicts);
    RenamePsiElementProcessor.forElement(myPrimaryElement)
        .findExistingNameConflicts(myPrimaryElement, myNewName, conflicts);
    if (!conflicts.isEmpty()) {
      if (ApplicationManager.getApplication().isUnitTestMode()) {
        throw new ConflictsInTestsException(conflicts.values());
      }
      ConflictsDialog conflictsDialog = prepareConflictsDialog(conflicts, refUsages.get());
      conflictsDialog.show();
      if (!conflictsDialog.isOK()) {
        if (conflictsDialog.isShowConflicts()) prepareSuccessful();
        return false;
      }
    }

    final List<UsageInfo> variableUsages = new ArrayList<UsageInfo>();
    if (!myRenamers.isEmpty()) {
      if (!findRenamedVariables(variableUsages)) return false;
      final LinkedHashMap<PsiElement, String> renames = new LinkedHashMap<PsiElement, String>();
      for (final AutomaticRenamer renamer : myRenamers) {
        final List<? extends PsiNamedElement> variables = renamer.getElements();
        for (final PsiNamedElement variable : variables) {
          final String newName = renamer.getNewName(variable);
          if (newName != null) {
            addElement(variable, newName);
            prepareRenaming(variable, newName, renames);
          }
        }
      }
      if (!renames.isEmpty()) {
        myAllRenames.putAll(renames);
        final Runnable runnable =
            new Runnable() {
              public void run() {
                for (Map.Entry<PsiElement, String> entry : renames.entrySet()) {
                  final UsageInfo[] usages =
                      RenameUtil.findUsages(
                          entry.getKey(),
                          entry.getValue(),
                          mySearchInComments,
                          mySearchTextOccurrences,
                          myAllRenames);
                  Collections.addAll(variableUsages, usages);
                }
              }
            };
        if (!ProgressManager.getInstance()
            .runProcessWithProgressSynchronously(
                runnable, RefactoringBundle.message("searching.for.variables"), true, myProject)) {
          return false;
        }
      }
    }

    final Set<UsageInfo> usagesSet = new HashSet<UsageInfo>(Arrays.asList(usagesIn));
    usagesSet.addAll(variableUsages);
    final List<UnresolvableCollisionUsageInfo> conflictUsages =
        RenameUtil.removeConflictUsages(usagesSet);
    if (conflictUsages != null) {
      mySkippedUsages.addAll(conflictUsages);
    }
    refUsages.set(usagesSet.toArray(new UsageInfo[usagesSet.size()]));

    prepareSuccessful();
    return true;
  }