@NotNull
  private static List<FairDiffIterable> collectWordBlockSubIterables(@NotNull FairDiffIterable wordChanges,
                                                                     @NotNull List<WordBlock> wordBlocks) {
    List<Range> changed = new ArrayList<>();
    for (Range range : wordChanges.iterateChanges()) {
      changed.add(range);
    }

    int index = 0;

    List<FairDiffIterable> subIterables = new ArrayList<>(wordBlocks.size());
    for (WordBlock block : wordBlocks) {
      Range words = block.words;

      while (index < changed.size()) {
        Range range = changed.get(index);
        if (range.end1 < words.start1 || range.end2 < words.start2) {
          index++;
          continue;
        }

        break;
      }

      subIterables.add(fair(new SubiterableDiffIterable(changed, words.start1, words.end1, words.start2, words.end2, index)));
    }
    return subIterables;
  }
@NotNull
  private static List<FairDiffIterable> collectWordBlockSubIterables(@NotNull FairDiffIterable wordChanges,
                                                                     @NotNull List<WordBlock> wordBlocks)