docs: protected int createInstances(DelegateExecution execution) {
      int nrOfInstances = resolveNrOfInstances(execution);
      if (nrOfInstances < 0) {
        throw new ActivitiIllegalArgumentException("Invalid number of instances: must be non-negative integer value" + ", but was " + nrOfInstances);
      }
  
      execution.setMultiInstanceRoot(true);
  
      setLoopVariable(execution, NUMBER_OF_INSTANCES, nrOfInstances);
      setLoopVariable(execution, NUMBER_OF_COMPLETED_INSTANCES, 0);
      setLoopVariable(execution, NUMBER_OF_ACTIVE_INSTANCES, nrOfInstances);
  
      List<DelegateExecution> concurrentExecutions = new ArrayList<DelegateExecution>();
      for (int loopCounter = 0; loopCounter < nrOfInstances; loopCounter++) {
        DelegateExecution concurrentExecution = Context.getCommandContext().getExecutionEntityManager()
            .createChildExecution((ExecutionEntity) execution);
        concurrentExecution.setCurrentFlowElement(activity);
        concurrentExecution.setActive(true);
        concurrentExecution.setScope(false);
  
        concurrentExecutions.add(concurrentExecution);
        logLoopDetails(concurrentExecution, "initialized", loopCounter, 0, nrOfInstances, nrOfInstances);
      }
  
      // Before the activities are executed, all executions MUST be created up front
      // Do not try to merge this loop with the previous one, as it will lead
      // to bugs, due to possible child execution pruning.
      for (int loopCounter = 0; loopCounter < nrOfInstances; loopCounter++) {
        DelegateExecution concurrentExecution = concurrentExecutions.get(loopCounter);
        // executions can be inactive, if instances are all automatics
        // (no-waitstate) and completionCondition has been met in the meantime
        if (concurrentExecution.isActive() && !concurrentExecution.isEnded() && concurrentExecution.getParent().isActive() && !concurrentExecution.getParent().isEnded()) {
          setLoopVariable(concurrentExecution, getCollectionElementIndexVariable(), loopCounter);
          executeOriginalBehavior(concurrentExecution, loopCounter);
        }
      }
  
      // See ACT-1586: ExecutionQuery returns wrong results when using multi
      // instance on a receive task The parent execution must be set to false, so it wouldn't show up in
      // the execution query when using .activityId(something). Do not we cannot nullify the
      // activityId (that would have been a better solution), as it would break boundary event behavior.
      if (!concurrentExecutions.isEmpty()) {
        ExecutionEntity executionEntity = (ExecutionEntity) execution;
        executionEntity.setActive(false);
      }
  
      return nrOfInstances;
    }