@Override
  public void applyHeavyFilter(final @NotNull Document copiedFragment,
                               int startOffset,
                               int startLineNumber,
                               @NotNull Consumer<? super AdditionalHighlight> consumer) {
    VcsContentAnnotation vcsContentAnnotation = VcsContentAnnotationImpl.getInstance(myProject);
    final LocalChangesCorrector localChangesCorrector = new LocalChangesCorrector(myProject);
    LineResult previousLineResult = null;

    for (int i = 0; i < copiedFragment.getLineCount(); i++) {
      final int lineStartOffset = copiedFragment.getLineStartOffset(i);
      final int lineEndOffset = copiedFragment.getLineEndOffset(i);
      final ExceptionLineParser worker = ExceptionLineParserFactory.getInstance().create(myCache);
      final String lineText = copiedFragment.getText(new TextRange(lineStartOffset, lineEndOffset));
      LineResult lineResult = ReadAction.compute(() -> {
        if (DumbService.isDumb(myProject)) return null;
        Result result = worker.execute(lineText, lineEndOffset);
        if (result == null) return null;
        return new LineResult(worker.getUClass(), worker.getFile(), worker.getMethod());
      });
      if (lineResult != null && lineResult.file() != null) {
        VirtualFile vf = lineResult.file().getVirtualFile();
        if (vf.getFileSystem().isReadOnly()) continue;

        VcsRevisionNumber recentChangeRevision = myRevNumbersCache.get(vf);
        if (recentChangeRevision == null) {
          recentChangeRevision = vcsContentAnnotation.fileRecentlyChanged(vf);
          if (recentChangeRevision == null) {
            myRevNumbersCache.put(vf, VcsRevisionNumber.NULL);
          }
          else {
            myRevNumbersCache.put(vf, recentChangeRevision);
          }
        }
        if (VcsRevisionNumber.NULL.equals(recentChangeRevision)) {
          recentChangeRevision = null;
        }

        FileStatus status = ChangeListManager.getInstance(myProject).getStatus(vf);
        boolean isFileChanged = FileStatus.NOT_CHANGED.equals(status) ||
                                FileStatus.UNKNOWN.equals(status) ||
                                FileStatus.IGNORED.equals(status);

        if (localChangesCorrector.isFileAlreadyIdentifiedAsChanged(vf) || isFileChanged || recentChangeRevision != null) {
          final Document document = getDocumentForFile(worker);
          if (document == null) return;

          TextRange fileLinkRange = worker.getInfo().fileLineRange;
          int startFileLinkOffset = fileLinkRange.getStartOffset();
          int idx = lineText.indexOf(':', startFileLinkOffset);
          int endFileLinkOffset = idx == -1 ? fileLinkRange.getEndOffset() : idx;
          consumer.consume(new MyAdditionalHighlight(startOffset + lineStartOffset + startFileLinkOffset,
                                                     startOffset + lineStartOffset + endFileLinkOffset));

          if (lineResult.uClass() != null) {
            // also check method
            final List<TextRange> ranges = findMethodRange(worker, document, previousLineResult);
            if (ranges != null) {
              boolean methodChanged = false;
              for (TextRange range : ranges) {
                if (localChangesCorrector.isRangeChangedLocally(vf, document, range)) {
                  methodChanged = true;
                  break;
                }
                final TextRange correctedRange = localChangesCorrector.getCorrectedRange(vf, document, range);
                if (vcsContentAnnotation.intervalRecentlyChanged(vf, correctedRange, recentChangeRevision)) {
                  methodChanged = true;
                  break;
                }
              }
              if (methodChanged) {
                consumer.consume(
                  new MyAdditionalHighlight(startOffset + lineStartOffset + worker.getInfo().methodNameRange.getStartOffset(),
                                            startOffset + lineStartOffset + worker.getInfo().methodNameRange.getEndOffset()));
              }
            }
          }
        }
      }
      previousLineResult = worker.getResult() == null ? null : lineResult;
    }
  }
@Override
  public void applyHeavyFilter(final @NotNull Document copiedFragment,
                               int startOffset,
                               int startLineNumber,
                               @NotNull Consumer<? super AdditionalHighlight> consumer)