public Task <EpisodeIdentity> FindIdentity(EpisodeInfo info)
        {
            string seriesTvdbId;

            info.SeriesProviderIds.TryGetValue(MetadataProviders.Tvdb.ToString(), out seriesTvdbId);

            if (string.IsNullOrEmpty(seriesTvdbId) || info.IndexNumber == null)
            {
                return(Task.FromResult <EpisodeIdentity>(null));
            }

            var id = new EpisodeIdentity
            {
                Type           = MetadataProviders.Tvdb.ToString(),
                SeriesId       = seriesTvdbId,
                SeasonIndex    = info.ParentIndexNumber,
                IndexNumber    = info.IndexNumber.Value,
                IndexNumberEnd = info.IndexNumberEnd
            };

            return(Task.FromResult(id));
        }
        /// <summary>
        /// Fetches the episode data.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <param name="identity">The identity.</param>
        /// <param name="seriesDataPath">The series data path.</param>
        /// <param name="seriesProviderIds">The series provider ids.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task{System.Boolean}.</returns>
        private Episode FetchEpisodeData(EpisodeInfo id, EpisodeIdentity identity, string seriesDataPath, Dictionary <string, string> seriesProviderIds, CancellationToken cancellationToken)
        {
            var episodeNumber = identity.IndexNumber;
            var seasonOffset  = TvdbSeriesProvider.GetSeriesOffset(seriesProviderIds) ?? 0;
            var seasonNumber  = identity.SeasonIndex + seasonOffset;

            string file;
            var    success           = false;
            var    usingAbsoluteData = false;

            var episode = new Episode
            {
                IndexNumber       = id.IndexNumber,
                ParentIndexNumber = id.ParentIndexNumber,
                IndexNumberEnd    = id.IndexNumberEnd
            };

            try
            {
                if (seasonNumber != null)
                {
                    file = Path.Combine(seriesDataPath, string.Format("episode-{0}-{1}.xml", seasonNumber.Value, episodeNumber));
                    FetchMainEpisodeInfo(episode, file, cancellationToken);

                    success = true;
                }
            }
            catch (FileNotFoundException)
            {
                // Could be using absolute numbering
                if (seasonNumber.HasValue && seasonNumber.Value != 1)
                {
                    throw;
                }
            }

            if (!success)
            {
                file = Path.Combine(seriesDataPath, string.Format("episode-abs-{0}.xml", episodeNumber));

                FetchMainEpisodeInfo(episode, file, cancellationToken);
                usingAbsoluteData = true;
                success           = true;
            }

            var end = identity.IndexNumberEnd ?? episodeNumber;

            episodeNumber++;

            while (episodeNumber <= end)
            {
                if (usingAbsoluteData)
                {
                    file = Path.Combine(seriesDataPath, string.Format("episode-abs-{0}.xml", episodeNumber));
                }
                else
                {
                    file = Path.Combine(seriesDataPath, string.Format("episode-{0}-{1}.xml", seasonNumber.Value, episodeNumber));
                }

                try
                {
                    FetchAdditionalPartInfo(episode, file, cancellationToken);
                }
                catch (FileNotFoundException)
                {
                    break;
                }
                catch (DirectoryNotFoundException)
                {
                    break;
                }

                episodeNumber++;
            }

            return(success ? episode : null);
        }