public static IndexIterationPointer union(IndexIterationPointer left, IndexIterationPointer right, Comparator comparator) {
        assert left.isDescending() == right.isDescending();
        assert left.getLastEntryKeyData() == null && right.lastEntryKeyData == null : "Can merge only initial pointers";
        Tuple2<Comparable<?>, Boolean> newFrom = min(left.getFrom(), left.isFromInclusive(),
                right.getFrom(), right.isFromInclusive(),
                comparator);
        Tuple2<Comparable<?>, Boolean> newTo = max(left.getTo(), left.isToInclusive(),
                right.getTo(), right.isToInclusive(),
                comparator);

        return IndexIterationPointer.create(newFrom.f0(), newFrom.f1(), newTo.f0(), newTo.f1(),
                left.isDescending(), null);
    }
@Test
    void unionAdjacentSingletonRange() {
        assertThat(union(pointer(singleton(5)), pointer(singleton(5)),
                OrderedIndexStore.SPECIAL_AWARE_COMPARATOR)).isEqualTo(pointer(singleton(5)));

        assertThat(union(pointer(singleton(5)), pointer(greaterThan(5)),
                OrderedIndexStore.SPECIAL_AWARE_COMPARATOR)).isEqualTo(pointer(atLeast(5)));
        // reverse order is also allowed
        assertThat(union(pointer(greaterThan(5)), pointer(singleton(5)),
                OrderedIndexStore.SPECIAL_AWARE_COMPARATOR)).isEqualTo(pointer(atLeast(5)));

        assertThat(union(pointer(singleton(5)), pointer(lessThan(5)),
                OrderedIndexStore.SPECIAL_AWARE_COMPARATOR)).isEqualTo(pointer(atMost(5)));
        // reverse order is also allowed
        assertThat(union(pointer(lessThan(5)), pointer(singleton(5)),
                OrderedIndexStore.SPECIAL_AWARE_COMPARATOR)).isEqualTo(pointer(atMost(5)));
    }