private UsageView doSearchAndShow(UsageTarget @NotNull [] searchFor,
                                    @NotNull Supplier<? extends UsageSearcher> searcherFactory,
                                    @NotNull UsageViewPresentation presentation,
                                    @NotNull FindUsagesProcessPresentation processPresentation,
                                    @Nullable UsageViewStateListener listener) {
    if (ApplicationManager.getApplication().isWriteAccessAllowed()) {
      throw new IllegalStateException("Can't start find usages from under write action. Please consider Application.invokeLater() it instead.");
    }
    Supplier<SearchScope> scopeSupplier = getMaxSearchScopeToWarnOfFallingOutOf(searchFor);
    AtomicReference<UsageViewEx> usageViewRef = new AtomicReference<>();
    long start = System.nanoTime();
    AtomicLong firstItemFoundTS = new AtomicLong();
    AtomicBoolean tooManyUsages = new AtomicBoolean();
    Task.Backgroundable task = new Task.Backgroundable(project, getProgressTitle(presentation), true, new SearchInBackgroundOption()) {
      @Override
      public void run(@NotNull ProgressIndicator indicator) {
        SearchScope searchScopeToWarnOfFallingOutOf = ReadAction.compute(() -> scopeSupplier.get());
        new SearchForUsagesRunnable(UsageViewManagerImpl.this, UsageViewManagerImpl.this.project, usageViewRef, presentation, searchFor, searcherFactory,
                                    processPresentation, searchScopeToWarnOfFallingOutOf, listener, firstItemFoundTS, tooManyUsages).run();
      }

      @Override
      public void onCancel() {
        reportSearchCompletedToFus(true);
        super.onCancel();
      }

      @NotNull
      @Override
      public NotificationInfo getNotificationInfo() {
        UsageViewEx usageView = usageViewRef.get();
        int count = usageView == null ? 0 : usageView.getUsagesCount();
        long duration = reportSearchCompletedToFus(false);
        String notification = StringUtil.capitalizeWords(UsageViewBundle.message("usages.n", count), true);
        LOG.debug(notification + " in " + duration + "ms.");
        return new NotificationInfo("Find Usages", UsageViewBundle.message("notification.title.find.usages.finished"), notification);
      }

      private long reportSearchCompletedToFus(boolean isCancelled) {
        long currentTS = System.nanoTime();
        long durationFirstResults = TimeUnit.NANOSECONDS.toMillis(firstItemFoundTS.get() - start);
        long duration = TimeUnit.NANOSECONDS.toMillis(currentTS - start);


        PsiElement element = SearchForUsagesRunnable.getPsiElement(searchFor);
        UsageViewEx view = usageViewRef.get();
        Class<? extends PsiElement> targetClass = element != null ? element.getClass() : null;
        Language language = element != null ? ReadAction.compute(element::getLanguage) : null;
        SearchScope scope = null;
        if (element instanceof DataProvider) {
          scope = UsageView.USAGE_SCOPE.getData((DataProvider)element);
        }
        int numberOfUsagesFound = view == null ? 0 : view.getUsagesCount();
        UsageViewStatisticsCollector.logSearchFinished(myProject, view, targetClass, scope, language, numberOfUsagesFound,
                                                       durationFirstResults, duration,
                                                       tooManyUsages.get(), isCancelled, CodeNavigateSource.FindToolWindow);
        return duration;
      }
    };
    ProgressManager.getInstance().run(task);
    return usageViewRef.get();
  }
private UsageView doSearchAndShow(UsageTarget @NotNull [] searchFor,
                                    @NotNull Supplier<? extends UsageSearcher> searcherFactory,
                                    @NotNull UsageViewPresentation presentation,
                                    @NotNull FindUsagesProcessPresentation processPresentation,
                                    @Nullable UsageViewStateListener listener)