public static AfterProcessingTimeStateMachine pastFirstElementInPane() {
    return new AfterProcessingTimeStateMachine(IDENTITY);
  }
@Test
  public void testAfterProcessingTimeFixedWindows() throws Exception {
    Duration windowDuration = Duration.millis(10);
    SimpleTriggerStateMachineTester<IntervalWindow> tester =
        TriggerStateMachineTester.forTrigger(
            AfterProcessingTimeStateMachine.pastFirstElementInPane()
                .plusDelayOf(Duration.millis(5)),
            FixedWindows.of(windowDuration));

    tester.advanceProcessingTime(new Instant(10));

    // Timer at 15
    tester.injectElements(1);
    IntervalWindow firstWindow = new IntervalWindow(new Instant(0), new Instant(10));
    tester.advanceProcessingTime(new Instant(12));
    assertFalse(tester.shouldFire(firstWindow));

    // Load up elements in the next window, timer at 17 for them
    tester.injectElements(11, 12, 13);
    IntervalWindow secondWindow = new IntervalWindow(new Instant(10), new Instant(20));
    assertFalse(tester.shouldFire(secondWindow));

    // Not quite time to fire
    tester.advanceProcessingTime(new Instant(14));
    assertFalse(tester.shouldFire(firstWindow));
    assertFalse(tester.shouldFire(secondWindow));

    // Timer at 19 for these in the first window; it should be ignored since the 15 will fire first
    tester.injectElements(2, 3);

    // Advance past the first timer and fire, finishing the first window
    tester.advanceProcessingTime(new Instant(16));
    assertTrue(tester.shouldFire(firstWindow));
    assertFalse(tester.shouldFire(secondWindow));
    tester.fireIfShouldFire(firstWindow);
    assertTrue(tester.isMarkedFinished(firstWindow));

    // The next window fires and finishes now
    tester.advanceProcessingTime(new Instant(18));
    assertTrue(tester.shouldFire(secondWindow));
    tester.fireIfShouldFire(secondWindow);
    assertTrue(tester.isMarkedFinished(secondWindow));
  }