docs: public void leave(DelegateExecution execution) {
  
      boolean zeroNrOfInstances = false;
      if (resolveNrOfInstances(execution) == 0) {
        // Empty collection, just leave.
        zeroNrOfInstances = true;
        removeLocalLoopVariable(execution, getCollectionElementIndexVariable());
        super.leave(execution); // Plan the default leave
        execution.setMultiInstanceRoot(false);
      }
  
      int loopCounter = getLoopVariable(execution, getCollectionElementIndexVariable());
      int nrOfInstances = getLoopVariable(execution, NUMBER_OF_INSTANCES);
      int nrOfCompletedInstances = getLoopVariable(execution, NUMBER_OF_COMPLETED_INSTANCES) + 1;
      int nrOfActiveInstances = getLoopVariable(execution, NUMBER_OF_ACTIVE_INSTANCES) - 1;
  
      Context.getCommandContext().getHistoryManager().recordActivityEnd((ExecutionEntity) execution, null);
      callActivityEndListeners(execution);
  
      if (zeroNrOfInstances) {
        return;
      }
  
      DelegateExecution miRootExecution = getMultiInstanceRootExecution(execution);
      if (miRootExecution != null) { // will be null in case of empty collection
        setLoopVariable(miRootExecution, NUMBER_OF_COMPLETED_INSTANCES, nrOfCompletedInstances);
        setLoopVariable(miRootExecution, NUMBER_OF_ACTIVE_INSTANCES, nrOfActiveInstances);
      }
  
      //executeCompensationBoundaryEvents(execution.getCurrentFlowElement(), execution);
  
      logLoopDetails(execution, "instance completed", loopCounter, nrOfCompletedInstances, nrOfActiveInstances, nrOfInstances);
  
      ExecutionEntity executionEntity = (ExecutionEntity) execution;
  
      if (executionEntity.getParent() != null) {
  
        executionEntity.inactivate();
        lockFirstParentScope(executionEntity);
  
        if (nrOfCompletedInstances >= nrOfInstances || completionConditionSatisfied(execution.getParent())) {
  
          ExecutionEntity executionToUse = null;
          if (nrOfInstances > 0) {
            executionToUse = executionEntity.getParent();
          } else {
            executionToUse = executionEntity;
          }
  
          boolean hasCompensation = false;
          Activity activity = (Activity) execution.getCurrentFlowElement();
          if (activity instanceof Transaction) {
            hasCompensation = true;
          } else if (activity instanceof SubProcess) {
            SubProcess subProcess = (SubProcess) activity;
            for (FlowElement subElement : subProcess.getFlowElements()) {
              if (subElement instanceof Activity) {
                Activity subActivity = (Activity) subElement;
                if (CollectionUtil.isNotEmpty(subActivity.getBoundaryEvents())) {
                  for (BoundaryEvent boundaryEvent : subActivity.getBoundaryEvents()) {
                    if (CollectionUtil.isNotEmpty(boundaryEvent.getEventDefinitions()) &&
                        boundaryEvent.getEventDefinitions().get(0) instanceof CompensateEventDefinition) {
  
                      hasCompensation = true;
                      break;
                    }
                  }
                }
              }
            }
          }
  
          if (hasCompensation) {
            ScopeUtil.createCopyOfSubProcessExecutionForCompensation(executionToUse);
          }
  
          if (activity instanceof CallActivity) {
            ExecutionEntityManager executionEntityManager = Context.getCommandContext().getExecutionEntityManager();
            if (executionToUse != null) {
              List<String> callActivityExecutionIds = new ArrayList<String>();
  
              // Find all execution entities that are at the call activity
              List<ExecutionEntity> childExecutions = executionEntityManager.collectChildren(executionToUse);
              if (childExecutions != null) {
                for (ExecutionEntity childExecution : childExecutions) {
                  if (activity.getId().equals(childExecution.getCurrentActivityId())) {
                    callActivityExecutionIds.add(childExecution.getId());
                  }
                }
  
                // Now all call activity executions have been collected, loop again and check which should be removed
                for (int i=childExecutions.size()-1; i>=0; i--) {
                  ExecutionEntity childExecution = childExecutions.get(i);
                  if (StringUtils.isNotEmpty(childExecution.getSuperExecutionId())
                      && callActivityExecutionIds.contains(childExecution.getSuperExecutionId())) {
  
                    executionEntityManager.deleteProcessInstanceExecutionEntity(childExecution.getId(), activity.getId(),
                        "call activity completion condition met", true, false);
                  }
                }
  
              }
            }
          }
  
          deleteChildExecutions(executionToUse, false, Context.getCommandContext());
          removeLocalLoopVariable(executionToUse, getCollectionElementIndexVariable());
          executionToUse.setScope(false);
          executionToUse.setMultiInstanceRoot(false);
          Context.getAgenda().planTakeOutgoingSequenceFlowsOperation(executionToUse, true);
        }
  
      } else {
        removeLocalLoopVariable(execution, getCollectionElementIndexVariable());
        execution.setMultiInstanceRoot(false);
        super.leave(execution);
      }
    }