docs: @FFDCIgnore(value = { RejectedExecutionException.class })
      @Override
      public <T> List<PolicyTaskFuture<T>> invokeAll(Collection<? extends Callable<T>> tasks, PolicyTaskCallback[] callbacks) throws InterruptedException {
          final boolean trace = TraceComponent.isAnyTracingEnabled();
  
          // Determine if we need a permit to run one or more of the tasks on the current thread, and if so, acquire it,
          int taskCount = tasks.size();
          boolean havePermit = false;
          boolean useCurrentThread = maxPolicy == MaxPolicy.loose || (havePermit = taskCount > 0 && maxConcurrencyConstraint.tryAcquire());
  
          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 tasks (except the last if we are able to run tasks on the current thread)
              int numToSubmitAsync = useCurrentThread ? taskCount - 1 : taskCount;
              t = 0;
              for (PolicyTaskFutureImpl<T> taskFuture : futures)
                  if (t++ < numToSubmitAsync || taskFuture.executor != this) {
                      boolean enqueued;
                      if (useCurrentThread && taskFuture.executor == this)
                          enqueued = taskFuture.executor.enqueue(taskFuture, 0, true);
                      else
                          enqueued = taskFuture.executor.enqueue(taskFuture, taskFuture.executor.maxWaitForEnqueueNS.get(), null);
  
                      if (!enqueued) // must immediately return if ran on current thread and was interrupted
                          taskFuture.throwIfInterrupted();
                  } else {
                      taskFuture.accept(true);
                  }
  
              // run on current thread (by current executor) if possible
              if (useCurrentThread)
                  for (t = numToSubmitAsync; t >= 0; t--) {
                      PolicyTaskFutureImpl<T> taskFuture = futures.get(t);
                      State currentState = taskFuture.executor.state.get();
                      if (taskFuture.executor == this && t == numToSubmitAsync) { // we intentionally avoided submitting the last task
                          if (currentState != State.ACTIVE)
                              throw new RejectedExecutionException(Tr.formatMessage(tc, "CWWKE1202.submit.after.shutdown", taskFuture.getIdentifier()));
                      } else if (taskFuture.executor == this && !taskFuture.isDone() && currentState.canStartTask && queue.remove(taskFuture)) {
                          maxQueueSizeConstraint.release();
                          taskFuture.nsQueueEnd = System.nanoTime();
                      } else {
                          if (trace && tc.isDebugEnabled())
                              Tr.debug(this, tc, "no longer in queue, or this executor is unable to run it", taskFuture);
                          continue; // other thread could already be processing the task, or it could be cancelled
                      }
  
                      if (taskFuture.nsStartBy == taskFuture.nsAcceptBegin - 1 // never times out, or
                          || taskFuture.nsStartBy - taskFuture.nsQueueEnd > 0) // have time remaining
                          runTask(taskFuture);
                      else { // timed out
                          taskFuture.nsRunEnd = taskFuture.nsQueueEnd;
                          RejectedExecutionException x = new RejectedExecutionException(new StartTimeoutException( //
                                          taskFuture.getIdentifier(), taskFuture.getTaskName(), //
                                          taskFuture.nsQueueEnd - taskFuture.nsAcceptBegin, //
                                          taskFuture.nsStartBy - taskFuture.nsAcceptBegin));
                          taskFuture.abort(false, x);
                          throw x;
                      }
  
                      // must immediately return if current thread is interrupted
                      taskFuture.throwIfInterrupted();
                  }
  
              // wait for completion
              for (PolicyTaskFutureImpl<T> future : futures) {
                  future.await();
                  taskCount--;
              }
          } 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 (havePermit)
                  transferOrReleasePermit();
  
              if (taskCount != 0)
                  for (Future<T> f : futures)
                      f.cancel(true);
          }
  
          @SuppressWarnings({ "rawtypes", "unchecked" })
          List<PolicyTaskFuture<T>> list = (List) futures;
          return list;
      }