List<Range<Type>> sortedRanges() {
        if (sorted)
            return ranges;

        ranges.sort((r1, r2) -> type.comparator.compare(r1.start, r2.start));

        List<Range<Type>> pruned = new ArrayList<>();
        Range<Type> start = ranges.get(0), end = start;
        for (int i = 1; i < ranges.size(); i++) {
            Range<Type> range = ranges.get(i);
            if (overlap(end, range)) {
                end = type.comparator.compare(end.end, range.end) < 0 ? range : end;
            }
            else {
                pruned.add(start == end ? start : new Range<>(start.start, end.end));
                start = end = range;
            }
        }
        pruned.add(start == end ? start : new Range<>(start.start, end.end));

        sorted = true;
        return ranges = pruned;
    }
Assumption: first.start <= second.start
Then there is overlap if
first.end  > second.start
first.end == second.start AND either of
  ranges are inclusive at either end, OR
  either range is a (logically empty) point (a, a), since this dominated by (or equal to) the other range.
container-search/src/main/java/com/yahoo/prelude/query/MultiRangeItem.java