code: @Deprecated
      public static <T> CompletableFuture<T> addTimeout(CompletableFuture<T> future, Callable<T> onTimeout, Duration timeout, ScheduledExecutorService executorService)
      {
          requireNonNull(future, "future is null");
          requireNonNull(onTimeout, "timeoutValue is null");
          requireNonNull(timeout, "timeout is null");
          requireNonNull(executorService, "executorService is null");
  
          // if the future is already complete, just return it
          if (future.isDone()) {
              return future;
          }
  
          // create an unmodifiable future that propagates cancel
          // down cast is safe because this is our code
          UnmodifiableCompletableFuture<T> futureWithTimeout = (UnmodifiableCompletableFuture<T>) unmodifiableFuture(future, true);
  
          // schedule a task to complete the future when the time expires
          ScheduledFuture<?> timeoutTaskFuture = executorService.schedule(new TimeoutFutureTask<>(futureWithTimeout, onTimeout, future), timeout.toMillis(), MILLISECONDS);
  
          // when future completes, cancel the timeout task
          future.whenCompleteAsync((value, exception) -> timeoutTaskFuture.cancel(false), executorService);
  
          return futureWithTimeout;
      }
docs: Returns a new future that is completed when the supplied future completes or
  when the timeout expires.  If the timeout occurs or the returned CompletableFuture
  is canceled, the supplied future will be canceled.