private void fireOrContinue(
      TriggerResult triggerResult, W window, ListState<StreamRecord<IN>> windowState)
      throws Exception {
    if (!triggerResult.isFire()) {
      return;
    }

    timestampedCollector.setAbsoluteTimestamp(window.maxTimestamp());
    Iterable<StreamRecord<IN>> contents = windowState.get();

    // Work around type system restrictions...
    int toEvict = evictor.evict((Iterable) contents, Iterables.size(contents), context.window);

    FluentIterable<IN> projectedContents =
        FluentIterable.from(contents)
            .skip(toEvict)
            .transform(
                new Function<StreamRecord<IN>, IN>() {
                  @Override
                  public IN apply(StreamRecord<IN> input) {
                    return input.getValue();
                  }
                });
    userFunction.apply(context.key, context.window, projectedContents, timestampedCollector);
  }