private Either <ProcessFailedResult, MetadataResult <TEmbyItem> > SetName(object source,
                                                                           MetadataResult <TEmbyItem> target, IPropertyMappingCollection propertyMappings,
                                                                           SourceName librarySourceName, ProcessResultContext resultContext)
 {
     return(Option <IPropertyMapping> .Some(propertyMappings.FirstOrDefault(m =>
                                                                            m.CanApply(source, target) && m.TargetPropertyName == nameof(target.Item.Name)))
            .Map(m =>
     {
         m.Apply(source, target);
         return target;
     })
            .ToEither(resultContext.Failed("No value for Name property mapped from library source")));
 }
        public Either <ProcessFailedResult, IMetadataFoundResult <TEmbyItem> > CreateMetadataFoundResult(
            IPluginConfiguration pluginConfiguration, IMediaItem mediaItem, ILogManager logManager)
        {
            var logger        = logManager.GetLogger(this.GetType().Name);
            var resultContext = new ProcessResultContext("PropertyMapping", mediaItem.EmbyData.Identifier.Name,
                                                         mediaItem.ItemType);

            var metadataResult = new MetadataResult <TEmbyItem>
            {
                Item        = new TEmbyItem(),
                HasMetadata = true
            };

            var propertyMappings = this.propertyMappingsFactory(pluginConfiguration, mediaItem.EmbyData.Language);
            var sourceData       = mediaItem.GetAllSourceData().ToList();

            var mediaItemMetadata = sourceData.Select(sd => sd.GetData <object>()).Somes();

            metadataResult = propertyMappings.Apply(mediaItemMetadata, metadataResult, s => logger.Debug(s));

            metadataResult = this.UpdateProviderIds(metadataResult, sourceData);

            var mappedMetadataResult = Option <MetadataResult <TEmbyItem> > .Some(metadataResult);

            return(mappedMetadataResult.ToEither(resultContext.Failed("Property mapping returned no data"))
                   .Bind(m => mediaItem.GetDataFromSource(pluginConfiguration.LibraryStructureSource(mediaItem.ItemType))
                         .ToEither(resultContext.Failed("No data returned by library structure source"))
                         .Bind(sd => this.SetIdentity(sd, m, propertyMappings, pluginConfiguration.LibraryStructureSource(mediaItem.ItemType).Name,
                                                      resultContext)))
                   .Match(r => string.IsNullOrWhiteSpace(r.Item.Name)
                        ? Left <ProcessFailedResult, MetadataResult <TEmbyItem> >(
                              resultContext.Failed("Property mapping failed for the Name property"))
                        : Right <ProcessFailedResult, MetadataResult <TEmbyItem> >(r),
                          failure => failure)
                   .Map(r => (IMetadataFoundResult <TEmbyItem>) new MetadataFoundResult <TEmbyItem>(mediaItem, r)));
        }