@Override
    public <T> CompletableFuture<T> submit(Callable<T> callable) {
        final CompletableFuture<T> promise = new CompletableFuture<>();
        try {
            CompletableFuture.supplyAsync(ContextPropagator.decorateSupplier(config.getContextPropagator(),() -> {
                try {
                    publishBulkheadEvent(() -> new BulkheadOnCallPermittedEvent(name));
                    return callable.call();
                } catch (CompletionException e) {
                    throw e;
                } catch (Exception e){
                    throw new CompletionException(e);
                }
            }), executorService).whenComplete((result, throwable) -> {
                publishBulkheadEvent(() -> new BulkheadOnCallFinishedEvent(name));
                if (throwable != null) {
                    promise.completeExceptionally(throwable);
                } else {
                    promise.complete(result);
                }
            });
        } catch (RejectedExecutionException rejected) {
            publishBulkheadEvent(() -> new BulkheadOnCallRejectedEvent(name));
            throw BulkheadFullException.createBulkheadFullException(this);
        }
        return promise;
    }
@Test
    public void testRunnableThreadLocalContextPropagator() {

        TestThreadLocalContextHolder.put("ValueShouldCrossThreadBoundary");
        AtomicReference<String> reference = new AtomicReference<>();

        fixedThreadPoolBulkhead
            .submit(() -> reference.set((String) TestThreadLocalContextHolder.get().orElse(null)));

        waitAtMost(5, TimeUnit.SECONDS).until(matches(() ->
            assertThat(reference).hasValue("ValueShouldCrossThreadBoundary")));
    }