@NotNull
  private ScheduledPass createScheduledPass(
      @NotNull FileEditor fileEditor,
      @NotNull TextEditorHighlightingPass pass,
      @NotNull Map<Pair<FileEditor, Integer>, ScheduledPass> toBeSubmitted,
      @NotNull List<TextEditorHighlightingPass> textEditorHighlightingPasses,
      @NotNull List<ScheduledPass> freePasses,
      @NotNull List<ScheduledPass> dependentPasses,
      @NotNull DaemonProgressIndicator updateProgress,
      @NotNull AtomicInteger threadsToStartCountdown) {
    int passId = pass.getId();
    Pair<FileEditor, Integer> key = Pair.create(fileEditor, passId);
    ScheduledPass scheduledPass = toBeSubmitted.get(key);
    if (scheduledPass != null) return scheduledPass;
    scheduledPass = new ScheduledPass(fileEditor, pass, updateProgress, threadsToStartCountdown);
    threadsToStartCountdown.incrementAndGet();
    toBeSubmitted.put(key, scheduledPass);
    for (int predecessorId : pass.getCompletionPredecessorIds()) {
      ScheduledPass predecessor =
          findOrCreatePredecessorPass(
              fileEditor,
              toBeSubmitted,
              textEditorHighlightingPasses,
              freePasses,
              dependentPasses,
              updateProgress,
              threadsToStartCountdown,
              predecessorId);
      if (predecessor != null) {
        predecessor.addSuccessorOnCompletion(scheduledPass);
      }
    }
    for (int predecessorId : pass.getStartingPredecessorIds()) {
      ScheduledPass predecessor =
          findOrCreatePredecessorPass(
              fileEditor,
              toBeSubmitted,
              textEditorHighlightingPasses,
              freePasses,
              dependentPasses,
              updateProgress,
              threadsToStartCountdown,
              predecessorId);
      if (predecessor != null) {
        predecessor.addSuccessorOnSubmit(scheduledPass);
      }
    }
    if (scheduledPass.myRunningPredecessorsCount.get() == 0
        && !freePasses.contains(scheduledPass)) {
      freePasses.add(scheduledPass);
    } else if (!dependentPasses.contains(scheduledPass)) {
      dependentPasses.add(scheduledPass);
    }

    if (pass.isRunIntentionPassAfter() && fileEditor instanceof TextEditor) {
      Editor editor = ((TextEditor) fileEditor).getEditor();
      ShowIntentionsPass ip = new ShowIntentionsPass(myProject, editor, -1);
      ip.setId(nextPassId.incrementAndGet());
      ip.setCompletionPredecessorIds(new int[] {scheduledPass.myPass.getId()});

      createScheduledPass(
          fileEditor,
          ip,
          toBeSubmitted,
          textEditorHighlightingPasses,
          freePasses,
          dependentPasses,
          updateProgress,
          threadsToStartCountdown);
    }

    return scheduledPass;
  }