@Override
  protected void collectInformationWithProgress(@NotNull ProgressIndicator progress) {
    FileViewProvider viewProvider = myFile.getViewProvider();
    HighlightingLevelManager highlightingManager = HighlightingLevelManager.getInstance(myProject);
    Map<PsiFile, List<ExternalAnnotator<?,?>>> allAnnotators = new HashMap<>();
    int externalAnnotatorsInRoots = 0;
    InspectionProfileImpl currentProfile = InspectionProjectProfileManager.getInstance(myProject).getCurrentProfile();
    Function<? super InspectionProfile, ? extends InspectionProfileWrapper> custom = InspectionProfileWrapper.getCustomInspectionProfileWrapper(myFile);
    InspectionProfile profile;
    if (custom != null) {
      profile = custom.apply(currentProfile).getInspectionProfile();
    }
    else {
      profile = currentProfile;
    }
    for (PsiFile psiRoot : viewProvider.getAllFiles()) {
      if (highlightingManager.shouldInspect(psiRoot) && !highlightingManager.runEssentialHighlightingOnly(psiRoot)) {
        List<ExternalAnnotator<?,?>> annotators = ExternalLanguageAnnotators.allForFile(psiRoot.getLanguage(), psiRoot);
        annotators = ContainerUtil.filter(annotators, annotator -> {
          String shortName = annotator.getPairedBatchInspectionShortName();
          if (shortName != null) {
            HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
            if (key == null) {
              if (!ApplicationManager.getApplication().isUnitTestMode()) {
                // tests should care about registering corresponding paired tools
                processError(new Exception("Paired tool '" + shortName + "' not found"), annotator, psiRoot);
              }
              return false;
            }
            return profile.isToolEnabled(key, myFile);
          }
          return true;
        });
        if (!annotators.isEmpty()) {
          externalAnnotatorsInRoots += annotators.size();
          allAnnotators.put(psiRoot, annotators);
        }
      }
    }
    setProgressLimit(externalAnnotatorsInRoots);

    boolean errorFound = DaemonCodeAnalyzerEx.getInstanceEx(myProject).getFileStatusMap().wasErrorFound(myDocument);
    Editor editor = getEditor();

    DumbService dumbService = DumbService.getInstance(myProject);
    for (Map.Entry<PsiFile, List<ExternalAnnotator<?,?>>> entry : allAnnotators.entrySet()) {
      PsiFile psiRoot = entry.getKey();
      List<ExternalAnnotator<?,?>> annotators = entry.getValue();
      for (ExternalAnnotator<?,?> annotator : annotators) {
        progress.checkCanceled();

        if (!dumbService.isUsableInCurrentContext(annotator)) {
          continue;
        }
        Object collectedInfo = null;
        try {
          collectedInfo = editor == null ? annotator.collectInformation(psiRoot) : annotator.collectInformation(psiRoot, editor, errorFound);
        }
        catch (Throwable t) {
          processError(t, annotator, psiRoot);
        }

        if (collectedInfo != null) {
          //noinspection unchecked,rawtypes
          myAnnotationData.add(new MyData(annotator, psiRoot, collectedInfo));
        }
        advanceProgress(1);
      }
    }

    long modificationStampBefore = myDocument.getModificationStamp();
    ExternalAnnotatorManager.getInstance().queue(new Update(myFile) {
      @Override
      public void setRejected() {
        super.setRejected();
        if (!myProject.isDisposed()) { // Project close in EDT might call MergeUpdateQueue.dispose which calls setRejected in EDT
          doFinish();
        }
      }

      @Override
      public void run() {
        if (documentChanged(modificationStampBefore) || myProject.isDisposed()) {
          return;
        }

        // have to instantiate new indicator because the old one (progress) might have already been canceled
        DaemonProgressIndicator indicator = new DaemonProgressIndicator();
        BackgroundTaskUtil.runUnderDisposeAwareIndicator(myProject, () -> {
          // run annotators outside the read action because they could start OSProcessHandler
          runChangeAware(myDocument, () -> doAnnotate());
          ReadAction.run(() -> {
            ProgressManager.checkCanceled();
            if (!documentChanged(modificationStampBefore)) {
              doApply();
              doFinish();
            }
          });
        }, indicator);
      }
    });
  }
@Override
  protected void collectInformationWithProgress(@NotNull ProgressIndicator progress)