static void removeAllFromManagers(Iterable<DoFnLifecycleManager> managers) throws Exception {
    Collection<Exception> thrown = new ArrayList<>();
    for (DoFnLifecycleManager manager : managers) {
      thrown.addAll(manager.removeAll());
    }
    if (!thrown.isEmpty()) {
      Exception overallException = new Exception("Exceptions thrown while tearing down DoFns");
      for (Exception e : thrown) {
        overallException.addSuppressed(e);
      }
      throw overallException;
    }
  }
@Test
  public void removeAllWhenManagersThrowSuppressesAndThrows() throws Exception {
    PipelineOptions options = PipelineOptionsFactory.create();
    DoFnLifecycleManager first = DoFnLifecycleManager.of(new ThrowsInCleanupFn("foo"), options);
    DoFnLifecycleManager second = DoFnLifecycleManager.of(new ThrowsInCleanupFn("bar"), options);
    DoFnLifecycleManager third = DoFnLifecycleManager.of(new ThrowsInCleanupFn("baz"), options);
    first.get();
    second.get();
    third.get();

    final Collection<Matcher<? super Throwable>> suppressions = new ArrayList<>();
    suppressions.add(
        allOf(
            instanceOf(UserCodeException.class),
            new CausedByMatcher(new ThrowableMessageMatcher("foo"))));
    suppressions.add(
        allOf(
            instanceOf(UserCodeException.class),
            new CausedByMatcher(new ThrowableMessageMatcher("bar"))));
    suppressions.add(
        allOf(
            instanceOf(UserCodeException.class),
            new CausedByMatcher(new ThrowableMessageMatcher("baz"))));

    thrown.expect(
        new BaseMatcher<Exception>() {
          @Override
          public void describeTo(Description description) {
            description
                .appendText("Exception suppressing ")
                .appendList("[", ", ", "]", suppressions);
          }

          @Override
          public boolean matches(Object item) {
            if (!(item instanceof Exception)) {
              return false;
            }
            Exception that = (Exception) item;
            return Matchers.containsInAnyOrder(suppressions)
                .matches(ImmutableList.copyOf(that.getSuppressed()));
          }
        });

    DoFnLifecycleManagers.removeAllFromManagers(ImmutableList.of(first, second, third));
  }