static @NotNull <T> MarkupIterator<T> mergeIterators(final @NotNull MarkupIterator<T> iterator1,
                                                       final @NotNull MarkupIterator<T> iterator2,
                                                       final @NotNull Comparator<? super T> comparator) {
    return new MarkupIterator<T>() {
      @Override
      public void dispose() {
        iterator1.dispose();
        iterator2.dispose();
      }

      @Override
      public boolean hasNext() {
        return iterator1.hasNext() || iterator2.hasNext();
      }

      @Override
      public T next() {
        return choose().next();
      }

      private @NotNull MarkupIterator<T> choose() {
        T t1 = iterator1.hasNext() ? iterator1.peek() : null;
        T t2 = iterator2.hasNext() ? iterator2.peek() : null;
        if (t1 == null) {
          return iterator2;
        }
        if (t2 == null) {
          return iterator1;
        }
        int compare = comparator.compare(t1, t2);
        return compare < 0 ? iterator1 : iterator2;
      }

      @Override
      public void remove() {
        throw new NoSuchElementException();
      }

      @Override
      public T peek() {
        return choose().peek();
      }
    };
  }
static @NotNull <T> MarkupIterator<T> mergeIterators(final @NotNull MarkupIterator<T> iterator1,
                                                       final @NotNull MarkupIterator<T> iterator2,
                                                       final @NotNull Comparator<? super T> comparator)