public static <T extends BoundedWindow> TimestampPrefixingWindowCoder<T> of(
      Coder<T> windowCoder) {
    return new TimestampPrefixingWindowCoder<>(windowCoder);
  }
@Test
  public void testEncodeAndDecode() throws Exception {
    List<IntervalWindow> intervalWindowsToTest =
        Lists.newArrayList(
            new IntervalWindow(new Instant(0L), new Instant(1L)),
            new IntervalWindow(new Instant(100L), new Instant(200L)),
            new IntervalWindow(new Instant(0L), BoundedWindow.TIMESTAMP_MAX_VALUE));
    TimestampPrefixingWindowCoder<IntervalWindow> coder1 =
        TimestampPrefixingWindowCoder.of(IntervalWindow.getCoder());
    for (IntervalWindow window : intervalWindowsToTest) {
      CoderProperties.coderDecodeEncodeEqual(coder1, window);
    }

    GlobalWindow globalWindow = GlobalWindow.INSTANCE;
    TimestampPrefixingWindowCoder<GlobalWindow> coder2 =
        TimestampPrefixingWindowCoder.of(GlobalWindow.Coder.INSTANCE);
    CoderProperties.coderDecodeEncodeEqual(coder2, globalWindow);
    TimestampPrefixingWindowCoder<CustomWindow> coder3 =
        TimestampPrefixingWindowCoder.of(CustomWindowCoder.of(true, true));
    for (CustomWindow window : CUSTOM_WINDOW_LIST) {
      CoderProperties.coderDecodeEncodeEqual(coder3, window);
    }
  }