void submitPasses(@NotNull Document document,
                    @NotNull VirtualFile virtualFile,
                    @NotNull PsiFile psiFile,
                    @NotNull FileEditor fileEditor,
                    HighlightingPass @NotNull [] passes,
                    @NotNull DaemonProgressIndicator updateProgress) {
    if (isDisposed()) return;
    ApplicationManager.getApplication().assertIsNonDispatchThread();

    List<TextEditorHighlightingPass> documentBoundPasses = new ArrayList<>();
    List<EditorBoundHighlightingPass> editorBoundPasses = new ArrayList<>();
    Int2ObjectMap<TextEditorHighlightingPass> id2Pass = new Int2ObjectOpenHashMap<>(30);

    List<ScheduledPass> freePasses = new ArrayList<>(); // passes free to start, with no "after" dependencies
    AtomicInteger threadsToStartCountdown = new AtomicInteger(0);

    for (HighlightingPass pass : passes) {
      if (pass instanceof EditorBoundHighlightingPass editorPass) {
        // have to make ids unique for this document
        assignUniqueId(editorPass, id2Pass);
        editorBoundPasses.add(editorPass);
      }
      else if (pass instanceof TextEditorHighlightingPass tePass) {
        assignUniqueId(tePass, id2Pass);
        documentBoundPasses.add(tePass);
      }
      else {
        // generic HighlightingPass, run all of them concurrently
        freePasses.add(new ScheduledPass(fileEditor, pass, updateProgress, threadsToStartCountdown));
      }
    }

    List<ScheduledPass> dependentPasses = new ArrayList<>();
    // passId -> created pass
    Int2ObjectMap<ScheduledPass> toBeSubmitted = new Int2ObjectOpenHashMap<>();
    sortById(documentBoundPasses);
    for (TextEditorHighlightingPass pass : documentBoundPasses) {
      createScheduledPass(fileEditor, document, virtualFile, psiFile, pass, toBeSubmitted, id2Pass, freePasses, dependentPasses, updateProgress, threadsToStartCountdown);
    }

    for (EditorBoundHighlightingPass pass : editorBoundPasses) {
      createScheduledPass(fileEditor, document, virtualFile, psiFile, pass, toBeSubmitted, id2Pass, freePasses, dependentPasses, updateProgress, threadsToStartCountdown);
    }

    if (CHECK_CONSISTENCY && !ApplicationManagerEx.isInStressTest()) {
      assertConsistency(freePasses, toBeSubmitted, threadsToStartCountdown);
    }

    if (LOG.isDebugEnabled()) {
      log(updateProgress, null, "submitPasses: "+virtualFile.getName() + " ----- starting " + threadsToStartCountdown.get() + "passes. free:"+freePasses+"; editorBound:"+editorBoundPasses+"; documentBound:"+documentBoundPasses);
    }

    for (ScheduledPass dependentPass : dependentPasses) {
      mySubmittedPasses.put(dependentPass, Job.nullJob());
    }
    for (ScheduledPass freePass : freePasses) {
      submit(freePass);
    }
  }
void submitPasses(@NotNull Document document,
                    @NotNull VirtualFile virtualFile,
                    @NotNull PsiFile psiFile,
                    @NotNull FileEditor fileEditor,
                    HighlightingPass @NotNull [] passes,
                    @NotNull DaemonProgressIndicator updateProgress)