public async Task <TvShow> GetTvShowAsync(Video video, bool forceRefresh)
        {
            TvShow show;

            if (!video.ExternalIds.TmdbId.IsNullOrEmpty())
            {
                show = await _tvShowCache.GetOrAddAsync(video.ExternalIds.TmdbId,
                                                        async s => await _tmdbConnection.GetTvShowAsync(s, video.SeasonNumber, video.EpisodeNumber),
                                                        forceRefresh);

                if (show != null)
                {
                    _tvShowCacheByTitle.Add(new TitleYearExternalIdKey(video.Show, video.Year, show.ExternalExternalIds.ImdbId,
                                                                       show.ExternalExternalIds.TvdbId),
                                            show);

                    return(show);
                }
            }

            if (video.ExternalIds.ImdbId.IsNullOrEmpty() && video.ExternalIds.TvdbId.IsNullOrEmpty())
            {
                show = await _tmdbConnection.SearchForTvShowAsync(video.Show, video.ExternalIds,
                                                                  video.SeasonNumber, video.EpisodeNumber);

                if (show != null)
                {
                    _tvShowCache.Add(show.Id, show);
                    _tvShowCacheByTitle.Add(new TitleYearExternalIdKey(video.Show, video.Year, show.ExternalExternalIds.ImdbId,
                                                                       show.ExternalExternalIds.TvdbId), show);
                }

                return(show);
            }

            var key = new TitleYearExternalIdKey(video.Show, video.Year, video.ExternalIds.ImdbId, video.ExternalIds.TvdbId);

            show = await _tvShowCacheByTitle.GetOrAddAsync(key,
                                                           async s => await _tmdbConnection.SearchForTvShowAsync(video.Show, video.ExternalIds,
                                                                                                                 video.SeasonNumber, video.EpisodeNumber),
                                                           forceRefresh);

            if (show != null)
            {
                _tvShowCache.Add(show.Id, show);
            }

            return(show);
        }
        public async Task <Movie> GetMovieAsync(Video video, bool forceRefresh)
        {
            Movie movie;

            if (!video.ExternalIds.TmdbId.IsNullOrEmpty())
            {
                movie = await _movieCache.GetOrAddAsync(video.ExternalIds.TmdbId,
                                                        async s => await _tmdbConnection.GetMovieAsync(s),
                                                        forceRefresh);

                if (movie != null)
                {
                    _movieCacheByTitle.Add(new TitleYearExternalIdKey(video.Title, video.Year, movie.ImdbId), movie);
                    return(movie);
                }
            }

            if (video.ExternalIds.ImdbId.IsNullOrEmpty())
            {
                movie = await _tmdbConnection.SearchForMovieAsync(video.Title, video.Year, video.ExternalIds);

                if (movie != null)
                {
                    _movieCache.Add(movie.Id, movie);
                    _movieCacheByTitle.Add(new TitleYearExternalIdKey(video.Title, video.Year, movie.ImdbId), movie);
                }

                return(movie);
            }

            var key = new TitleYearExternalIdKey(video.Title, video.Year, video.ExternalIds.ImdbId);

            movie = await _movieCacheByTitle.GetOrAddAsync(key,
                                                           async s => await _tmdbConnection.SearchForMovieAsync(video.Title, video.Year, video.ExternalIds),
                                                           forceRefresh);

            if (movie != null)
            {
                _movieCache.Add(movie.Id, movie);
            }

            return(movie);
        }