private static <T> @Nullable T getBestMatchingBreakpoint(int caretOffset, Iterator<@NotNull T> breakpoints, Function<T, @Nullable TextRange> rangeProvider) {
    // Best matching = closest to the insertion point and minimal by range of all breakpoints or breakpoint variants
    T bestBreakpoint = null;
    int bestDistance = Integer.MAX_VALUE;
    int bestRangeLength = Integer.MAX_VALUE;
    while (breakpoints.hasNext()) {
      var b = breakpoints.next();
      TextRange range = rangeProvider.apply(b);
      int rangeLength = range != null ? range.getLength() : Integer.MAX_VALUE;
      // note that range = null means "whole line"
      int distance = range == null ?
                       0 :
                       range.containsOffset(caretOffset) ? //include end offset
                         0 :
                         Math.min(Math.abs(range.getStartOffset() - caretOffset), Math.abs(range.getEndOffset() - caretOffset));
      if (bestBreakpoint == null || distance < bestDistance || (distance == bestDistance && rangeLength < bestRangeLength)) {
          bestBreakpoint = b;
          bestDistance = distance;
          bestRangeLength = rangeLength;
        }
    }
    return bestBreakpoint;
  }
private static <T> @Nullable T getBestMatchingBreakpoint(int caretOffset, Iterator<@NotNull T> breakpoints, Function<T, @Nullable TextRange> rangeProvider)