LongRangeSet (@NotNull LongRangeSet other) { if (other.isEmpty() || other == this) return this; if (other.contains(myValue)) return other; if (other instanceof Point) { long value1 = Math.min(myValue, ((Point)other).myValue); long value2 = Math.max(myValue, ((Point)other).myValue); return value1 + 1 == value2 ? range(value1, value2) : new RangeSet(new long[]{value1, value1, value2, value2}); } if (other instanceof ModRange) { return other.join(this); } if (other instanceof Range) { if (myValue < other.min()) { return myValue + 1 == other.min() ? range(myValue, other.max()) : new RangeSet(new long[]{myValue, myValue, other.min(), other.max()}); } else { assert myValue > other.max(); return myValue - 1 == other.max() ? range(other.min(), myValue) : new RangeSet(new long[]{other.min(), other.max(), myValue, myValue}); } } long[] longs = other.asRangeArray(); int pos = -Arrays.binarySearch(longs, myValue) - 1; assert pos >= 0 && pos % 2 == 0; boolean touchLeft = pos > 0 && longs[pos - 1] + 1 == myValue; boolean touchRight = pos < longs.length - 1 && myValue + 1 == longs[pos]; long[] result; if (touchLeft) { if (touchRight) { result = new long[longs.length - 2]; System.arraycopy(longs, 0, result, 0, pos - 1); System.arraycopy(longs, pos + 1, result, pos - 1, longs.length - pos - 1); } else { result = longs.clone(); result[pos - 1] = myValue; } } else { if (touchRight) { result = longs.clone(); result[pos] = myValue; } else { result = new long[longs.length + 2]; System.arraycopy(longs, 0, result, 0, pos); result[pos] = result[pos + 1] = myValue; System.arraycopy(longs, pos, result, pos + 2, longs.length - pos); } } return fromRanges(result, result.length); }