/// <summary>
        /// Retrieve a list of all applications assigned to the organisations of the current user.
        /// </summary>
        /// <param name="sessionData">The session data.</param>
        /// <returns>A list of all applications assigned to the organisations of the current user.</returns>
        public Dictionary<string, ApplicationList> GetAssignedOrganisationApplications(SessionData sessionData)
        {
            User user = this.userManager.GetUserById(sessionData.UserId);
            IEnumerable<string> organisationIds = user.GetAllOrganisations().Select(o => o.Key);
            ApplicationList assignedApplications = this.DataAccess.GetAssignedOrganisationApplications(organisationIds);

            ProductSearchFilter filter = new ProductSearchFilter
            {
                FormIds = assignedApplications.Select(a => a.FormId).ToList()
            };
            ProductList<ProductSearchResult> productList = this.DataAccess.FindProducts<ProductSearchResult>(filter, new Pagination());

            RoleList roleList = this.DataAccess.GetRoleList();
            SecureSession secureSession = new SecureSession(user);
            Dictionary<string, ApplicationList> assignedApplicationList = new Dictionary<string, ApplicationList>();

            foreach (Application app in assignedApplications)
            {
                int formVersion = app.FormVersion ?? productList[app.FormId].Version;
                AccessLevel applicationAccess = this.entitlementProvider.GetApplicationAccess(secureSession, app, roleList, formVersion);
                if (AccessLevel.NoAccess == applicationAccess)
                {
                    continue;
                }

                if (!productList.Exists(x => x.Id == app.FormId))
                {
                    continue;
                }

                string formName = productList[app.FormId].Name;
                if (!assignedApplicationList.ContainsKey(formName))
                {
                    assignedApplicationList.Add(formName, new ApplicationList());
                }

                assignedApplicationList[formName].Add(app);
            }

            return assignedApplicationList;
        }
        /// <summary>
        /// Gets a list of all products the user has access too.
        /// </summary>
        /// <param name="sessionData">The session data.</param>
        /// <param name="filter">The search filter.</param>
        /// <param name="pagination">The paging information. Defaults to <see langword="null"/>.</param>
        /// <returns>
        /// A list of all products the user has access to and their associated identification fields.
        /// </returns>
        public ProductList<DashboardProductSearchResult> FindProducts(SessionData sessionData, ProductSearchFilter filter, Pagination pagination)
        {
            IEnumerable<Organisation> organisations = new List<Organisation>();
            User user = this.userManager.GetUserById(sessionData.UserId);
            SecureSession secureSession = new SecureSession(sessionData.DeserializationSource, sessionData.SessionId, user);

            if (!string.IsNullOrWhiteSpace(filter.OrganisationHandle))
            {
                organisations = this.DataAccess.FindOrganisations(new OrganisationSearchFilter { OrganisationHandle = filter.OrganisationHandle })
                                                .Where(x => x.Enabled && x.FormVault);
                if (organisations.Any() && secureSession.AuthenticatedUser != null && !secureSession.AuthenticatedUser.Organisations.ContainsKey(organisations.First().Id))
                {
                    secureSession.AuthenticatedUser.Organisations.Add(organisations.First().Id, organisations.First().Name);
                }
            }

            UserFormAccessList authorisedForms = this.entitlementProvider.GetAuthorisedForms(secureSession, this.DataAccess.GetRoleList());
            filter.FormIds = secureSession.AuthenticatedUser.IsAdministrator() ? authorisedForms.Select(f => f.FormId).ToList() : authorisedForms.AccessibleForms().ToList();
            if (!filter.FormIds.Any())
            {
                return new ProductList<DashboardProductSearchResult>();
            }

            filter.SearchTerm = filter.SearchTerm != null ? Regex.Escape(filter.SearchTerm) : filter.SearchTerm;

            int removalCount = 0;
            ProductList<DashboardProductSearchResult> allProducts = this.DataAccess.FindProducts<DashboardProductSearchResult>(filter, pagination);
            if (!string.IsNullOrWhiteSpace(filter.OrganisationHandle))
            {
                if (organisations.Any())
                {
                    removalCount = allProducts.Count(p => p.OrganisationId != organisations.First().Id);
                    allProducts.RemoveAll(p => p.OrganisationId != organisations.First().Id);
                }
                else
                {
                    return new ProductList<DashboardProductSearchResult>();
                }
            }

            if (allProducts.Count == 0)
            {
                return allProducts;
            }

            WorkflowConfigurationContainerList workflowConfigs = this.workflowService.FindWorkflowConfigurations(WorkflowTargetType.FormApplication, allProducts.ToDictionary(p => p.Id, p => p.Version));
            foreach (DashboardProductSearchResult product in allProducts)
            {
                if (secureSession.AuthenticatedUser.IsAdministrator())
                {
                    product.CanStartApplication = true;
                }
                else
                {
                    string defaultState = workflowConfigs[product.Id].Configuration.InitialState.Name;
                    product.CanStartApplication = authorisedForms[product.Id].ExplicitWorkflowStates.Contains(defaultState);
                }
            }

            removalCount += allProducts.Count(p => !p.CanStartApplication);

            if (pagination != null)
            {
                pagination.TotalRecordCount -= removalCount;
            }

            return allProducts;
        }