@NotNull
  public Block createPreviousBlock(String @NotNull [] prevContent) {
    try {
      FairDiffIterable iterable = ByLine.compare(Arrays.asList(prevContent), Arrays.asList(mySource),
                                                 ComparisonPolicy.IGNORE_WHITESPACES, DumbProgressIndicator.INSTANCE);

      // empty range should not be transferred to the non-empty range
      boolean greedy = myStart != myEnd;

      int start = myStart;
      int end = myEnd;
      int shift = 0;

      for (Range range : iterable.iterateChanges()) {
        int changeStart = range.start2 + shift;
        int changeEnd = range.end2 + shift;
        int changeShift = (range.end1 - range.start1) - (range.end2 - range.start2);

        DiffUtil.UpdatedLineRange updatedRange =
          DiffUtil.updateRangeOnModification(start, end, changeStart, changeEnd, changeShift, greedy);

        start = updatedRange.startLine;
        end = updatedRange.endLine;
        shift += changeShift;
      }

      if (start < 0 || end > prevContent.length || end < start) {
        LOG.error("Invalid block range: [" + start + ", " + end + "); length - " + prevContent.length);
      }


      // intern strings, reducing memory usage
      for (Range range : iterable.iterateUnchanged()) {
        int count = range.end1 - range.start1;
        for (int i = 0; i < count; i++) {
          int prevIndex = range.start1 + i;
          int sourceIndex = range.start2 + i;
          if (prevContent[prevIndex].equals(mySource[sourceIndex])) {
            prevContent[prevIndex] = mySource[sourceIndex];
          }
        }
      }

      return new Block(prevContent, start, end);
    }
    catch (DiffTooBigException e) {
      return new Block(prevContent, 0, 0);
    }
  }
@NotNull
  public Block createPreviousBlock(String @NotNull [] prevContent)