@Override
    public ValueSet canonicalize(boolean removeSafeConstants)
    {
        if (!removeSafeConstants) {
            return this;
        }

        AtomicLong counter = new AtomicLong(0);
        return new SortedRangeSet(
                type,
                lowIndexedRanges.entrySet().stream()
                        .collect(toMap(
                                // Since map values contain all range information, we can mark all keys as 0, 1, 2... in ascending order.
                                entry -> Marker.exactly(BIGINT, counter.incrementAndGet()),
                                entry -> {
                                    boolean removeConstants = entry.getValue().getLow().getBound().equals(Marker.Bound.EXACTLY) && entry.getValue().getHigh().getBound().equals(Marker.Bound.EXACTLY);
                                    return entry.getValue().canonicalize(removeConstants);
                                },
                                (e1, e2) -> { throw new IllegalStateException(format("Duplicate key %s", e1)); },
                                TreeMap::new)));
    }
@Test
    public void testCanonicalize()
            throws Exception
    {
        assertSameSet(SortedRangeSet.all(BIGINT), SortedRangeSet.all(BIGINT), false);
        assertSameSet(
                SortedRangeSet.of(
                        Range.lessThan(BIGINT, 0L),
                        Range.equal(BIGINT, 1L),
                        Range.equal(BIGINT, 2L),
                        Range.range(BIGINT, 5L, false, 9L, false),
                        Range.greaterThanOrEqual(BIGINT, 11L)),
                SortedRangeSet.of(
                        Range.lessThan(BIGINT, 0L),
                        Range.equal(BIGINT, 1L),
                        Range.equal(BIGINT, 2L),
                        Range.range(BIGINT, 5L, false, 9L, false),
                        Range.greaterThanOrEqual(BIGINT, 11L)),
                false);

        assertDifferentSet(
                SortedRangeSet.of(
                        Range.lessThan(BIGINT, 0L),
                        Range.equal(BIGINT, 1L),
                        Range.equal(BIGINT, 2L),
                        Range.range(BIGINT, 5L, false, 9L, false),
                        Range.greaterThanOrEqual(BIGINT, 11L)),
                SortedRangeSet.of(
                        Range.lessThan(BIGINT, 0L),
                        Range.equal(BIGINT, 1L),
                        Range.equal(BIGINT, 3L),
                        Range.range(BIGINT, 5L, false, 9L, false),
                        Range.greaterThanOrEqual(BIGINT, 11L)),
                false);
        assertDifferentSet(SortedRangeSet.all(BIGINT), SortedRangeSet.none(BIGINT), false);
        assertDifferentSet(SortedRangeSet.all(BIGINT), SortedRangeSet.all(VARCHAR), false);

        assertSameSet(
                SortedRangeSet.of(
                        Range.lessThan(BIGINT, 0L),
                        Range.equal(BIGINT, 1L),
                        Range.equal(BIGINT, 2L),
                        Range.range(BIGINT, 5L, false, 9L, false),
                        Range.greaterThanOrEqual(BIGINT, 11L)),
                SortedRangeSet.of(
                        Range.lessThan(BIGINT, 0L),
                        Range.equal(BIGINT, 3L),
                        Range.equal(BIGINT, 4L),
                        Range.range(BIGINT, 5L, false, 9L, false),
                        Range.greaterThanOrEqual(BIGINT, 11L)),
                true);
        assertSameSet(SortedRangeSet.all(BIGINT), SortedRangeSet.all(BIGINT), true);

        assertDifferentSet(
                SortedRangeSet.of(
                        Range.lessThan(BIGINT, 0L),
                        Range.range(BIGINT, 0L, false, 2L, false),
                        Range.range(BIGINT, 5L, false, 9L, false),
                        Range.greaterThanOrEqual(BIGINT, 11L)),
                SortedRangeSet.of(
                        Range.lessThan(BIGINT, 0L),
                        Range.range(BIGINT, 0L, false, 3L, false),
                        Range.range(BIGINT, 5L, true, 9L, false),
                        Range.greaterThanOrEqual(BIGINT, 11L)),
                true);
        assertDifferentSet(SortedRangeSet.all(BIGINT), SortedRangeSet.all(BOOLEAN), true);
    }