@Override
  public ParSeqBasedCompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action,
      Executor executor)
  {
    Task<?> that = getOrGenerateTaskFromStage(other);
    return nextStageByComposingTask(Task.par(_task, that).flatMap("thenAcceptBothAsync", (t, u) -> Task.blocking(() -> {
      action.run();
      return null;
    }, executor)));
  }
@Test public void testRunAfterBothAsync() throws Exception {
    CountDownLatch waitLatch = new CountDownLatch(1);
    CompletionStage<String> completionStage1 = createTestStage(TESTVALUE1);
    CompletionStage<String> completionStage2 = createTestStage(TESTVALUE2);

    finish(completionStage1.runAfterBothAsync(completionStage2, () -> {
      assertEquals(THREAD_NAME_VALUE, Thread.currentThread().getName());
      waitLatch.countDown();
    }, _mockExecutor));

    assertTrue(waitLatch.await(1000, TimeUnit.MILLISECONDS));
  }