@Contract(pure = true)
  public static @NotNull CharSequence applyOperations(@NotNull CharSequence original,
                                                      @NotNull Collection<@NotNull StringOperation> operations) {
    if (operations.isEmpty()) {
      return original;
    }
    final List<StringOperation> sorted = sort(operations);

    // The result looks like this:
    // originalChunk0 + replacement0 + ... + originalChunkN + replacementN + lastChunk

    final StringBuilder result = new StringBuilder();
    int previousRangeEnd = 0;

    // each iteration appends original chunk and following replacement
    for (StringOperation operation : sorted) {
      TextRange range = operation.myRange;
      result.append(original, previousRangeEnd, range.getStartOffset());
      result.append(operation.myReplacement);
      previousRangeEnd = range.getEndOffset(); // next original chunk starts where the current replacement ends
    }

    // last chunk
    result.append(original, previousRangeEnd, original.length());

    return result.toString();
  }
@Contract(pure = true)
  public static @NotNull CharSequence applyOperations(@NotNull CharSequence original,
                                                      @NotNull Collection<@NotNull StringOperation> operations)