protected internal virtual void ExecuteInclusiveGatewayLogic(IExecutionEntity execution)
        {
            ICommandContext         commandContext         = Context.CommandContext;
            IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager;

            LockFirstParentScope(execution);

            ICollection <IExecutionEntity> allExecutions     = executionEntityManager.FindChildExecutionsByProcessInstanceId(execution.ProcessInstanceId);
            IEnumerator <IExecutionEntity> executionIterator = allExecutions.GetEnumerator();
            bool oneExecutionCanReachGateway = false;

            while (!oneExecutionCanReachGateway && executionIterator.MoveNext())
            {
                IExecutionEntity executionEntity = executionIterator.Current;
                if (!executionEntity.ActivityId.Equals(execution.CurrentActivityId))
                {
                    bool canReachGateway = ExecutionGraphUtil.IsReachable(execution.ProcessDefinitionId, executionEntity.ActivityId, execution.CurrentActivityId);
                    if (canReachGateway)
                    {
                        oneExecutionCanReachGateway = true;
                    }
                }
                else if (executionEntity.ActivityId.Equals(execution.CurrentActivityId) && executionEntity.IsActive)
                {
                    // Special case: the execution has reached the inc gw, but the operation hasn't been executed yet for that execution
                    oneExecutionCanReachGateway = true;
                }
            }

            // If no execution can reach the gateway, the gateway activates and executes fork behavior
            if (!oneExecutionCanReachGateway)
            {
                logger.LogDebug("Inclusive gateway cannot be reached by any execution and is activated");

                // Kill all executions here (except the incoming)
                ICollection <IExecutionEntity> executionsInGateway = executionEntityManager.FindInactiveExecutionsByActivityIdAndProcessInstanceId(execution.CurrentActivityId, execution.ProcessInstanceId);
                foreach (IExecutionEntity executionEntityInGateway in executionsInGateway)
                {
                    if (!executionEntityInGateway.Id.Equals(execution.Id))
                    {
                        commandContext.HistoryManager.RecordActivityEnd(executionEntityInGateway, null);
                        executionEntityManager.DeleteExecutionAndRelatedData(executionEntityInGateway, null, false);
                    }
                }

                // Leave
                commandContext.Agenda.PlanTakeOutgoingSequenceFlowsOperation(execution, true);
            }
        }
        public override void Execute(IExecutionEntity execution)
        {
            // First off all, deactivate the execution
            execution.Inactivate();

            // Join
            FlowElement     flowElement = execution.CurrentFlowElement;
            ParallelGateway parallelGateway;

            if (flowElement is ParallelGateway)
            {
                parallelGateway = (ParallelGateway)flowElement;
            }
            else
            {
                throw new ActivitiException("Programmatic error: parallel gateway behaviour can only be applied" + " to a ParallelGateway instance, but got an instance of " + flowElement);
            }

            LockFirstParentScope(execution);

            IExecutionEntity multiInstanceExecution = null;

            if (HasMultiInstanceParent(parallelGateway))
            {
                multiInstanceExecution = FindMultiInstanceParentExecution(execution);
            }

            IExecutionEntityManager        executionEntityManager = Context.CommandContext.ExecutionEntityManager;
            ICollection <IExecutionEntity> joinedExecutions       = executionEntityManager.FindInactiveExecutionsByActivityIdAndProcessInstanceId(execution.CurrentActivityId, execution.ProcessInstanceId);

            if (multiInstanceExecution != null)
            {
                joinedExecutions = CleanJoinedExecutions(joinedExecutions, multiInstanceExecution);
            }

            int nbrOfExecutionsToJoin          = parallelGateway.IncomingFlows.Count;
            int nbrOfExecutionsCurrentlyJoined = joinedExecutions.Count;

            // Fork

            // Is needed to set the endTime for all historic activity joins
            Context.CommandContext.HistoryManager.RecordActivityEnd(execution, null);

            if (nbrOfExecutionsCurrentlyJoined == nbrOfExecutionsToJoin)
            {
                // Fork
                if (log.IsEnabled(LogLevel.Debug))
                {
                    log.LogDebug($"parallel gateway '{execution.CurrentActivityId}' activates: {nbrOfExecutionsCurrentlyJoined} of {nbrOfExecutionsToJoin} joined");
                }

                if (parallelGateway.IncomingFlows.Count > 1)
                {
                    // All (now inactive) children are deleted.
                    foreach (IExecutionEntity joinedExecution in joinedExecutions)
                    {
                        // The current execution will be reused and not deleted
                        if (!joinedExecution.Id.Equals(execution.Id))
                        {
                            executionEntityManager.DeleteExecutionAndRelatedData(joinedExecution, null, false);
                        }
                    }
                }

                // TODO: potential optimization here: reuse more then 1 execution, only 1 currently
                Context.Agenda.PlanTakeOutgoingSequenceFlowsOperation(execution, false); // false -> ignoring conditions on parallel gw
            }
            else if (log.IsEnabled(LogLevel.Debug))
            {
                log.LogDebug($"parallel gateway '{execution.CurrentActivityId}' does not activate: {nbrOfExecutionsCurrentlyJoined} of {nbrOfExecutionsToJoin} joined");
            }
        }