LongRangeSet (@NotNull LongRangeSet other) { if (other.isEmpty()) return this; if (other == this) return Empty.EMPTY; if (other instanceof Point) { long value = ((Point)other).myValue; if (value < myFrom || value > myTo) return this; if (value == myFrom) return range(myFrom + 1, myTo); if (value == myTo) return range(myFrom, myTo - 1); return new RangeSet(new long[]{myFrom, value - 1, value + 1, myTo}); } if (other instanceof Range) { LongRangeSet toJoin = Empty.EMPTY; long from = ((Range)other).myFrom; long to = ((Range)other).myTo; if (to < myFrom || from > myTo) return this; if (other instanceof ModRange modRange) { long newBits = ~modRange.myBits; if (modRange.myMod < 64) { newBits &= (1L << modRange.myMod) - 1; } toJoin = modRange(Math.max(from, myFrom), Math.min(to, myTo), modRange.myMod, newBits); } if (from <= myFrom && to >= myTo) return toJoin; if (from > myFrom && to < myTo) { return new RangeSet(new long[]{myFrom, from - 1, to + 1, myTo}).join(toJoin); } if (from <= myFrom) { return range(to + 1, myTo).join(toJoin); } assert to >= myTo; return range(myFrom, from - 1).join(toJoin); } long[] ranges = ((RangeSet)other).myRanges; LongRangeSet result = this; for (int i = 0; i < ranges.length; i += 2) { result = result.subtract(range(ranges[i], ranges[i + 1])); if (result.isEmpty()) return result; } return result; }