docs: @FFDCIgnore(value = { RejectedExecutionException.class })
      @Override
      public <T> List<PolicyTaskFuture<T>> invokeAll(Collection<? extends Callable<T>> tasks, PolicyTaskCallback[] callbacks, long timeout,
                                                     TimeUnit unit) throws InterruptedException {
          final boolean trace = TraceComponent.isAnyTracingEnabled();
  
          int taskCount = tasks.size();
          long stop = System.nanoTime() + unit.toNanos(timeout);
          long qWait, remaining;
  
          List<PolicyTaskFutureImpl<T>> futures = new ArrayList<PolicyTaskFutureImpl<T>>(taskCount);
          try {
              // create futures in advance, which gives the callback an opportunity to reject
              int t = 0;
              for (Callable<T> task : tasks) {
                  PolicyTaskCallback callback = callbacks == null ? null : callbacks[t++];
                  PolicyExecutorImpl executor = callback == null ? this : (PolicyExecutorImpl) callback.getExecutor(this);
                  long startTimeoutNS = callback == null ? startTimeout : callback.getStartTimeout(executor.startTimeout);
                  futures.add(new PolicyTaskFutureImpl<T>(executor, task, callback, startTimeoutNS));
              }
  
              // enqueue all tasks
              for (PolicyTaskFutureImpl<T> taskFuture : futures) {
                  remaining = stop - System.nanoTime();
                  if (remaining <= 0)
                      throw new RejectedExecutionException(Tr.formatMessage(tc, "CWWKE1204.unable.to.invoke", taskFuture.getIdentifier(),
                                                                            taskCount - futures.indexOf(taskFuture) + 1, taskCount, timeout, unit));
                  qWait = taskFuture.executor.maxWaitForEnqueueNS.get();
                  taskFuture.executor.enqueue(taskFuture,
                                              qWait < remaining ? qWait : remaining, // limit waiting to lesser of maxWaitForEnqueue and remaining time
                                              false); // never run on the current thread because it would prevent timeout
              }
  
              // wait for completion
              for (PolicyTaskFutureImpl<T> future : futures)
                  if (future.await(stop - System.nanoTime(), TimeUnit.NANOSECONDS) > PolicyTaskFutureImpl.RUNNING)
                      taskCount--;
                  else
                      break;
          } catch (RejectedExecutionException x) {
              if (trace && tc.isDebugEnabled())
                  Tr.debug(this, tc, "rejected", x);
              if (x.getCause() instanceof InterruptedException)
                  throw (InterruptedException) x.getCause();
              else
                  throw x;
          } finally {
              if (taskCount != 0)
                  for (Future<T> f : futures)
                      f.cancel(true);
          }
  
          @SuppressWarnings({ "rawtypes", "unchecked" })
          List<PolicyTaskFuture<T>> list = (List) futures;
          return list;
      }