public static IQueryable <ApplicationVideo> ApplyFilters(
            ApplicationDbContext context,
            IQueryable <ApplicationVideo> source,
            Tag[] filters,
            ArchiveMode archiveMode,
            PublishedMode publishedMode = PublishedMode.SomePublished)
        {
            var publishedStatus = from avsv in context.ApplicationVideoSourceVideos
                                  join sv in context.SourceVideos on avsv.SourceVideoId equals sv.Id
                                  group sv.PublishedStatus by avsv.ApplicationVideoId;

            var videoList = from v in source.Where(x => FilterArchive(archiveMode, x.Archived))
                            join vl in publishedStatus on v.Id equals vl.Key into publishedStatuses
                            from ps in publishedStatuses.DefaultIfEmpty()
                            where AggregatePublishedMode(ps, publishedMode)
                            select v;

            foreach (var tagSet in filters.GroupBy(x => x.Type))
            {
                if (tagSet.Count() > 0)
                {
                    switch (tagSet.Key)
                    {
                    case "platform":
                        // videoList = from v in videoList
                        //             join avsv in context.ApplicationVideoSourceVideos on v.Id equals avsv.ApplicationVideoId
                        //             join sv in context.SourceVideos.Where(x => tagSet.Select(v => v.Value).Contains(x.Platform)) on avsv.SourceVideoId equals sv.Id
                        //             select v;
                        break;

                    case "search":
                        videoList = videoList.Where(x => tagSet.Where(v => v != null).Any(v => EF.Functions.Like(x.Title, "%" + v.Value + "%")));
                        break;

                    case "playlist":
                        videoList = from v in videoList
                                    join vp in context.ApplicationPlaylistApplicationVideos on v.Id equals vp.ApplicationVideoId
                                    join p in context.ApplicationPlaylists.Where(x => tagSet.Select(v => v.Value).Contains(x.Title)) on vp.ApplicationPlaylistId equals p.Id
                                    select v;
                        break;

                    case Constants.GenericTag:
                        videoList = from v in videoList
                                    join vp in context.ApplicationVideoApplicationGenericTags on v.Id equals vp.VideoId
                                    join m in context.ApplicationGenericTags.Where(x => tagSet.Select(v => v.Value).Contains(x.Tag)) on vp.TagId equals m.Id
                                    select v;
                        break;

                    default:
                        videoList = from v in videoList
                                    join vp in context.ApplicationVideoApplicationMetaTags on v.Id equals vp.VideoId
                                    join m in context.ApplicationMetaTags.Where(x => tagSet.Select(v => v.Value).Contains(x.Tag)) on vp.TagId equals m.Id
                                    join mt in context.ApplicationMetaTagsTypes.Where(x => x.Type == tagSet.Key) on m.TypeId equals mt.Id
                                    select v;
                        break;
                    }
                }
            }
            return(videoList);
        }
        public static bool AggregatePublishedMode(IEnumerable <bool> sources, PublishedMode mode)
        {
            if (sources == null)
            {
                return(false);
            }
            switch (mode)
            {
            case PublishedMode.AllPublished:
                return(sources.Aggregate((acc, cur) => acc && cur));

            case PublishedMode.AllUnpublished:
                return(!sources.Aggregate((acc, cur) => acc || cur));

            case PublishedMode.SomePublished:
                return(sources.Aggregate((acc, cur) => acc || cur));

            case PublishedMode.All:
                return(true);

            default:
                throw new ArgumentException($"Invalid publish mode '{mode}'");
            }
        }