public static TimeWindows ofSizeAndGrace(final Duration size, final Duration afterWindowEnd) throws IllegalArgumentException {
        final String sizeMsgPrefix = prepareMillisCheckFailMsgPrefix(size, "size");
        final long sizeMs = validateMillisecondDuration(size, sizeMsgPrefix);

        final String afterWindowEndMsgPrefix = prepareMillisCheckFailMsgPrefix(afterWindowEnd, "afterWindowEnd");
        final long afterWindowEndMs = validateMillisecondDuration(afterWindowEnd, afterWindowEndMsgPrefix);

        return new TimeWindows(sizeMs, sizeMs, afterWindowEndMs, true);
    }
@Test
    public void gracePeriodShouldEnforceBoundaries() {
        TimeWindows.ofSizeAndGrace(ofMillis(3L), ofMillis(0L));

        try {
            TimeWindows.ofSizeAndGrace(ofMillis(3L), ofMillis(-1L));
            fail("should not accept negatives");
        } catch (final IllegalArgumentException e) {
            //expected
        }
    }