/// <summary>
        /// Search for a series with a given query and a language and returns null if api response is not well formed
        /// </summary>
        /// <param name="query">Query that identifies the series.</param>
        /// <param name="language">Series language.</param>
        /// <returns>Returns a readonly collection of series or null if response is not well formed</returns>
        public async Task<List<TheTvDbSeries>> SearchSeriesAsync(string query, TheTvDbLanguage language)
        {
            if (query == null) throw new ArgumentNullException(nameof(query));

            var seriesCollectionRaw = await _seriesServiceProxy.Search(query, language);
            return _seriesParser.ParseSearch(seriesCollectionRaw);
        }
        public async Task<string> Retrieve(uint episodeId, TheTvDbLanguage language)
        {
            var url = string.Format(EpisodeUrlFormat, 
                ProxyConfiguration.BaseUrl, 
                ProxyConfiguration.ApiKey, 
                episodeId, 
                language.ToShortString());
            
            var response = await GetAsync(url);

            return await response.Content.ReadAsStringAsync();
        }
        public async Task<string> Search(string query, TheTvDbLanguage language)
        {
            if (query == null) throw new ArgumentNullException(nameof(query));

            var url = string.Format(SearchSeriesUrlFormat, 
                ProxyConfiguration.BaseUrl, 
                query, 
                language.ToShortString());

            var response = await GetAsync(url);

            return await response.Content.ReadAsStringAsync();
        }
        public async Task<Windows.Storage.Streams.IInputStream> RetrieveFull(uint showId, TheTvDbLanguage language)
#endif
        {
            var url = string.Format(FullSeriesUrlFormat, 
                ProxyConfiguration.BaseUrl, 
                ProxyConfiguration.ApiKey, 
                showId, 
                language.ToShortString());

            var response = await GetAsync(url);

#if WINDOWS_PORTABLE || WINDOWS_DESKTOP
            return await response.Content.ReadAsStreamAsync();
#elif WINDOWS_UAP
            return (await response.Content.ReadAsStreamAsync()).AsInputStream();
#endif
        }
 /// <summary>
 /// Get a specific episode based on its id and the given language and returns null if api response is not well formed
 /// </summary>
 /// <param name="episodeId">Id of the episode</param>
 /// <param name="language">Episode language</param>
 /// <returns>The corresponding episode or null if api response is not well formed</returns>
 public async Task<TheTvDbEpisode> GetEpisodeAsync(uint episodeId, TheTvDbLanguage language)
 {
     var episodeRaw = await _episodeServiceProxy.Retrieve(episodeId, language);
     return _episodeParser.Parse(episodeRaw);
 }
 /// <summary>
 /// Get a specific series based on its id and if compression mode is true also all banners and actors; 
 /// or null if api response is not well formed
 /// </summary>
 /// <param name="seriesId">Id of the series.</param>
 /// <param name="language">Language of the series.</param>
 /// <param name="compression">Set compression mode to false if you want to have an uncompressed transmission 
 /// which increases the bandwith load a lot. Compressed transmission also loads all banners and actors.</param>
 /// <returns>Returns the corresponding series or null if api response is not well formed</returns>
 public async Task<TheTvDbSeries> GetSeriesAsync(uint seriesId, TheTvDbLanguage language, bool compression = true)
 {
     if (compression)
     {
         var fullSeriesStream = await _seriesServiceProxy.RetrieveFull(seriesId, language);
         return await _seriesParser.ParseFull(fullSeriesStream, language);
     }
     
     var seriesRaw = await _seriesServiceProxy.Retrieve(seriesId, language);
     return _seriesParser.Parse(seriesRaw);
 }
 public TheTvDbManager(ITheTvDbCache cache, ITheTvDbClient client, TheTvDbLanguage preferredLanguage)
 {
     _cache = cache;
     _client = client;
     _preferredLanguage = preferredLanguage;
 }
 public async Task<System.IO.Stream> RetrieveFull(uint showId, TheTvDbLanguage language)
        public async Task<TheTvDbSeries> ParseFull(Windows.Storage.Streams.IInputStream fullSeriesCompressedStream, TheTvDbLanguage language)
#endif
        {
            if (fullSeriesCompressedStream == null) throw new ArgumentNullException(nameof(fullSeriesCompressedStream));

            string seriesRaw;
            string actorsRaw;
            string bannersRaw;

#if WINDOWS_PORTABLE || WINDOWS_DESKTOP
            using (var archive = new ZipArchive(fullSeriesCompressedStream, ZipArchiveMode.Read))
#elif WINDOWS_UAP
            using (var archive = new ZipArchive(fullSeriesCompressedStream.AsStreamForRead(), ZipArchiveMode.Read))
#endif
            {
                // Throw ParseException if series metadata cannot be retrieved from the compressed file.
                seriesRaw = archive.GetEntry(language.ToShortString() + ".xml").ReadToEnd();
                if (seriesRaw == null) throw new TheTvDbParseException("Compressed file does not have a series metadata file.");

                actorsRaw = archive.GetEntry("actors.xml").ReadToEnd();
                bannersRaw = archive.GetEntry("banners.xml").ReadToEnd();
            }

            // Create parse tasks if string not null
            var seriesTask = Task.Run(() => Parse(seriesRaw));
            var actorsTask = actorsRaw != null ?
                Task.Run(() => _actorParseService.Parse(actorsRaw)) :
                null;
            var bannersTask = bannersRaw != null ?
                Task.Run(() => _bannerParseService.Parse(bannersRaw)) :
                null;

            // Create tasks list to await it
            var tasks = new List<Task> { seriesTask };
            if (actorsTask != null) tasks.Add(actorsTask);
            if (bannersTask != null) tasks.Add(bannersTask);

            await Task.WhenAll(tasks);

            var series = seriesTask.Result;
            if (actorsTask != null) series.Actors = actorsTask.Result;
            if (bannersTask != null) series.Banners = bannersTask.Result;

            return series;
        }
        /// <summary>
        /// Parse complete series from an compressed stream with a given language and return null if stream or xml is not valid
        /// </summary>
        /// <param name="fullSeriesCompressedStream">Complete series zip compressed stream</param>
        /// <param name="language">Series language</param>
        /// <returns>Return the parsed complete series or null if stream or xml is not valid</returns>
#if WINDOWS_PORTABLE || WINDOWS_DESKTOP
        public async Task<TheTvDbSeries> ParseFull(System.IO.Stream fullSeriesCompressedStream, TheTvDbLanguage language)