/**
   * Called when the wrapped {@link ActivityBehavior} calls the {@link
   * AbstractBpmnActivityBehavior#leave(ActivityExecution)} method. Handles the completion of one of
   * the parallel instances
   */
  public void leave(ActivityExecution execution) {
    callActivityEndListeners(execution);

    int loopCounter = getLoopVariable(execution, LOOP_COUNTER);
    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;

    if (isExtraScopeNeeded()) {
      // In case an extra scope was created, it must be destroyed first before going further
      ExecutionEntity extraScope = (ExecutionEntity) execution;
      execution = execution.getParent();
      extraScope.remove();
    }

    setLoopVariable(execution.getParent(), NUMBER_OF_COMPLETED_INSTANCES, nrOfCompletedInstances);
    setLoopVariable(execution.getParent(), NUMBER_OF_ACTIVE_INSTANCES, nrOfActiveInstances);
    logLoopDetails(
        execution,
        "instance completed",
        loopCounter,
        nrOfCompletedInstances,
        nrOfActiveInstances,
        nrOfInstances);

    ExecutionEntity executionEntity = (ExecutionEntity) execution;
    executionEntity.inactivate();
    executionEntity.getParent().forceUpdate();

    List<ActivityExecution> joinedExecutions =
        executionEntity.findInactiveConcurrentExecutions(execution.getActivity());
    if (joinedExecutions.size() == nrOfInstances || completionConditionSatisfied(execution)) {

      // Removing all active child executions (ie because completionCondition is true)
      List<ExecutionEntity> executionsToRemove = new ArrayList<ExecutionEntity>();
      for (ActivityExecution childExecution : executionEntity.getParent().getExecutions()) {
        if (childExecution.isActive()) {
          executionsToRemove.add((ExecutionEntity) childExecution);
        }
      }
      for (ExecutionEntity executionToRemove : executionsToRemove) {
        if (LOGGER.isDebugEnabled()) {
          LOGGER.debug(
              "Execution {} still active, but multi-instance is completed. Removing this execution.",
              executionToRemove);
        }
        executionToRemove.inactivate();
        executionToRemove.deleteCascade("multi-instance completed");
      }
      executionEntity.takeAll(
          executionEntity.getActivity().getOutgoingTransitions(), joinedExecutions);
    }
  }