/// <exclude />
        public static void Scavenge()
        {
            Log.LogVerbose(LogTitle, "Starting scavenger run");

            List <IFlowInformation> flowInformations = DataFacade.GetData <IFlowInformation>().ToList();

            // NOTE: Low performance implementation
            foreach (IFlowInformation flowInformation in flowInformations)
            {
                TimeSpan timeSpan = DateTime.Now - flowInformation.TimeStamp;
                if (timeSpan > Timeout)
                {
                    FlowToken flowToken = null;
                    string    flowTokenStr;

                    try
                    {
                        flowToken = FlowTokenSerializer.Deserialize(flowInformation.SerializedFlowToken);

                        flowTokenStr = flowToken.ToString();
                    }
                    catch (Exception)
                    {
                        flowTokenStr = flowInformation.SerializedFlowToken ?? string.Empty;
                        if (flowTokenStr.Length > 200)
                        {
                            flowTokenStr = flowTokenStr.Substring(0, 200);
                        }
                    }

                    Log.LogVerbose(LogTitle, "Scavenging flow started by username '{0}', flow = '{1}'".FormatWith(flowInformation.Username, flowTokenStr));

                    DataFacade.Delete <IFlowInformation>(flowInformation);

                    if (flowToken != null)
                    {
                        FlowControllerFacade.CancelFlow(flowToken);
                    }
                }
            }
        }
        /// <exclude />
        public static FlowToken Execute(EntityToken entityToken, ActionToken actionToken, FlowControllerServicesContainer flowControllerServicesContainer, TaskManagerEvent taskManagerEvent)
        {
            if (entityToken == null)
            {
                throw new ArgumentNullException("entityToken");
            }
            if (actionToken == null)
            {
                throw new ArgumentNullException("actionToken");
            }


            string username = UserValidationFacade.GetUsername();

#if NO_SECURITY
#else
            HookingFacade.EnsureInitialization();

            IEnumerable <UserPermissionDefinition>      userPermissionDefinitions      = PermissionTypeFacade.GetUserPermissionDefinitions(username);
            IEnumerable <UserGroupPermissionDefinition> userGroupPermissionDefinitions = PermissionTypeFacade.GetUserGroupPermissionDefinitions(username);
            SecurityResult securityResult = SecurityResolver.Resolve(UserValidationFacade.GetUserToken(), actionToken, entityToken, userPermissionDefinitions, userGroupPermissionDefinitions);
            if (securityResult != SecurityResult.Allowed && !(entityToken is SecurityViolationWorkflowEntityToken))
            {
                return(ExecuteSecurityViolation(actionToken, entityToken, flowControllerServicesContainer));
            }
#endif

            bool ignoreLocking = actionToken.IsIgnoreEntityTokenLocking();

            if (!ignoreLocking && ActionLockingFacade.IsLocked(entityToken))
            {
                return(ExecuteEntityTokenLocked(actionToken, entityToken, flowControllerServicesContainer));
            }

            IActionExecutor actionExecutor = ActionExecutorCache.GetActionExecutor(actionToken);

            ActionEventSystemFacade.FireOnBeforeActionExecution(entityToken, actionToken);

            FlowToken flowToken;
            using (TaskContainer taskContainer = TaskManagerFacade.CreateNewTasks(entityToken, actionToken, taskManagerEvent))
            {
                ITaskManagerFlowControllerService taskManagerService = null;
                if (flowControllerServicesContainer.GetService(typeof(ITaskManagerFlowControllerService)) == null)
                {
                    taskManagerService = new TaskManagerFlowControllerService(taskContainer);
                    flowControllerServicesContainer.AddService(taskManagerService);
                }

                try
                {
                    if (actionExecutor is IActionExecutorSerializedParameters)
                    {
                        string serializedEntityToken = EntityTokenSerializer.Serialize(entityToken);
                        string serializedActionToken = ActionTokenSerializer.Serialize(actionToken);

                        flowToken = Execute(actionExecutor as IActionExecutorSerializedParameters,
                                            serializedEntityToken, serializedActionToken, actionToken,
                                            flowControllerServicesContainer);
                    }
                    else
                    {
                        flowToken = Execute(actionExecutor, entityToken, actionToken,
                                            flowControllerServicesContainer);
                    }
                }
                finally
                {
                    if (taskManagerService != null)
                    {
                        flowControllerServicesContainer.RemoveService(taskManagerService);
                    }
                }

                taskContainer.SetOnIdleTaskManagerEvent(new FlowTaskManagerEvent(flowToken));
                taskContainer.UpdateTasksWithFlowToken(flowToken);

                taskContainer.SaveTasks();
            }

            ActionEventSystemFacade.FireOnAfterActionExecution(entityToken, actionToken, flowToken);

            IManagementConsoleMessageService managementConsoleMessageService = flowControllerServicesContainer
                                                                               .GetService <IManagementConsoleMessageService>();
            if (managementConsoleMessageService != null)
            {
                FlowControllerFacade.RegisterNewFlowInformation(flowToken, entityToken, actionToken,
                                                                managementConsoleMessageService.CurrentConsoleId);
            }
            else
            {
                Log.LogWarning(nameof(ActionExecutorFacade), "Missing ManagementConsoleMessageService, can not register the flow");
            }

            return(flowToken);
        }