public void store(@NotNull TextChange change) {
    if (myChanges.isEmpty()) {
      myChanges.add(new ChangeEntry(new TextChangeImpl(change.getText(), change.getStart(), change.getEnd()), change.getStart()));
      return;
    }
    
    // There is a big chance that the document is processed sequentially from start to end, hence, it makes sense
    // to check if given change lays beyond other registered changes and register it quickly in case of success.
    ChangeEntry last = myChanges.get(myChanges.size() - 1);
    if (last.clientStartOffset + last.change.getText().length() < change.getStart()) {
      int clientShift = last.clientStartOffset - last.change.getStart() + last.change.getDiff();
      myChanges.add(new ChangeEntry(
        new TextChangeImpl(change.getText(), change.getStart() - clientShift, change.getEnd() - clientShift),
        change.getStart()
      ));
      return;
    }

    int insertionIndex = doStore(change);
    if (insertionIndex < 0) {
      return;
    }
    mergeIfNecessary(insertionIndex);
  }
public void store(@NotNull TextChange change)