private void doShowDialogAndStartFind(
      @NotNull PsiElement psiElement,
      PsiFile scopeFile,
      FileEditor editor,
      boolean showDialog,
      boolean useMaximalScope) {
    FindUsagesHandler handler = getNewFindUsagesHandler(psiElement, false);
    if (handler == null) return;

    boolean singleFile = scopeFile != null;
    AbstractFindUsagesDialog dialog =
        handler.getFindUsagesDialog(singleFile, shouldOpenInNewTab(), mustOpenInNewTab());
    if (showDialog) {
      dialog.show();
      if (!dialog.isOK()) return;
    } else {
      dialog.close(DialogWrapper.OK_EXIT_CODE);
    }

    setOpenInNewTab(dialog.isShowInSeparateWindow());

    FindUsagesOptions findUsagesOptions = dialog.calcFindUsagesOptions();
    if (!showDialog && useMaximalScope) {
      findUsagesOptions.searchScope = getMaximalScope(handler);
    }

    clearFindingNextUsageInFile();
    LOG.assertTrue(handler.getPsiElement().isValid());
    PsiElement[] primaryElements = handler.getPrimaryElements();
    checkNotNull(primaryElements, handler, "getPrimaryElements()");
    PsiElement[] secondaryElements = handler.getSecondaryElements();
    checkNotNull(secondaryElements, handler, "getSecondaryElements()");
    UsageInfoToUsageConverter.TargetElementsDescriptor descriptor =
        new UsageInfoToUsageConverter.TargetElementsDescriptor(primaryElements, secondaryElements);
    if (singleFile) {
      findUsagesOptions = findUsagesOptions.clone();
      editor.putUserData(KEY_START_USAGE_AGAIN, null);
      findUsagesInEditor(
          descriptor, handler, scopeFile, FileSearchScope.FROM_START, findUsagesOptions, editor);
    } else {
      findUsages(
          descriptor,
          handler,
          dialog.isSkipResultsWhenOneUsage(),
          dialog.isShowInSeparateWindow(),
          findUsagesOptions);
    }
  }
    public boolean equals(final Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;

      final SearchData that = (SearchData) o;

      return Arrays.equals(myElements, that.myElements)
          && (myOptions != null ? myOptions.equals(that.myOptions) : that.myOptions == null);
    }
 private static String generateUsagesString(final FindUsagesOptions selectedOptions) {
   return selectedOptions.generateUsagesString();
 }
  private static UsageSearcher createUsageSearcher(
      @NotNull final UsageInfoToUsageConverter.TargetElementsDescriptor descriptor,
      @NotNull final FindUsagesHandler handler,
      @NotNull FindUsagesOptions _options,
      final PsiFile scopeFile) {
    final FindUsagesOptions options = _options.clone();
    return new UsageSearcher() {
      @Override
      public void generate(@NotNull final Processor<Usage> processor) {
        if (scopeFile != null) {
          options.searchScope = new LocalSearchScope(scopeFile);
        }
        final Processor<UsageInfo> usageInfoProcessor =
            new CommonProcessors.UniqueProcessor<UsageInfo>(
                new Processor<UsageInfo>() {
                  @Override
                  public boolean process(UsageInfo usageInfo) {
                    return processor.process(
                        UsageInfoToUsageConverter.convert(descriptor, usageInfo));
                  }
                });
        final List<? extends PsiElement> elements =
            ApplicationManager.getApplication()
                .runReadAction(
                    new Computable<List<? extends PsiElement>>() {
                      @Override
                      public List<? extends PsiElement> compute() {
                        return descriptor.getAllElements();
                      }
                    });

        options.fastTrack = new SearchRequestCollector(new SearchSession());

        try {
          for (final PsiElement element : elements) {
            ApplicationManager.getApplication()
                .runReadAction(
                    new Runnable() {
                      @Override
                      public void run() {
                        LOG.assertTrue(element.isValid());
                      }
                    });
            handler.processElementUsages(element, usageInfoProcessor, options);
            for (CustomUsageSearcher searcher :
                Extensions.getExtensions(CustomUsageSearcher.EP_NAME)) {
              try {
                searcher.processElementUsages(element, processor, options);
              } catch (IndexNotReadyException e) {
                DumbService.getInstance(element.getProject())
                    .showDumbModeNotification("Find usages is not available during indexing");
              } catch (Exception e) {
                LOG.error(e);
              }
            }
          }

          Project project =
              ApplicationManager.getApplication()
                  .runReadAction(
                      new Computable<Project>() {
                        @Override
                        public Project compute() {
                          return scopeFile != null
                              ? scopeFile.getProject()
                              : !elements.isEmpty()
                                  ? elements.get(0).getProject()
                                  : handler.getProject();
                        }
                      });
          PsiSearchHelper.SERVICE
              .getInstance(project)
              .processRequests(
                  options.fastTrack,
                  new ReadActionProcessor<PsiReference>() {
                    @Override
                    public boolean processInReadAction(final PsiReference ref) {
                      return !ref.getElement().isValid()
                          || usageInfoProcessor.process(new UsageInfo(ref));
                    }
                  });
        } finally {
          options.fastTrack = null;
        }
      }
    };
  }