private void FetchInfoFromBannerNode(FanartXmlData data, XmlReader reader, int seasonNumber)
        {
            reader.MoveToContent();

            string bannerType = null;
            string bannerType2 = null;
            string url = null;
            int? bannerSeason = null;

            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    switch (reader.Name)
                    {
                        case "BannerType":
                            {
                                bannerType = reader.ReadElementContentAsString() ?? string.Empty;
                                break;
                            }

                        case "BannerType2":
                            {
                                bannerType2 = reader.ReadElementContentAsString() ?? string.Empty;
                                break;
                            }

                        case "BannerPath":
                            {
                                url = reader.ReadElementContentAsString() ?? string.Empty;
                                break;
                            }

                        case "Season":
                            {
                                var val = reader.ReadElementContentAsString();

                                if (!string.IsNullOrWhiteSpace(val))
                                {
                                    bannerSeason = int.Parse(val);
                                }
                                break;
                            }


                        default:
                            reader.Skip();
                            break;
                    }
                }
            }

            if (!string.IsNullOrEmpty(url) && bannerSeason.HasValue && bannerSeason.Value == seasonNumber)
            {
                if (string.Equals(bannerType, "season", StringComparison.OrdinalIgnoreCase))
                {
                    if (string.Equals(bannerType2, "season", StringComparison.OrdinalIgnoreCase))
                    {
                        data.Poster = url;
                    }
                    else if (string.Equals(bannerType2, "seasonwide", StringComparison.OrdinalIgnoreCase))
                    {
                        data.Banner = url;
                    }
                }
                else if (string.Equals(bannerType, "fanart", StringComparison.OrdinalIgnoreCase))
                {
                    data.Backdrops.Add(url);
                }
            }
        }
        private async Task DownloadImages(BaseItem item, FanartXmlData data, int backdropLimit, CancellationToken cancellationToken)
        {
            if (!item.HasImage(ImageType.Primary))
            {
                var url = data.LanguagePoster ?? data.Poster;
                if (!string.IsNullOrEmpty(url))
                {
                    url = TVUtils.BannerUrl + url;

                    await _providerManager.SaveImage(item, url, RemoteSeriesProvider.Current.TvDbResourcePool, ImageType.Primary, null, cancellationToken)
                      .ConfigureAwait(false);
                }
            }

            if (ConfigurationManager.Configuration.DownloadSeasonImages.Banner && !item.HasImage(ImageType.Banner))
            {
                var url = data.LanguageBanner ?? data.Banner;
                if (!string.IsNullOrEmpty(url))
                {
                    url = TVUtils.BannerUrl + url;

                    await _providerManager.SaveImage(item, url, RemoteSeriesProvider.Current.TvDbResourcePool, ImageType.Banner, null, cancellationToken)
                      .ConfigureAwait(false);
                }
            }

            if (ConfigurationManager.Configuration.DownloadSeasonImages.Backdrops && item.BackdropImagePaths.Count == 0)
            {
                var bdNo = item.BackdropImagePaths.Count;

                foreach (var backdrop in data.Backdrops)
                {
                    var url = TVUtils.BannerUrl + backdrop;

                    await _providerManager.SaveImage(item, url, RemoteSeriesProvider.Current.TvDbResourcePool, ImageType.Backdrop, bdNo, cancellationToken)
                      .ConfigureAwait(false);

                    bdNo++;

                    if (item.BackdropImagePaths.Count >= backdropLimit) break;
                }
            }
        }
        private FanartXmlData FetchFanartXmlData(string bannersXmlPath, int seasonNumber, CancellationToken cancellationToken)
        {
            var settings = new XmlReaderSettings
            {
                CheckCharacters = false,
                IgnoreProcessingInstructions = true,
                IgnoreComments = true,
                ValidationType = ValidationType.None
            };

            var data = new FanartXmlData();

            using (var streamReader = new StreamReader(bannersXmlPath, Encoding.UTF8))
            {
                // Use XmlReader for best performance
                using (var reader = XmlReader.Create(streamReader, settings))
                {
                    reader.MoveToContent();

                    // Loop through each element
                    while (reader.Read())
                    {
                        cancellationToken.ThrowIfCancellationRequested();

                        if (reader.NodeType == XmlNodeType.Element)
                        {
                            switch (reader.Name)
                            {
                                case "Banner":
                                    {
                                        using (var subtree = reader.ReadSubtree())
                                        {
                                            FetchInfoFromBannerNode(data, subtree, seasonNumber);
                                        }
                                        break;
                                    }
                                default:
                                    reader.Skip();
                                    break;
                            }
                        }
                    }
                }
            }

            return data;
        }
        private void FetchInfoFromBannerNode(FanartXmlData data, XmlReader reader, int backdropLimit)
        {
            reader.MoveToContent();

            string type = null;
            string url = null;

            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    switch (reader.Name)
                    {
                        case "BannerType":
                            {
                                type = reader.ReadElementContentAsString() ?? string.Empty;

                                if (string.Equals(type, "poster", StringComparison.OrdinalIgnoreCase))
                                {
                                    // Already got it
                                    if (!string.IsNullOrEmpty(data.Poster))
                                    {
                                        return;
                                    }
                                }
                                else if (string.Equals(type, "series", StringComparison.OrdinalIgnoreCase))
                                {
                                    // Already got it
                                    if (!string.IsNullOrEmpty(data.Banner))
                                    {
                                        return;
                                    }
                                }
                                else if (string.Equals(type, "fanart", StringComparison.OrdinalIgnoreCase))
                                {
                                    if (data.Backdrops.Count >= backdropLimit)
                                    {
                                        return;
                                    }
                                }
                                else
                                {
                                    return;
                                }

                                break;
                            }

                        case "BannerPath":
                            {
                                url = reader.ReadElementContentAsString() ?? string.Empty;
                                break;
                            }

                        default:
                            reader.Skip();
                            break;
                    }
                }
            }

            if (!string.IsNullOrEmpty(url))
            {
                if (string.Equals(type, "poster", StringComparison.OrdinalIgnoreCase))
                {
                    data.Poster = url;
                }
                else if (string.Equals(type, "series", StringComparison.OrdinalIgnoreCase))
                {
                    data.Banner = url;
                }
                else if (string.Equals(type, "fanart", StringComparison.OrdinalIgnoreCase))
                {
                    data.Backdrops.Add(url);
                }
            }
        }