@Override
  public void actionPerformed(@NotNull final AnActionEvent e) {
    myIsLoading = true;
    Project project = e.getProject();
    ConsoleViewImpl consoleView = (ConsoleViewImpl)e.getData(LangDataKeys.CONSOLE_VIEW);
    Editor editor = consoleView != null ? consoleView.getEditor() : null;
    if (project == null || editor == null) return;
    EditorHyperlinkSupport hyperlinks = consoleView.getHyperlinks();

    ProgressManager.getInstance().run(new Task.Backgroundable(
      project, LangBundle.message("progress.title.getting.file.history"), true) {
      private final Object LOCK = new Object();
      private final MergingUpdateQueue myUpdateQueue = new MergingUpdateQueue("AnnotateStackTraceAction", 200, true, null);

      private MyActiveAnnotationGutter myGutter;

      @Override
      public void onCancel() {
        editor.getGutter().closeAllAnnotations();
      }

      @Override
      public void onFinished() {
        myIsLoading = false;
        Disposer.dispose(myUpdateQueue);
      }

      @Override
      public void run(@NotNull ProgressIndicator indicator) {
        Map<VirtualFile, IntList> files2lines = CollectionFactory.createSmallMemoryFootprintMap();
        Int2ObjectMap<LastRevision> revisions = new Int2ObjectOpenHashMap<>();

        ApplicationManager.getApplication().runReadAction(() -> {
          for (int line = 0; line < editor.getDocument().getLineCount(); line++) {
            indicator.checkCanceled();
            VirtualFile file = getHyperlinkVirtualFile(hyperlinks.findAllHyperlinksOnLine(line));
            if (file == null) continue;

            files2lines.computeIfAbsent(file, __ -> new IntArrayList()).add(line);
          }
        });

        for (Map.Entry<VirtualFile, IntList> entry : files2lines.entrySet()) {
          VirtualFile file = entry.getKey();
          IntList value = entry.getValue();
          indicator.checkCanceled();
          LastRevision revision = getLastRevision(file);
          if (revision == null) {
            continue;
          }
          synchronized (LOCK) {
            for (IntListIterator iterator = value.iterator(); iterator.hasNext(); ) {
              revisions.put(iterator.nextInt(), revision);
            }
          }

          myUpdateQueue.queue(new Update("update") {
            @Override
            public void run() {
              updateGutter(indicator, revisions);
            }
          });
        }

        // myUpdateQueue can be disposed before the last revisions are passed to the gutter
        ApplicationManager.getApplication().invokeLater(() -> updateGutter(indicator, revisions));
      }

      @RequiresEdt
      private void updateGutter(@NotNull ProgressIndicator indicator, @NotNull Map<Integer, LastRevision> revisions) {
        if (indicator.isCanceled()) return;

        if (myGutter == null) {
          myGutter = new MyActiveAnnotationGutter(getProject(), hyperlinks, indicator);
          editor.getGutter().registerTextAnnotation(myGutter, myGutter);
        }

        Map<Integer, LastRevision> revisionsCopy;
        synchronized (LOCK) {
          revisionsCopy = new HashMap<>(revisions);
        }

        myGutter.updateData(revisionsCopy);
        ((EditorGutterComponentEx)editor.getGutter()).revalidateMarkup();
      }

      @Nullable
      private LastRevision getLastRevision(@NotNull VirtualFile file) {
        try {
          AbstractVcs vcs = VcsUtil.getVcsFor(project, file);
          if (vcs == null) return null;

          VcsHistoryProvider historyProvider = vcs.getVcsHistoryProvider();
          if (historyProvider == null) return null;

          FilePath filePath = VcsContextFactory.getInstance().createFilePathOn(file);

          if (historyProvider instanceof VcsHistoryProviderEx) {
            VcsFileRevision revision = ((VcsHistoryProviderEx)historyProvider).getLastRevision(filePath);
            if (revision == null) return null;
            return LastRevision.create(revision);
          }
          else {
            VcsHistorySession session = historyProvider.createSessionFor(filePath);
            if (session == null) return null;

            List<VcsFileRevision> list = session.getRevisionList();
            if (list == null || list.isEmpty()) return null;

            return LastRevision.create(list.get(0));
          }
        }
        catch (VcsException e) {
          LOG.warn(e);
          return null;
        }
      }
    });
  }
@Override
  public void actionPerformed(@NotNull final AnActionEvent e)