public static <T> CompletionStage<Collection<T>> flattenFutures(
      Collection<CompletionStage<T>> inputFutures) {
    CompletableFuture<T>[] futures = inputFutures.toArray(new CompletableFuture[0]);

    return CompletableFuture.allOf(futures)
        .thenApply(
            ignored -> {
              final List<T> result =
                  Stream.of(futures).map(CompletableFuture::join).collect(Collectors.toList());
              return result;
            });
  }
@Test
  public void testFlattenFuturesForFailedFuture() {
    CompletionStage<Collection<String>> resultFuture =
        FutureUtils.flattenFutures(
            ImmutableList.of(
                CompletableFuture.completedFuture("hello"),
                createFailedFuture(new RuntimeException())));

    CompletionStage<Void> validationFuture =
        resultFuture.handle(
            (results, ex) -> {
              Assert.assertTrue(
                  "Expected exception to be of RuntimeException", ex instanceof RuntimeException);
              return null;
            });

    validationFuture.toCompletableFuture().join();
  }