code: @SuppressWarnings("unchecked")
    public <G, ERR, A, I extends Iterable<? extends G>> OrFuture<I, Every<ERR>>
    sequence(Iterable<? extends OrFuture<? extends G, ? extends Every<? extends ERR>>> input,
             Collector<? super G, A, I> collector) {
      OrPromise<I, Every<ERR>> promise = promise();
      AtomicInteger count = new AtomicInteger(0);
      AtomicBoolean finished = new AtomicBoolean(false);
      // this is necessary as nothing guarantees the iterable can be iterated multiple times
      Queue<OrFuture<? extends G, ? extends Every<? extends ERR>>> copy = new ConcurrentLinkedQueue<>();
      java.util.Iterator<? extends OrFuture<? extends G, ? extends Every<? extends ERR>>> iterator = input.iterator();
      while (iterator.hasNext()) {
        count.incrementAndGet();
        OrFuture<? extends G, ? extends Every<? extends ERR>> future = iterator.next();
        copy.add(future);
        if (!iterator.hasNext()) finished.set(true);
        future.onComplete(or -> {
          if (or.isBad()) {
            promise.tryFailure((Every<ERR>) or.getBad());
          } else if (count.decrementAndGet() == 0 && finished.get()) {
            promise.complete(accumulate(copy, collector));
          }
        });
      }
      return promise.future();
    }
docs: Transforms an Iterable of OrFutures&lt;G, ERR&gt; into an OrFuture&lt;COLL&lt;G, ERR&gt;&gt;
  where COLL is a collection created with the collector given as argument.
  <p>
  This method differs from combined in that the returned future will fail fast and complete as soon
  as one of the given futures fails.
  
  @param input iterable of OrFutures
  @param collector a collector to collect the results of the transformation
  @param <G> the good type of the future
  @param <ERR> the bad type of the future
  @param <A> the mutable accumulation type of the reduction operation
  @param <I> the result type of the reduction operation
  @return a single OrFuture