/// <summary>
        /// Gets work based on a known transition timespan.
        /// </summary>
        /// <param name="session">A secure Session.</param>
        /// <param name="formId">The form id.</param>
        /// <param name="state">The Workflow State.</param>
        /// <param name="transition">The Workflow Transision.</param>
        /// <param name="work">The work list to update.</param>
        private void GetWorkAfterTimespan(SecureSession session, string formId, WorkflowState state, WorkflowTransition transition, UnitOfWorkList<ApplicationWorkItem> work)
        {
            DateTime? lastTransitionDate = transition.GetKnownTransitionDateTime();
            if (lastTransitionDate != null)
            {
                ApplicationSearchFilter filter = new ApplicationSearchFilter
                {
                    ApplicationStates = new List<string> { state.Name },
                    StateTransitionDate = new DateTimeRange()
                    {
                        To = lastTransitionDate
                    }
                };

                // Pagination pagination = new Pagination() { PageIndex = 0, PageSize = 50 };
                Pagination pagination = null;

                IEnumerable<Application> apps = this.formServiceGateway.SearchApplications(session, formId, filter, pagination);
                work.AddRange(apps.Select(app => new ApplicationWorkItem
                {
                    Application = app,
                    Transition = transition
                }).Select(workItem => new UnitOfWork<ApplicationWorkItem>(workItem)));
            }
        }
        /// <summary>
        /// Gets work for all applicaiotns in the specified state.
        /// </summary>
        /// <param name="session">A secure Session.</param>
        /// <param name="formId">The form id.</param>
        /// <param name="state">The Workflow State.</param>
        /// <param name="transition">The Workflow Transision.</param>
        /// <param name="work">The work list to update.</param>
        private void GetAllEventsInState(SecureSession session, string formId, WorkflowState state, WorkflowTransition transition, UnitOfWorkList<ApplicationWorkItem> work)
        {
            ApplicationSearchFilter filter = new ApplicationSearchFilter
            {
                ApplicationStates = new List<string> { state.Name }
            };

            IEnumerable<Application> apps = this.formServiceGateway.SearchApplications(session, formId, filter);
            work.AddRange(apps.Select(app => new ApplicationWorkItem
            {
                Application = app,
                Transition = transition
            }).Select(workItem => new UnitOfWork<ApplicationWorkItem>(workItem)));
        }
        /// <summary>
        /// Gets work fo all apps in a geven state after a fixed point in time.
        /// </summary>
        /// <param name="session">A secure Session.</param>
        /// <param name="formId">The form id.</param>
        /// <param name="state">The Workflow State.</param>
        /// <param name="transition">The Workflow Transision.</param>
        /// <param name="work">The work list to update.</param>
        private void GetWorkAfterDateTime(SecureSession session, string formId, WorkflowState state, WorkflowTransition transition, UnitOfWorkList<ApplicationWorkItem> work)
        {
            if (transition.ExitStateName == state.Name)
            {
                return;
            }

            ApplicationSearchFilter filter = new ApplicationSearchFilter
            {
                ApplicationStates = new List<string> { state.Name }
            };

            IEnumerable<Application> apps = null;

            if (transition.OnDateTimeCompare == ComparisonType.Value)
            {
                DateTime? pointInTime = transition.GetOnDateTimeTransitionDateTime();
                if (pointInTime != null && pointInTime <= DateTime.Now)
                {
                    apps = this.formServiceGateway.SearchApplications(session, formId, filter, null);
                }
            }

            if (transition.OnDateTimeCompare == ComparisonType.Field && !string.IsNullOrEmpty(transition.OnDateTimeField))
            {
                var offset = DateTime.Now;
                if (!string.IsNullOrEmpty(transition.OnDateTimeOffset))
                {
                    offset = offset.Subtract(transition.OnDateTimeOffset);
                }

                filter.ApplicationDataDates = new Dictionary<string, DateTimeRange>
                {
                    { transition.OnDateTimeField, new DateTimeRange() { To = offset } }
                };

                apps = this.formServiceGateway.SearchApplications(session, formId, filter);
            }

            if (apps != null)
            {
                work.AddRange(apps.Select(app => new ApplicationWorkItem
                {
                    Application = app,
                    Transition = transition
                }).Select(workItem => new UnitOfWork<ApplicationWorkItem>(workItem)));
            }
        }
        /// <summary>
        /// Finds the states that have any time system transitions.
        /// </summary>
        /// <param name="session">A <see cref="SecureSession"/> session object.</param>
        /// <param name="formId">A form ID.</param>
        /// <param name="state">A <see cref="WorkflowState"/> object.</param>
        /// <returns>The states that have any time system transitions.</returns>
        private UnitOfWorkList<ApplicationWorkItem> FindWork(SecureSession session, string formId, WorkflowState state)
        {
            UnitOfWorkList<ApplicationWorkItem> work = new UnitOfWorkList<ApplicationWorkItem>();
            foreach (WorkflowTransition transition in state.Transitions)
            {
                switch (transition.Trigger)
                {
                    case TriggerEvent.AfterDateTime:
                        this.GetWorkAfterTimespan(session, formId, state, transition, work);
                        break;

                    case TriggerEvent.OnDateTime:
                        this.GetWorkAfterDateTime(session, formId, state, transition, work);
                        break;

                    case TriggerEvent.AtAnyTime:
                        this.GetAllEventsInState(session, formId, state, transition, work);
                        break;

                    case TriggerEvent.EmailLink:
                        Dictionary<string, WorkflowAction> actionList = this.GetAllWorkflowActionsForTransition(formId);

                        foreach (var item in actionList)
                        {
                            var appId = item.Key;
                            var action = item.Value;
                            var app = this.formServiceGateway.GetApplication(session, appId);
                            ApplicationWorkItem workItem = new ApplicationWorkItem
                            {
                                Application = app,
                                Transition = transition
                            };
                            workItem.Transition = state.Transitions.FirstOrDefault(t => t.Name == action.WorkflowActionData.TransitionName) ?? transition;
                            workItem.EmailAddress = action.WorkflowActionData.EmailAddress;
                            workItem.UserId = action.WorkflowActionData.UserId;
                            work.Add(new UnitOfWork<ApplicationWorkItem>(workItem));
                        }

                        break;
                }
            }

            return work;
        }