Represents declarative sorting.
Inheritance: IDescriptor
        public static GridModel ToGridModel(this IQueryable queryable, int page, int pageSize, IList<SortDescriptor> sortDescriptors, IEnumerable<IFilterDescriptor> filterDescriptors,
            IEnumerable<GroupDescriptor> groupDescriptors)
        {
            IQueryable data = queryable;

            if (filterDescriptors.Any())
            {
                data = data.Where(filterDescriptors);
            }

            GridModel result = new GridModel();

            result.Total = data.Count();
            IList<SortDescriptor> temporarySortDescriptors = new List<SortDescriptor>();

            if (!sortDescriptors.Any() && queryable.Provider.IsEntityFrameworkProvider())
            {
                // The Entity Framework provider demands OrderBy before calling Skip.
                SortDescriptor sortDescriptor = new SortDescriptor
                {
                    Member = queryable.ElementType.FirstSortableProperty()
                };
                sortDescriptors.Add(sortDescriptor);
                temporarySortDescriptors.Add(sortDescriptor);
            }

            if (groupDescriptors.Any())
            {
                groupDescriptors.Reverse().Each(groupDescriptor =>
                {
                    SortDescriptor sortDescriptor = new SortDescriptor
                    {
                        Member = groupDescriptor.Member,
                        SortDirection = groupDescriptor.SortDirection
                    };

                    sortDescriptors.Insert(0, sortDescriptor);
                    temporarySortDescriptors.Add(sortDescriptor);
                });
            }

            if (sortDescriptors.Any())
            {
                data = data.Sort(sortDescriptors);
            }

            data = data.Page(page - 1, pageSize);

            if (groupDescriptors.Any())
            {
                data = data.GroupBy(groupDescriptors);
            }

            result.Data = data;

            temporarySortDescriptors.Each(sortDescriptor => sortDescriptors.Remove(sortDescriptor));

            return result;
        }
        public static GridModel ToGridModel(this IQueryable queryable, int page, int pageSize, IList<SortDescriptor> sortDescriptors, IEnumerable<IFilterDescriptor> filterDescriptors,
            IEnumerable<GroupDescriptor> groupDescriptors)
        {
            IQueryable data = queryable;

            #if MVC3
            if (queryable.ElementType.IsDynamicObject())
            {
                var firstItem = queryable.Cast<object>().FirstOrDefault();
                if (firstItem != null)
                {
                    if (filterDescriptors.Any())
                    {
                        filterDescriptors.SetMemberTypeFrom(firstItem);
                    }

                    if (groupDescriptors.Any())
                    {
                        groupDescriptors.SetMemberTypeFrom(firstItem);
                    }
                }
            }
            #endif

            if (filterDescriptors.Any())
            {
                data = data.Where(filterDescriptors);
            }

            GridModel result = new GridModel();

            result.Total = data.Count();
            IList<SortDescriptor> temporarySortDescriptors = new List<SortDescriptor>();

            if (!sortDescriptors.Any() && queryable.Provider.IsEntityFrameworkProvider())
            {
                // The Entity Framework provider demands OrderBy before calling Skip.
                SortDescriptor sortDescriptor = new SortDescriptor
                {
                    Member = queryable.ElementType.FirstSortableProperty()
                };
                sortDescriptors.Add(sortDescriptor);
                temporarySortDescriptors.Add(sortDescriptor);
            }

            if (groupDescriptors.Any())
            {
                groupDescriptors.Reverse().Each(groupDescriptor =>
                {
                    SortDescriptor sortDescriptor = new SortDescriptor
                    {
                        Member = groupDescriptor.Member,
                        SortDirection = groupDescriptor.SortDirection
                    };

                    sortDescriptors.Insert(0, sortDescriptor);
                    temporarySortDescriptors.Add(sortDescriptor);
                });
            }

            if (sortDescriptors.Any())
            {
                data = data.Sort(sortDescriptors);
            }

            var notPagedData = data;

            data = data.Page(page - 1, pageSize);

            if (groupDescriptors.Any())
            {
                data = data.GroupBy(notPagedData, groupDescriptors);
            }

            result.Data = data;

            temporarySortDescriptors.Each(sortDescriptor => sortDescriptors.Remove(sortDescriptor));

            return result;
        }