@Override
  public boolean shouldFire(TriggerStateMachine.TriggerContext context) throws Exception {
    return context.trigger().subTrigger(ACTUAL).invokeShouldFire(context)
        || context.trigger().subTrigger(UNTIL).invokeShouldFire(context);
  }
@Test
  public void testShouldFireAfterMerge() throws Exception {
    tester =
        TriggerStateMachineTester.forTrigger(
            AfterEachStateMachine.inOrder(
                AfterPaneStateMachine.elementCountAtLeast(5)
                    .orFinally(AfterWatermarkStateMachine.pastEndOfWindow()),
                RepeatedlyStateMachine.forever(AfterPaneStateMachine.elementCountAtLeast(1))),
            Sessions.withGapDuration(Duration.millis(10)));

    // Finished the orFinally in the first window
    tester.injectElements(1);
    IntervalWindow firstWindow = new IntervalWindow(new Instant(1), new Instant(11));
    assertFalse(tester.shouldFire(firstWindow));
    tester.advanceInputWatermark(new Instant(11));
    assertTrue(tester.shouldFire(firstWindow));
    tester.fireIfShouldFire(firstWindow);

    // Set up second window where it is not done
    tester.injectElements(5);
    IntervalWindow secondWindow = new IntervalWindow(new Instant(5), new Instant(15));
    assertFalse(tester.shouldFire(secondWindow));

    // Merge them, if the merged window were on the second trigger, it would be ready
    tester.mergeWindows();
    IntervalWindow mergedWindow = new IntervalWindow(new Instant(1), new Instant(15));
    assertFalse(tester.shouldFire(mergedWindow));

    // Now adding 3 more makes the main trigger ready to fire
    tester.injectElements(1, 2, 3, 4, 5);
    tester.mergeWindows();
    assertTrue(tester.shouldFire(mergedWindow));
  }