public static <W extends BoundedWindow, AccumT, OutputT>
      TriggerTester<Integer, OutputT, W> combining(
          WindowFn<?, W> windowFn,
          Trigger<W> trigger,
          AccumulationMode mode,
          KeyedCombineFn<String, Integer, AccumT, OutputT> combineFn,
          Coder<OutputT> outputCoder,
          Duration allowedDataLateness)
          throws Exception {

    WindowingStrategy<?, W> strategy =
        WindowingStrategy.of(windowFn)
            .withTrigger(trigger)
            .withMode(mode)
            .withAllowedLateness(allowedDataLateness);

    CoderRegistry registry = new CoderRegistry();
    registry.registerStandardCoders();
    AppliedCombineFn<String, Integer, AccumT, OutputT> fn =
        AppliedCombineFn.<String, Integer, AccumT, OutputT>withInputCoder(
            combineFn, registry, KvCoder.of(StringUtf8Coder.of(), VarIntCoder.of()));

    return new TriggerTester<Integer, OutputT, W>(
        strategy,
        SystemReduceFn.<String, Integer, AccumT, OutputT, W>combining(StringUtf8Coder.of(), fn)
            .create(KEY),
        outputCoder);
  }
  public static <W extends BoundedWindow> TriggerTester<Integer, Iterable<Integer>, W> nonCombining(
      WindowFn<?, W> windowFn,
      Trigger<W> trigger,
      AccumulationMode mode,
      Duration allowedDataLateness)
      throws Exception {

    WindowingStrategy<?, W> strategy =
        WindowingStrategy.of(windowFn)
            .withTrigger(trigger)
            .withMode(mode)
            .withAllowedLateness(allowedDataLateness);
    return nonCombining(strategy);
  }