docs: @SuppressWarnings("unchecked")
      private <T> Entry<Collection<? extends Callable<T>>, TaskLifeCycleCallback[]> createCallbacks(Collection<? extends Callable<T>> tasks) {
          int numTasks = tasks.size();
          TaskLifeCycleCallback[] callbacks = new TaskLifeCycleCallback[numTasks];
          List<Callable<T>> taskUpdates = null;
  
          if (numTasks == 1) {
              Callable<T> task = tasks.iterator().next();
  
              ThreadContextDescriptor contextDescriptor;
              if (task instanceof ContextualAction) {
                  ContextualAction<Callable<T>> a = (ContextualAction<Callable<T>>) task;
                  contextDescriptor = a.getContextDescriptor();
                  task = a.getAction();
                  taskUpdates = Arrays.asList(task);
              } else {
                  contextDescriptor = getContextService().captureThreadContext(getExecutionProperties(task));
              }
  
              callbacks[0] = new TaskLifeCycleCallback(this, contextDescriptor);
          } else {
              // Thread context capture is expensive, so reuse callbacks when execution properties match
              Map<Map<String, String>, TaskLifeCycleCallback> execPropsToCallback = new HashMap<Map<String, String>, TaskLifeCycleCallback>();
              WSContextService contextSvc = null;
              int t = 0;
              for (Callable<T> task : tasks) {
                  if (task instanceof ContextualAction) {
                      ContextualAction<Callable<T>> a = (ContextualAction<Callable<T>>) task;
                      taskUpdates = taskUpdates == null ? new ArrayList<Callable<T>>(tasks) : taskUpdates;
                      taskUpdates.set(t, a.getAction());
                      callbacks[t++] = new TaskLifeCycleCallback(this, a.getContextDescriptor());
                  } else {
                      Map<String, String> execProps = getExecutionProperties(task);
                      TaskLifeCycleCallback callback = execPropsToCallback.get(execProps);
                      if (callback == null) {
                          contextSvc = contextSvc == null ? getContextService() : contextSvc;
                          execPropsToCallback.put(execProps, callback = new TaskLifeCycleCallback(this, contextSvc.captureThreadContext(execProps)));
                      }
                      callbacks[t++] = callback;
                  }
              }
          }
  
          return new SimpleEntry<Collection<? extends Callable<T>>, TaskLifeCycleCallback[]>(taskUpdates == null ? tasks : taskUpdates, callbacks);
      }