public void findUsages(@NotNull Processor<? super Usage> processor) {
    final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
    progress.setIndeterminate(false);

    final MatchResultSink sink = new MatchResultSink() {
      int count;

      @Override
      public void setMatchingProcess(@NotNull MatchingProcess _process) {
        findStarted();
      }

      @Override
      public void processFile(@NotNull PsiFile element) {
        final VirtualFile virtualFile = element.getVirtualFile();
        if (virtualFile != null)
          progress.setText(SSRBundle.message("looking.in.progress.message", virtualFile.getPresentableName()));
      }

      @Override
      public void matchingFinished() {
        if (mySearchContext.getProject().isDisposed()) return;
        findEnded();
        progress.setText(SSRBundle.message("found.progress.message", count));
      }

      @Override
      public ProgressIndicator getProgressIndicator() {
        return progress;
      }

      @Override
      public void newMatch(@NotNull MatchResult result) {
        UsageInfo info;

        if (MatchResult.MULTI_LINE_MATCH.equals(result.getName())) {
          int start = -1;
          int end = -1;
          PsiElement parent = result.getMatch().getParent();

          for (final MatchResult matchResult : result.getChildren()) {
            PsiElement el = matchResult.getMatch();
            final int elementStart = el.getTextRange().getStartOffset();

            if (start == -1 || start > elementStart) {
              start = elementStart;
            }
            final int newend = elementStart + el.getTextLength();

            if (newend > end) {
              end = newend;
            }
          }

          final int parentStart = parent.getTextRange().getStartOffset();
          int startOffset = start - parentStart;
          info = new UsageInfo(parent, startOffset, end - parentStart);
        }
        else {
          final PsiElement match = result.getMatch();
          if (!match.isPhysical()) {
            // e.g. lambda parameter anonymous type element
            return;
          }
          info = new UsageInfo(match);
        }

        final Usage usage = new UsageInfo2UsageAdapter(info);
        foundUsage(result, usage);
        processor.process(usage);
        ++count;
      }
    };

    try {
      new Matcher(mySearchContext.getProject(), myConfiguration.getMatchOptions()).findMatches(sink);
    }
    catch (StructuralSearchException e) {
      myProcessPresentation.setShowNotFoundMessage(false);
      @SuppressWarnings("InstanceofCatchParameter") String content =
        e instanceof StructuralSearchScriptException
        ? SSRBundle.message("search.script.problem", e.getCause().toString().replace(ScriptSupport.UUID, ""))
        : SSRBundle.message("search.template.problem", e.getMessage());
      NotificationGroupManager.getInstance()
        .getNotificationGroup(UIUtil.SSR_NOTIFICATION_GROUP_ID)
        .createNotification(content, NotificationType.ERROR)
        .setImportant(true)
        .notify(mySearchContext.getProject());
    }
  }
public void findUsages(@NotNull Processor<? super Usage> processor)