default U reduce(U identity, BinaryOperator<U> accumulator) {
    if (getLastActive().isSequential()) {
      Object[] result = {identity};
      forEach(
          r -> {
            if (result[0] == null) result[0] = r;
            else {
              result[0] = accumulator.apply((U) result[0], r);
            }
          });
      return (U) result[0];
    }
    Function<FastFuture, U> safeJoin =
        (FastFuture cf) -> (U) BlockingStreamHelper.getSafe(cf, getErrorHandler());
    IncrementalReducer<U> collector =
        new IncrementalReducer(
            this.getLazyCollector().get().withResults(new ArrayList<>()),
            this,
            getParallelReduction());
    Object[] result = {identity};
    try {
      this.getLastActive()
          .injectFutures()
          .forEach(
              next -> {
                collector.getConsumer().accept(next);

                result[0] = collector.reduce(safeJoin, (U) result[0], accumulator);
              });
    } catch (SimpleReactProcessingException e) {

    }
    return collector.reduceResults(
        collector.getConsumer().getAllResults(), safeJoin, (U) result[0], accumulator);
  }
  default void forEach(Consumer<? super U> c) {
    Function<FastFuture<U>, U> safeJoin =
        (FastFuture<U> cf) -> (U) BlockingStreamHelper.getSafe(cf, getErrorHandler());

    if (getLastActive().isSequential()) {
      // if single threaded we can simply push from each Future into the collection to be returned
      try {
        this.getLastActive()
            .operation(f -> f.peek(c))
            .injectFutures()
            .forEach(
                next -> {
                  safeJoin.apply(next);
                });
      } catch (SimpleReactProcessingException e) {

      }

      return;
    }

    IncrementalReducer<U> collector =
        new IncrementalReducer(
            this.getLazyCollector().get().withResults(new ArrayList<>()),
            this,
            getParallelReduction());
    try {
      this.getLastActive()
          .operation(f -> f.peek(c))
          .injectFutures()
          .forEach(
              next -> {
                collector.getConsumer().accept(next);
              });
    } catch (SimpleReactProcessingException e) {

    }
    collector.getConsumer().block(safeJoin);
  }
  default Optional<U> reduce(BinaryOperator<U> accumulator) {
    if (getLastActive().isSequential()) {
      Object[] result = {null};
      forEach(
          r -> {
            if (result[0] == null) result[0] = r;
            else {
              result[0] = accumulator.apply((U) result[0], r);
            }
          });
      return (Optional) Optional.ofNullable(result[0]);
    }
    Function<FastFuture, U> safeJoin =
        (FastFuture cf) -> (U) BlockingStreamHelper.getSafe(cf, getErrorHandler());
    IncrementalReducer<U> collector =
        new IncrementalReducer(
            this.getLazyCollector().get().withResults(new ArrayList<>()),
            this,
            getParallelReduction());
    Optional[] result = {Optional.empty()};
    try {
      this.getLastActive()
          .injectFutures()
          .forEach(
              next -> {
                collector.getConsumer().accept(next);
                if (!result[0].isPresent()) result[0] = collector.reduce(safeJoin, accumulator);
                else result[0] = result[0].map(v -> collector.reduce(safeJoin, (U) v, accumulator));
              });
    } catch (SimpleReactProcessingException e) {

    }

    if (result[0].isPresent())
      return result[0].map(
          v ->
              collector.reduceResults(
                  collector.getConsumer().getAllResults(), safeJoin, (U) v, accumulator));

    return collector.reduceResults(collector.getConsumer().getAllResults(), safeJoin, accumulator);
  }