public Versions subtract(Versions other) {
        if (other.lowest() <= lowest) {
            if (other.highest >= highest) {
                // Case 1: other is a superset of this.  Trim everything.
                return Versions.NONE;
            } else if (other.highest < lowest) {
                // Case 2: other is a disjoint version range that is lower than this.  Trim nothing.
                return this;
            } else {
                // Case 3: trim some values from the beginning of this range.
                //
                // Note: it is safe to assume that other.highest() + 1 will not overflow.
                // The reason is because if other.highest() were Short.MAX_VALUE,
                // other.highest() < highest could not be true.
                return new Versions((short) (other.highest() + 1), highest);
            }
        } else if (other.highest >= highest) {
            int newHighest = other.lowest - 1;
            if (newHighest < 0) {
                // Case 4: other was NONE.  Trim nothing.
                return this;
            } else if (newHighest < highest) {
                // Case 5: trim some values from the end of this range.
                return new Versions(lowest, (short) newHighest);
            } else {
                // Case 6: other is a disjoint range that is higher than this.  Trim nothing.
                return this;
            }
        } else {
            // Case 7: the difference between this and other would be two ranges, not one.
            return null;
        }
    }
@Test
    public void testSubtract() {
        assertEquals(Versions.NONE, Versions.NONE.subtract(Versions.NONE));
        assertEquals(newVersions(0, 0),
            newVersions(0, 0).subtract(Versions.NONE));
        assertEquals(newVersions(1, 1),
            newVersions(1, 2).subtract(newVersions(2, 2)));
        assertEquals(newVersions(2, 2),
            newVersions(1, 2).subtract(newVersions(1, 1)));
        assertNull(newVersions(0, Short.MAX_VALUE).subtract(newVersions(1, 100)));
        assertEquals(newVersions(10, 10),
            newVersions(1, 10).subtract(newVersions(1, 9)));
        assertEquals(newVersions(1, 1),
            newVersions(1, 10).subtract(newVersions(2, 10)));
        assertEquals(newVersions(2, 4),
            newVersions(2, Short.MAX_VALUE).subtract(newVersions(5, Short.MAX_VALUE)));
        assertEquals(newVersions(5, Short.MAX_VALUE),
            newVersions(0, Short.MAX_VALUE).subtract(newVersions(0, 4)));
    }