using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Controller.Providers { public class ItemIdentifier where TLookupInfo : ItemLookupInfo where TIdentity : IItemIdentity { public async Task> FindIdentities(TLookupInfo item, IProviderManager providerManager, CancellationToken cancellationToken) { var providers = providerManager.GetItemIdentityProviders(); var converters = providerManager.GetItemIdentityConverters(); var identities = new List(); foreach (var provider in providers) { var result = new IdentityPair { Identity = await provider.FindIdentity(item), Order = provider.Order }; if (!Equals(result.Identity, default(TIdentity))) { identities.Add(result); } } var convertersAvailable = new List>(converters); bool changesMade; do { changesMade = false; for (int i = convertersAvailable.Count - 1; i >= 0; i--) { var converter = convertersAvailable[i]; var input = identities.FirstOrDefault(id => id.Identity.Type == converter.SourceType); var existing = identities.Where(id => id.Identity.Type == converter.ResultType); if (input != null && !existing.Any(id => id.Order <= converter.Order)) { var result = new IdentityPair { Identity = await converter.Convert(input.Identity).ConfigureAwait(false), Order = converter.Order }; if (!Equals(result.Identity, default(TIdentity))) { identities.Add(result); convertersAvailable.RemoveAt(i); changesMade = true; } } } } while (changesMade); return identities.OrderBy(id => id.Order).Select(id => id.Identity); } private class IdentityPair { public TIdentity Identity; public int Order; } } }