code: public static <T, R> ComposableFuture<List<R>> batch(final List<T> elements, final int batchSize,
                                                         final FutureSuccessHandler<T, R> producer) {
      return batch(elements, 0, batchSize, producer);
    }
docs: Execute the producer on each element in the list in batches.
  every batch is executed in parallel and the next batch begins only after the previous one ended.
  An error in one of the futures produced by the producer will end the flow and return a future containing the error
  <p>
  The batches are created in order i.e. the first batch is the first section of the list and so on.
  The order within a single batch is undefined since it runs in parallel.
  
  @param elements  the input to the producer
  @param batchSize how many items will be processed in parallel
  @param producer  produces a future based on input from the element list
  @param <T>       the type of the elements in the input list
  @param <R>       the result type of the future returning from the producer
  @return a future containing a list of all the results produced by the producer.