private void processLine(@NotNull Range range, int start, int end, byte type, @NotNull T flags) {
    Pair<@NotNull Interval, @Nullable Interval> pair1 = EditorUtil.logicalLineToYRange(myEditor, start);
    int visualStart = pair1.first.intervalStart();

    int sharedPrefixHeight;
    if (pair1.second == null) {
      sharedPrefixHeight = pair1.first.intervalEnd() - pair1.first.intervalStart();
    }
    else {
      sharedPrefixHeight = pair1.second.intervalStart() - pair1.first.intervalStart();
    }

    if (start == end) {
      if (sharedPrefixHeight != 0) {
        appendChange(range, new ChangedLines<>(visualStart, visualStart + sharedPrefixHeight, Range.MODIFIED, flags));
      }
      else {
        appendChange(range, new ChangedLines<>(visualStart, visualStart, type, flags));
      }
    }
    else {
      Pair<@NotNull Interval, @Nullable Interval> pair2 = EditorUtil.logicalLineToYRange(myEditor, end - 1);
      int visualEnd = pair2.first.intervalEnd();

      int sharedSuffixHeight;
      if (pair2.second == null) {
        sharedSuffixHeight = pair2.first.intervalEnd() - pair2.first.intervalStart();
      }
      else {
        sharedSuffixHeight = pair2.first.intervalEnd() - pair2.second.intervalEnd();
      }

      if (type == Range.EQUAL || type == Range.MODIFIED) {
        appendChange(range, new ChangedLines<>(visualStart, visualEnd, type, flags));
      }
      else {
        if (sharedPrefixHeight != 0 && visualEnd - visualStart > sharedPrefixHeight) {
          appendChange(range, new ChangedLines<>(visualStart, visualStart + sharedPrefixHeight, Range.MODIFIED, flags));
          visualStart += sharedPrefixHeight;
          sharedPrefixHeight = 0;
        }
        if (sharedSuffixHeight != 0 && visualEnd - visualStart > sharedSuffixHeight) {
          appendChange(range, new ChangedLines<>(visualStart, visualEnd - sharedSuffixHeight, type, flags));
          appendChange(range, new ChangedLines<>(visualEnd - sharedSuffixHeight, visualEnd, Range.MODIFIED, flags));
        }
        else {
          byte bodyType = sharedPrefixHeight != 0 || sharedSuffixHeight != 0 ? Range.MODIFIED : type;
          appendChange(range, new ChangedLines<>(visualStart, visualEnd, bodyType, flags));
        }
      }
    }
  }
private void processLine(@NotNull Range range, int start, int end, byte type, @NotNull T flags)