@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));
      }
@Override
      public void run(@NotNull ProgressIndicator indicator)