/// <summary>
        /// Find organization business objects by custom predicates.
        /// </summary>
        /// <param name="predicate">linq predicate. see organization properties for predicate at <see cref="RapidWebDev.Platform.Linq.Organization"/>.</param>
        /// <param name="orderby">dynamic orderby command</param>
        /// <param name="pageIndex">current paging index</param>
        /// <param name="pageSize">page size</param>
        /// <param name="recordCount">total hit records count</param>
        /// <returns>Returns enumerable organizations</returns>
        public IEnumerable<OrganizationObject> FindOrganizations(LinqPredicate predicate, string orderby, int pageIndex, int pageSize, out int recordCount)
        {
            try
            {
                using (MembershipDataContext ctx = DataContextFactory.Create<MembershipDataContext>())
                {
                    // set query criteria.
                    var q = from org in ctx.Organizations
                            where org.ApplicationId == authenticationContext.ApplicationId
                            select org;

                    if (predicate != null && !Kit.IsEmpty(predicate.Expression))
                        q = q.Where(predicate.Expression, predicate.Parameters);

                    if (!Kit.IsEmpty(orderby))
                        q = q.OrderBy(orderby);

                    // get count of matched organizations
                    recordCount = q.Count();

                    // collect organizations
                    List<Organization> organizations = q.Skip(pageIndex * pageSize).Take(pageSize).ToList();

                    // collect all OrganizationsInHierarchy entities of the organizations.
                    Guid[] organizationIdArray = organizations.Select(org => org.OrganizationId).ToArray();
                    var organizationsInHierarchyDictionary = (from organizationsInHierarchy in ctx.OrganizationsInHierarchies
                                                              where organizationsInHierarchy.ApplicationId == this.authenticationContext.ApplicationId
                                                                    && organizationIdArray.Contains(organizationsInHierarchy.OrganizationId)
                                                              group organizationsInHierarchy by organizationsInHierarchy.OrganizationId into g
                                                              select g).ToDictionary(g => g.Key, g => g.ToList());

                    List<OrganizationObject> organizationObjects = new List<OrganizationObject>();

                    // go through each organization to parse dynamic properties and hierarchies.
                    foreach (Organization org in organizations)
                    {
                        OrganizationObject organizationObject = new OrganizationObject()
                        {
                            ExtensionDataTypeId = org.ExtensionDataTypeId,
                            OrganizationId = org.OrganizationId,
                            OrganizationCode = org.OrganizationCode,
                            OrganizationName = org.OrganizationName,
                            OrganizationTypeId = org.OrganizationTypeId,
                            Description = org.Description,
                            Status = org.Status,
                            CreatedBy = org.CreatedBy,
                            CreatedDate = org.CreatedDate,
                            LastUpdatedBy = org.LastUpdatedBy,
                            LastUpdatedDate = org.LastUpdatedDate,
                            ParentOrganizationId = org.ParentOrganizationId
                        };

                        if (organizationsInHierarchyDictionary.ContainsKey(org.OrganizationId))
                        {
                            List<OrganizationsInHierarchy> organizationsInHierarchies = organizationsInHierarchyDictionary[org.OrganizationId];
                            foreach (OrganizationsInHierarchy organizationsInHierarchy in organizationsInHierarchies)
                                organizationObject.Hierarchies[organizationsInHierarchy.HierarchyType] = organizationsInHierarchy.HierarchyDataId;
                        }

                        organizationObject.ParseExtensionPropertiesFrom(org);
                        base.AddCache(organizationObject.OrganizationId, organizationObject.Clone());

                        UpdateTimeZone(organizationObject);
                        organizationObjects.Add(organizationObject);
                    }

                    return organizationObjects;
                }
            }
            catch (Exception exp)
            {
                Logger.Instance(this).Error(exp);
                throw;
            }
        }
        /// <summary>
        /// Find organization elements by enumerable organization ids.
        /// </summary>
        /// <param name="organizationIdList">enumerabe organization type ids, null or empty value indicates to query all organizations</param>
        /// <returns></returns>
        private IDictionary<Guid, OrganizationObject> BulkGetOrganizationsFromDB(IEnumerable<Guid> organizationIdList)
        {
            try
            {
                if (organizationIdList.Count() == 0)
                    return new Dictionary<Guid, OrganizationObject>();

                Guid[] organizationIdArray = organizationIdList.ToArray();
                using (MembershipDataContext ctx = DataContextFactory.Create<MembershipDataContext>())
                {
                    // collect all organizations
                    var q = ctx.Organizations.Where(org => organizationIdArray.Contains(org.OrganizationId) && org.ApplicationId == authenticationContext.ApplicationId);
                    List<Organization> organizations = (from org in ctx.Organizations
                                                        where organizationIdArray.Contains(org.OrganizationId)
                                                             && org.ApplicationId == authenticationContext.ApplicationId
                                                        select org).Distinct().ToList();

                    // collect related hierarchies for the organizations.
                    var organizationsInHierarchyDictionary = (from organizationsInHierarchy in ctx.OrganizationsInHierarchies
                                                              where organizationsInHierarchy.ApplicationId == this.authenticationContext.ApplicationId
                                                                    && organizationIdArray.Contains(organizationsInHierarchy.OrganizationId)
                                                              group organizationsInHierarchy by organizationsInHierarchy.OrganizationId into g
                                                              select g).ToDictionary(g => g.Key, g => g.ToList());

                    List<OrganizationObject> organizationObjects = new List<OrganizationObject>();

                    // go through each organization to parse dynamic properties and hierarchies.
                    foreach (Organization org in organizations)
                    {
                        OrganizationObject organizationObject = new OrganizationObject()
                        {
                            ExtensionDataTypeId = org.ExtensionDataTypeId,
                            OrganizationId = org.OrganizationId,
                            OrganizationCode = org.OrganizationCode,
                            OrganizationName = org.OrganizationName,
                            OrganizationTypeId = org.OrganizationTypeId,
                            Description = org.Description,
                            Status = org.Status,
                            CreatedBy = org.CreatedBy,
                            CreatedDate = org.CreatedDate,
                            LastUpdatedBy = org.LastUpdatedBy,
                            LastUpdatedDate = org.LastUpdatedDate,
                            ParentOrganizationId = org.ParentOrganizationId
                        };

                        if (organizationsInHierarchyDictionary.ContainsKey(org.OrganizationId))
                        {
                            List<OrganizationsInHierarchy> organizationsInHierarchies = organizationsInHierarchyDictionary[org.OrganizationId];
                            foreach (OrganizationsInHierarchy organizationsInHierarchy in organizationsInHierarchies)
                                organizationObject.Hierarchies[organizationsInHierarchy.HierarchyType] = organizationsInHierarchy.HierarchyDataId;
                        }

                        organizationObject.ParseExtensionPropertiesFrom(org);
                        base.AddCache(organizationObject.OrganizationId, organizationObject.Clone());

                        UpdateTimeZone(organizationObject);
                        organizationObjects.Add(organizationObject);
                    }

                    return organizationObjects.ToDictionary(org => org.OrganizationId, org => org);
                }
            }
            catch (Exception exp)
            {
                Logger.Instance(this).Error(exp);
                throw;
            }
        }