@Override
  public ParSeqBasedCompletionStage<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action,
      Executor executor)
  {
    return nextStageByComposingTask(_task.transformWith("whenCompleteAsync", prevTaskResult -> {
      if (prevTaskResult.isFailed()) {
        return Task.blocking(() -> {
          try {
            action.accept(null, prevTaskResult.getError());
          } catch (Exception e) {
            // no ops
          }
          return null;
        }, executor)
            .flatMap((t) -> Task.failure(prevTaskResult.getError())); // always Complete the stage with original failure
      } else {
        return Task.blocking(() -> {
          action.accept(prevTaskResult.get(),
              prevTaskResult.getError()); // Complete the stage with original value or new failure
          return prevTaskResult.get();
        }, executor);
      }
    }));
  }
@Test
  public void testWhenCompleteAsync() throws Exception
  {
    CountDownLatch waitLatch = new CountDownLatch(1);
    CompletionStage<String> stage = createTestStage(TESTVALUE1).whenCompleteAsync((v, t) -> {
      assertEquals(THREAD_NAME_VALUE, Thread.currentThread().getName());
      waitLatch.countDown();
    }, _mockExecutor);
    finish(stage);
    assertTrue(waitLatch.await(1000, TimeUnit.MILLISECONDS));
  }