@Nullable
  private static AnnotatedLineModificationDetails createFragmentDetails(@NotNull String lineContentAfter,
                                                                        @NotNull LineOffsets afterLineOffsets,
                                                                        @NotNull List<? extends LineFragment> fragments,
                                                                        int originalLineNumber) {
    LineFragment lineFragment = ContainerUtil.find(fragments.iterator(), fragment -> {
      return fragment.getStartLine2() <= originalLineNumber && originalLineNumber < fragment.getEndLine2();
    });
    if (lineFragment == null) return null; // line unmodified

    if (lineFragment.getStartLine1() == lineFragment.getEndLine1()) {
      return createNewLineDetails(lineContentAfter); // the whole line is new
    }

    List<DiffFragment> innerFragments = lineFragment.getInnerFragments();
    if (innerFragments == null) {
      return createModifiedLineDetails(lineContentAfter); // the whole line is modified
    }

    int lineStart = afterLineOffsets.getLineStart(originalLineNumber);
    int lineEnd = afterLineOffsets.getLineEnd(originalLineNumber);
    int windowStart = lineStart - lineFragment.getStartOffset2();
    int windowEnd = lineEnd - lineFragment.getStartOffset2();
    int lineLength = lineEnd - lineStart;

    List<InnerChange> changes = new ArrayList<>();
    for (DiffFragment innerFragment : innerFragments) {
      if (innerFragment.getEndOffset2() < windowStart || innerFragment.getStartOffset2() > windowEnd) continue;
      int start = Math.max(0, innerFragment.getStartOffset2() - windowStart);
      int end = Math.min(lineLength, innerFragment.getEndOffset2() - windowStart);
      boolean hasDeleted = innerFragment.getStartOffset1() != innerFragment.getEndOffset1();
      boolean hasInserted = innerFragment.getStartOffset2() != innerFragment.getEndOffset2();
      InnerChangeType type = hasInserted ? hasDeleted ? InnerChangeType.MODIFIED
                                                      : InnerChangeType.INSERTED
                                         : InnerChangeType.DELETED;
      changes.add(new InnerChange(start, end, type));
    }

    return new AnnotatedLineModificationDetails(lineContentAfter, changes);
  }
@Nullable
  private static AnnotatedLineModificationDetails createFragmentDetails(@NotNull String lineContentAfter,
                                                                        @NotNull LineOffsets afterLineOffsets,
                                                                        @NotNull List<? extends LineFragment> fragments,
                                                                        int originalLineNumber)