int nrOfActiveInstances = getLoopVariable(execution, NUMBER_OF_ACTIVE_INSTANCES) - 1;
if (isExtraScopeNeeded()) {
resetMiRootActivityInstanceId(execution);
// 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;
// remove event subscriptions that separately created for multi instance
executionEntity.removeEventSubscriptions();
executionEntity.inactivate();
executionEntity.getParent().forceUpdate();
List<ActivityExecution> joinedExecutions = executionEntity.findInactiveConcurrentExecutions(execution.getActivity());
if (joinedExecutions.size() == nrOfInstances || completionConditionSatisfied(execution)) {
resetMiRootActivityInstanceId(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.isLoggable(Level.FINE)) {
LOGGER.fine("Execution " + executionToRemove + " still active, "
+ "but multi-instance is completed. Removing this execution.");
}
executionToRemove.inactivate();
executionToRemove.deleteCascade("multi-instance completed");
}
executionEntity.takeAll(activity.getOutgoingTransitions(), joinedExecutions);
} else {
if(isExtraScopeNeeded()) {
callActivityEndListeners(execution);
} else {
executionEntity.setActivityInstanceId(null);
}
}
}