protected ActionResult ListExtensions(PackagingExtensionsOptions options, string packageType, Pager pager) {
            var selectedSource = _packagingSourceManager.GetSources().Where(s => s.Id == options.SourceId).FirstOrDefault();

            var sources = selectedSource != null
                ? new[] { selectedSource }
                : _packagingSourceManager.GetSources()
            ;

            IEnumerable<PackagingEntry> extensions = null;
            int totalCount = 0;
            foreach (var source in sources) {
                try {
                    Expression<Func<PublishedPackage, bool>> packagesCriteria = p => p.PackageType == packageType &&
                                p.IsLatestVersion &&
                                (string.IsNullOrEmpty(options.SearchText)
                                    || p.Title.Contains(options.SearchText)
                                    || p.Description.Contains(options.SearchText)
                                    || p.Tags.Contains(options.SearchText));

                    var sourceExtensions = _packagingSourceManager.GetExtensionList(true,
                        source,
                        packages => {
                            packages = packages.Where(packagesCriteria);

                            switch (options.Order) {
                                case PackagingExtensionsOrder.Downloads:
                                    packages = packages.OrderByDescending(p => p.DownloadCount).ThenBy(p => p.Title);
                                    break;
                                case PackagingExtensionsOrder.Ratings:
                                    packages = packages.OrderByDescending(p => p.Rating).ThenBy(p => p.Title);
                                    break;
                                case PackagingExtensionsOrder.Alphanumeric:
                                    packages = packages.OrderBy(p => p.Title);
                                    break;
                            }

                            if (pager.PageSize != 0) {
                                packages = packages.Skip((pager.Page - 1) * pager.PageSize).Take(pager.PageSize);
                            }

                            return packages;
                        }).ToArray();

                    // count packages separately to prevent loading everything just to count
                    totalCount += _packagingSourceManager.GetExtensionCount(
                        source,
                        packages => packages.Where(packagesCriteria));

                    extensions = extensions == null ? sourceExtensions : extensions.Concat(sourceExtensions);

                    // apply another paging rule in case there were multiple sources
                    if (sources.Count() > 1) {
                        switch (options.Order) {
                            case PackagingExtensionsOrder.Downloads:
                                extensions = extensions.OrderByDescending(p => p.DownloadCount).ThenBy(p => p.Title);
                                break;
                            case PackagingExtensionsOrder.Ratings:
                                extensions = extensions.OrderByDescending(p => p.Rating).ThenBy(p => p.Title);
                                break;
                            case PackagingExtensionsOrder.Alphanumeric:
                                extensions = extensions.OrderBy(p => p.Title);
                                break;
                        }

                        if (pager.PageSize != 0) {
                            extensions = extensions.Take(pager.PageSize);
                        }
                    }
                } catch (Exception exception) {
                    this.Error(exception, T("Error loading extensions from gallery source '{0}'. {1}.", source.FeedTitle, exception.Message), Logger, Services.Notifier);
                }
            }

            extensions = extensions ?? new PackagingEntry[0];
            var pagerShape = Services.New.Pager(pager).TotalItemCount(totalCount);

            // maintain previous route data when generating page links
            var routeData = new RouteData();
            routeData.Values.Add("Options.Order", options.Order);
            routeData.Values.Add("Options.SearchText", options.SearchText);
            routeData.Values.Add("Options.SourceId", options.SourceId);
            pagerShape.RouteData(routeData);

            extensions = extensions.ToList();

            // Populate the notifications
            IEnumerable<Tuple<ExtensionDescriptor, PackagingEntry>> extensionDescriptors = _extensionManager.AvailableExtensions()
                .Join(extensions, extensionDescriptor => extensionDescriptor.Id, packaginEntry => packaginEntry.ExtensionId(),
                      (extensionDescriptor, packagingEntry) => new Tuple<ExtensionDescriptor, PackagingEntry>(extensionDescriptor, packagingEntry));

            foreach (Tuple<ExtensionDescriptor, PackagingEntry> packagings in extensionDescriptors) {
                packagings.Item2.Installed = true;

                if (_extensionDisplayEventHandler != null) {
                    foreach (string notification in _extensionDisplayEventHandler.Displaying(packagings.Item1, ControllerContext.RequestContext)) {
                        packagings.Item2.Notifications.Add(notification);
                    }
                }
            }

            return View(packageType == DefaultExtensionTypes.Theme ? "Themes" : "Modules", new PackagingExtensionsViewModel {
                Extensions = extensions,
                Sources = _packagingSourceManager.GetSources().OrderBy(s => s.FeedTitle),
                Pager = pagerShape,
                Options = options
            });
        }
        public ActionResult Themes(PackagingExtensionsOptions options, PagerParameters pagerParameters) {
            if (!Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to list Themes")))
                return new HttpUnauthorizedResult();

            var pager = new Pager(Services.WorkContext.CurrentSite, pagerParameters);
            return ListExtensions(options, DefaultExtensionTypes.Theme, pager);
        }