protected void doRun() {
    PsiDocumentManager.getInstance(myProject).commitAllDocuments();
    final Ref<UsageInfo[]> refUsages = new Ref<>();
    final Ref<Language> refErrorLanguage = new Ref<>();
    final Ref<Boolean> refProcessCanceled = new Ref<>();
    final Ref<Boolean> anyException = new Ref<>();

    final Runnable findUsagesRunnable =
        new Runnable() {
          @Override
          public void run() {
            try {
              refUsages.set(
                  DumbService.getInstance(myProject)
                      .runReadActionInSmartMode(
                          new Computable<UsageInfo[]>() {
                            @Override
                            public UsageInfo[] compute() {
                              return findUsages();
                            }
                          }));
            } catch (UnknownReferenceTypeException e) {
              refErrorLanguage.set(e.getElementLanguage());
            } catch (ProcessCanceledException e) {
              refProcessCanceled.set(Boolean.TRUE);
            } catch (Throwable e) {
              anyException.set(Boolean.TRUE);
              LOG.error(e);
            }
          }
        };

    if (!ProgressManager.getInstance()
        .runProcessWithProgressSynchronously(
            findUsagesRunnable, RefactoringBundle.message("progress.text"), true, myProject)) {
      return;
    }

    if (!refErrorLanguage.isNull()) {
      Messages.showErrorDialog(
          myProject,
          RefactoringBundle.message(
              "unsupported.refs.found", refErrorLanguage.get().getDisplayName()),
          RefactoringBundle.message("error.title"));
      return;
    }
    if (DumbService.isDumb(myProject)) {
      DumbService.getInstance(myProject)
          .showDumbModeNotification("Refactoring is not available until indices are ready");
      return;
    }
    if (!refProcessCanceled.isNull()) {
      Messages.showErrorDialog(
          myProject,
          "Index corruption detected. Please retry the refactoring - indexes will be rebuilt automatically",
          RefactoringBundle.message("error.title"));
      return;
    }

    if (!anyException.isNull()) {
      // do not proceed if find usages fails
      return;
    }
    assert !refUsages.isNull() : "Null usages from processor " + this;
    if (!preprocessUsages(refUsages)) return;
    final UsageInfo[] usages = refUsages.get();
    assert usages != null;
    UsageViewDescriptor descriptor = createUsageViewDescriptor(usages);

    boolean isPreview = isPreviewUsages(usages);
    if (!isPreview) {
      isPreview =
          !ensureElementsWritable(usages, descriptor) || UsageViewUtil.hasReadOnlyUsages(usages);
      if (isPreview) {
        StatusBarUtil.setStatusBarInfo(
            myProject, RefactoringBundle.message("readonly.occurences.found"));
      }
    }
    if (isPreview) {
      for (UsageInfo usage : usages) {
        LOG.assertTrue(usage != null, getClass());
      }
      previewRefactoring(usages);
    } else {
      execute(usages);
    }
  }