concurrent/src/main/java/io/airlift/concurrent/MoreFutures.java
@Deprecated
    public static <V> CompletableFuture<List<V>> allAsList(List<CompletableFuture<? extends V>> futures)
    {
        CompletableFuture<Void> allDoneFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));

        // Eagerly propagate exceptions, rather than waiting for all the futures to complete first (default behavior)
        for (CompletableFuture<? extends V> future : futures) {
            future.whenComplete((v, throwable) -> {
                if (throwable != null) {
                    allDoneFuture.completeExceptionally(throwable);
                }
            });
        }

        return unmodifiableFuture(allDoneFuture.thenApply(v ->
                futures.stream()
                        .map(CompletableFuture::join)
                        .collect(Collectors.<V>toList())));
    }
@Deprecated
    public static <V> CompletableFuture<List<V>> allAsList(List<CompletableFuture<? extends V>> futures)
    {
        CompletableFuture<Void> allDoneFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));

        // Eagerly propagate exceptions, rather than waiting for all the futures to complete first (default behavior)
        for (CompletableFuture<? extends V> future : futures) {
            future.whenComplete((v, throwable) -> {
                if (throwable != null) {
                    allDoneFuture.completeExceptionally(throwable);
                }
            });
        }

        return unmodifiableFuture(allDoneFuture.thenApply(v ->
                futures.stream()
                        .map(CompletableFuture::join)
                        .collect(Collectors.<V>toList())));
    }
Returns an unmodifiable future that is completed when all of the given
futures complete. If any of the given futures complete exceptionally, then the
returned future also does so immediately, with a CompletionException holding this exception
as its cause. Otherwise, the results of the given futures are reflected in the
returned future as a list of results matching the input order. If no futures are
provided, returns a future completed with an empty list.