@Override
  public void documentChanged(@NotNull DocumentEvent e) {
    if (!myLookupStartMarker.isValid()) {
      // in the scenario of concurrent document modifications by many remote clients (CWM) there may be a situation
      // when one client (or host) has created a lookup and the another client immediately deleted a text under the offset
      // so the range marker became invalid because it's out of the document bounds
      // here we try to recreate the range marker recalculating the start offset within the new document bounds
      int start = calculateStartOffset(0, true);
      myLookupStartMarker.dispose();
      myLookupStartMarker = createLeftGreedyMarker(start);
      myStartMarkerDisposeInfo = null;
    }

    if (!myLookupOriginalStartMarker.isValid()) {
      // the original marker shouldn't take into account myAdditionalPrefix and myRemovedPrefix values
      int start = calculateStartOffset(0, false);
      myLookupOriginalStartMarker.dispose();
      myLookupOriginalStartMarker = createLeftGreedyMarker(start);
    }
    // capture the trace in the case when range marker is still invalid by some reasons
    if (myStartMarkerDisposeInfo == null && !myLookupStartMarker.isValid()) {
      Throwable throwable = new Throwable();
      String eString = e.toString();
      myStartMarkerDisposeInfo = () -> eString + "\n" + ExceptionUtil.getThrowableText(throwable);
    }
  }
@Override
  public void documentChanged(@NotNull DocumentEvent e)