docs: function executeAllProcessOneTasks(batch, cancellable, context) {
    const states = batch.states;
    const messages = batch.messages;
    const m = messages.length;
    const ms = toCountString(m, 'message');
  
    const t = batch.taskDefs.processOneTaskDefs.length;
    const ts = toCountString(t, 'process one task');
  
    if (m <= 0) {
      if (context.debugEnabled) context.debug(`Skipping execution of ${ts} for ${batch.describe(true)}, since ${ms}`);
      return Promise.resolve([]);
    }
    if (t <= 0) {
      context.warn(`Skipping execution of ${ts} for ${batch.describe(true)}, since ${ts}`);
      return Promise.resolve([]);
    }
  
    // Find all of the messages that do NOT have any preceding messages, which must be processed before they can be processed
    const independentMessages = batch.firstMessagesToProcess && batch.firstMessagesToProcess.length > 0 ?
      batch.firstMessagesToProcess : messages.filter(message => !states.get(message).prevMessage);
  
    if (context.debugEnabled) {
      const i = independentMessages.length;
      context.debug(`About to execute ${ts} on ${i} independent of ${ms} for ${batch.describe(true)}`);
    }
  
    // Execute all of the incomplete processOne tasks on each of the independent messages and collect their promises
    const promises = independentMessages.map(message => executeProcessOneTasks(batch, message, cancellable, context));
  
    return Promises.flatten(promises, cancellable, flattenOpts, context).then(
      independentOutcomes => {
        const outcomes = Arrays.flatten(independentOutcomes);
        context.trace(`executeAllProcessOneTasks - independent outcomes (${independentOutcomes.length}) vs flattened outcomes (${outcomes.length})`);
        return outcomes;
      }
    );
  }