protected internal virtual void PropagateError(string errorCode, string errorMessage, System.Exception origException,
                                                       IActivityExecution execution)
        {
            var walker = new ActivityExecutionHierarchyWalker(execution);

            var errorDeclarationFinder = new ErrorDeclarationForProcessInstanceFinder(this, origException, errorCode,
                                                                                      execution.Activity);
            var activityExecutionMappingCollector = new ActivityExecutionMappingCollector(execution);

            walker.AddScopePreVisitor(errorDeclarationFinder);
            walker.AddExecutionPreVisitor(activityExecutionMappingCollector);
            // map variables to super executions in the hierarchy of called process instances
            walker.AddExecutionPreVisitor(new OutputVariablesPropagator());

            try
            {
                walker.WalkUntil((element) => errorDeclarationFinder.ErrorEventDefinition != null || element == null);
            }
            catch (System.Exception e)
            {
                //separate the exception handling to support a fail-safe error propagation
                throw new ErrorPropagationException(this, e);
            }

            var errorHandlingActivity = errorDeclarationFinder.ErrorHandlerActivity;

            // process the error
            if (errorHandlingActivity == null)
            {
                if (origException == null)
                {
                    Log.MissingBoundaryCatchEvent(execution.Activity.Id, errorCode);
                    execution.End(true);
                }
                else
                {
                    // throw original exception
                    throw origException;
                }
            }
            else
            {
                var errorDefinition        = errorDeclarationFinder.ErrorEventDefinition;
                var errorHandlingExecution =
                    activityExecutionMappingCollector.GetExecutionForScope(errorHandlingActivity.EventScope);

                if (!ReferenceEquals(errorDefinition.ErrorCodeVariable, null))
                {
                    errorHandlingExecution.SetVariable(errorDefinition.ErrorCodeVariable, errorCode);
                }
                if (!ReferenceEquals(errorDefinition.ErrorMessageVariable, null))
                {
                    errorHandlingExecution.SetVariable(errorDefinition.ErrorMessageVariable, errorMessage);
                }
                errorHandlingExecution.ExecuteActivity(errorHandlingActivity);
            }
        }
        protected internal virtual void executeEscalationHandler(EscalationEventDefinition escalationEventDefinition,
                                                                 ActivityExecutionMappingCollector activityExecutionMappingCollector)
        {
            var escalationHandler = escalationEventDefinition.EscalationHandler;
            var escalationScope   = GetScopeForEscalation(escalationEventDefinition);
            IActivityExecution escalationExecution =
                activityExecutionMappingCollector.GetExecutionForScope(escalationScope);

            if (!ReferenceEquals(escalationEventDefinition.EscalationCodeVariable, null))
            {
                escalationExecution.SetVariable(escalationEventDefinition.EscalationCodeVariable,
                                                Escalation.EscalationCode);
            }

            escalationExecution.ExecuteActivity(escalationHandler);
        }