public IntervalSet negate() {
    if (!isValid()) {
      return IntervalSet.ALWAYS;
    }
    if (mStartMs == MIN_MS) {
      if (mEndMs == MAX_MS) {
        // this is ALWAYS, so the negation is never
        return IntervalSet.NEVER;
      }
      return new IntervalSet(after(mEndMs));
    }
    // start is after min
    if (mEndMs == MAX_MS) {
      return new IntervalSet(before(mStartMs));
    }

    // start is after min, and end is before max. This requires 2 intervals.
    return new IntervalSet(Lists.newArrayList(before(mStartMs), after(mEndMs)));
  }
@Test
  public void negate() {
    for (int i = 0; i < 100; i++) {
      List<Long> sortedTimes =
          ThreadLocalRandom.current().longs(1, Long.MAX_VALUE - 1).distinct().limit(2).sorted()
              .boxed().collect(Collectors.toList());
      long startMs = sortedTimes.get(0);
      long endMs = sortedTimes.get(1);
      Interval interval = Interval.between(startMs, endMs);
      Set<Interval> neg = Sets.newHashSet(interval.negate().getIntervals());

      Assert.assertTrue(neg.size() == 2);
      Assert.assertTrue(
          neg.containsAll(Arrays.asList(Interval.before(startMs), Interval.after(endMs))));
    }
  }