Sfoglia il codice sorgente

update active recordings

Luke Pulverenti 7 anni fa
parent
commit
e441e2f53d
100 ha cambiato i file con 501 aggiunte e 556 eliminazioni
  1. 14 4
      Emby.Dlna/ContentDirectory/ContentDirectory.cs
  2. 2 5
      Emby.Dlna/Didl/Filter.cs
  3. 0 1
      Emby.Dlna/Didl/StringWriterWithEncoding.cs
  4. 2 3
      Emby.Dlna/PlayTo/PlayToController.cs
  5. 0 101
      Emby.Dlna/Profiles/PanasonicVieraProfile.cs
  6. 5 4
      Emby.Dlna/Ssdp/Extensions.cs
  7. 3 3
      Emby.Drawing.ImageMagick/ImageHelpers.cs
  8. 3 4
      Emby.Drawing.ImageMagick/ImageMagickEncoder.cs
  9. 6 6
      Emby.Drawing.ImageMagick/StripCollageBuilder.cs
  10. 14 10
      Emby.Drawing/ImageProcessor.cs
  11. 9 1
      Emby.Server.Implementations/ApplicationHost.cs
  12. 1 1
      Emby.Server.Implementations/Channels/ChannelManager.cs
  13. 3 3
      Emby.Server.Implementations/Data/SqliteItemRepository.cs
  14. 1 1
      Emby.Server.Implementations/Dto/DtoService.cs
  15. 1 1
      Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs
  16. 11 50
      Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
  17. 2 2
      Emby.Server.Implementations/Notifications/Notifications.cs
  18. 4 4
      Emby.Server.Implementations/Services/ServiceHandler.cs
  19. 1 1
      Emby.Server.Implementations/Sorting/ArtistComparer.cs
  20. 61 30
      Emby.Server.Implementations/Updates/InstallationManager.cs
  21. 1 1
      MediaBrowser.Api/ChannelService.cs
  22. 0 1
      MediaBrowser.Api/ConfigurationService.cs
  23. 1 2
      MediaBrowser.Api/Devices/DeviceService.cs
  24. 0 1
      MediaBrowser.Api/Dlna/DlnaServerService.cs
  25. 2 2
      MediaBrowser.Api/Dlna/DlnaService.cs
  26. 1 14
      MediaBrowser.Api/Images/ImageService.cs
  27. 1 1
      MediaBrowser.Api/ItemUpdateService.cs
  28. 0 1
      MediaBrowser.Api/LocalizationService.cs
  29. 0 1
      MediaBrowser.Api/Movies/CollectionService.cs
  30. 1 1
      MediaBrowser.Api/Movies/MoviesService.cs
  31. 2 2
      MediaBrowser.Api/PlaylistService.cs
  32. 1 1
      MediaBrowser.Api/Reports/Data/ReportBuilder.cs
  33. 4 4
      MediaBrowser.Api/SearchService.cs
  34. 0 1
      MediaBrowser.Api/SuggestionsService.cs
  35. 0 1
      MediaBrowser.Api/TvShowsService.cs
  36. 1 1
      MediaBrowser.Api/UserLibrary/ArtistsService.cs
  37. 6 6
      MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
  38. 1 1
      MediaBrowser.Api/UserLibrary/GameGenresService.cs
  39. 1 1
      MediaBrowser.Api/UserLibrary/GenresService.cs
  40. 1 1
      MediaBrowser.Api/UserLibrary/MusicGenresService.cs
  41. 5 7
      MediaBrowser.Api/UserLibrary/PersonsService.cs
  42. 2 4
      MediaBrowser.Api/UserLibrary/StudiosService.cs
  43. 2 4
      MediaBrowser.Api/UserLibrary/YearsService.cs
  44. 0 1
      MediaBrowser.Api/VideosService.cs
  45. 2 2
      MediaBrowser.Common/Updates/IInstallationManager.cs
  46. 2 2
      MediaBrowser.Controller/Drawing/IImageProcessor.cs
  47. 19 12
      MediaBrowser.Controller/Entities/AggregateFolder.cs
  48. 16 6
      MediaBrowser.Controller/Entities/Audio/Audio.cs
  49. 3 13
      MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs
  50. 35 27
      MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
  51. 13 7
      MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
  52. 0 1
      MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
  53. 1 1
      MediaBrowser.Controller/Entities/BaseItem.cs
  54. 1 1
      MediaBrowser.Controller/Entities/Book.cs
  55. 13 13
      MediaBrowser.Controller/Entities/CollectionFolder.cs
  56. 0 1
      MediaBrowser.Controller/Entities/Game.cs
  57. 0 1
      MediaBrowser.Controller/Entities/GameGenre.cs
  58. 0 1
      MediaBrowser.Controller/Entities/Genre.cs
  59. 1 1
      MediaBrowser.Controller/Entities/ICollectionFolder.cs
  60. 2 2
      MediaBrowser.Controller/Entities/InternalPeopleQuery.cs
  61. 2 3
      MediaBrowser.Controller/Entities/Movies/BoxSet.cs
  62. 3 3
      MediaBrowser.Controller/Entities/MusicVideo.cs
  63. 9 1
      MediaBrowser.Controller/Entities/PeopleHelper.cs
  64. 0 1
      MediaBrowser.Controller/Entities/Person.cs
  65. 10 2
      MediaBrowser.Controller/Entities/Photo.cs
  66. 0 1
      MediaBrowser.Controller/Entities/Studio.cs
  67. 1 1
      MediaBrowser.Controller/Entities/TV/Season.cs
  68. 9 1
      MediaBrowser.Controller/Entities/TV/Series.cs
  69. 16 3
      MediaBrowser.Controller/Entities/User.cs
  70. 1 1
      MediaBrowser.Controller/Entities/UserRootFolder.cs
  71. 2 2
      MediaBrowser.Controller/Entities/UserView.cs
  72. 0 1
      MediaBrowser.Controller/Entities/Year.cs
  73. 9 2
      MediaBrowser.Controller/IO/FileData.cs
  74. 10 4
      MediaBrowser.Controller/Library/ItemResolveArgs.cs
  75. 0 44
      MediaBrowser.Controller/Library/NameExtensions.cs
  76. 0 1
      MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs
  77. 0 1
      MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
  78. 0 1
      MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs
  79. 12 4
      MediaBrowser.Controller/Providers/DirectoryService.cs
  80. 1 1
      MediaBrowser.Controller/Providers/IDirectoryService.cs
  81. 9 2
      MediaBrowser.Controller/Providers/MetadataResult.cs
  82. 2 3
      MediaBrowser.Controller/Providers/SongInfo.cs
  83. 13 2
      MediaBrowser.Controller/Session/SessionInfo.cs
  84. 35 36
      MediaBrowser.LocalMetadata/Images/EpisodeLocalImageProvider.cs
  85. 0 1
      MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs
  86. 1 1
      MediaBrowser.Model/Dto/BaseItemDto.cs
  87. 6 11
      MediaBrowser.Model/Dto/MediaSourceInfo.cs
  88. 8 3
      MediaBrowser.Model/Extensions/ListHelper.cs
  89. 50 17
      MediaBrowser.Model/Services/QueryParamCollection.cs
  90. 2 0
      MediaBrowser.Model/Updates/PackageVersionInfo.cs
  91. 2 2
      MediaBrowser.Providers/Books/AudioBookMetadataService.cs
  92. 2 2
      MediaBrowser.Providers/Books/AudioPodcastMetadataService.cs
  93. 1 5
      MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs
  94. 0 1
      MediaBrowser.Providers/Chapters/ChapterManager.cs
  95. 0 1
      MediaBrowser.Providers/Manager/GenericPriorityQueue.cs
  96. 0 1
      MediaBrowser.Providers/Manager/GenericPriorityQueueNode.cs
  97. 0 1
      MediaBrowser.Providers/Manager/IFixedSizePriorityQueue.cs
  98. 0 1
      MediaBrowser.Providers/Manager/IPriorityQueue.cs
  99. 0 1
      MediaBrowser.Providers/Manager/SimplePriorityQueue.cs
  100. 1 1
      MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs

+ 14 - 4
Emby.Dlna/ContentDirectory/ContentDirectory.cs

@@ -10,7 +10,6 @@ using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Logging;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Controller.TV;
 using MediaBrowser.Model.Globalization;
@@ -129,9 +128,20 @@ namespace Emby.Dlna.ContentDirectory
                 }
             }
 
-            // No configuration so it's going to be pretty arbitrary
-            return _userManager.Users.FirstOrDefault(i => i.Policy.IsAdministrator) ??
-                _userManager.Users.First();
+            foreach (var user in _userManager.Users)
+            {
+                if (user.Policy.IsAdministrator)
+                {
+                    return user;
+                }
+            }
+
+            foreach (var user in _userManager.Users)
+            {
+                return user;
+            }
+
+            return null;
         }
 
         public void Dispose()

+ 2 - 5
Emby.Dlna/Didl/Filter.cs

@@ -1,13 +1,12 @@
 using MediaBrowser.Model.Extensions;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 
 namespace Emby.Dlna.Didl
 {
     public class Filter
     {
-        private readonly List<string> _fields;
+        private readonly string[] _fields;
         private readonly bool _all;
 
         public Filter()
@@ -20,9 +19,7 @@ namespace Emby.Dlna.Didl
         {
             _all = StringHelper.EqualsIgnoreCase(filter, "*");
 
-            var list = (filter ?? string.Empty).Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).ToList();
-
-            _fields = list;
+            _fields = (filter ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
         }
 
         public bool Contains(string field)

+ 0 - 1
Emby.Dlna/Didl/StringWriterWithEncoding.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
-using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 

+ 2 - 3
Emby.Dlna/PlayTo/PlayToController.cs

@@ -13,7 +13,6 @@ using MediaBrowser.Model.System;
 using System;
 using System.Collections.Generic;
 using System.Globalization;
-using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 using MediaBrowser.Common.Configuration;
@@ -49,7 +48,7 @@ namespace Emby.Dlna.PlayTo
         {
             get
             {
-                var lastDateKnownActivity = new[] { _creationTime, _device.DateLastActivity }.Max();
+                var lastDateKnownActivity = _creationTime > _device.DateLastActivity ? _creationTime : _device.DateLastActivity;
 
                 if (DateTime.UtcNow >= lastDateKnownActivity.AddSeconds(120))
                 {
@@ -565,7 +564,7 @@ namespace Emby.Dlna.PlayTo
                     streamInfo.TargetVideoCodecTag,
                     streamInfo.IsTargetAVC);
 
-                return list.FirstOrDefault();
+                return list.Count == 0 ? null : list[0];
             }
 
             return null;

+ 0 - 101
Emby.Dlna/Profiles/PanasonicVieraProfile.cs

@@ -30,107 +30,6 @@ namespace Emby.Dlna.Profiles
 
             TimelineOffsetSeconds = 10;
 
-            TranscodingProfiles = new[]
-           {
-               new TranscodingProfile
-               {
-                   Container = "mp3",
-                   AudioCodec = "mp3",
-                   Type = DlnaProfileType.Audio
-               },
-               new TranscodingProfile
-               {
-                   Container = "ts",
-                   AudioCodec = "ac3",
-                   VideoCodec = "h264",
-                   Type = DlnaProfileType.Video
-               },
-               new TranscodingProfile
-               {
-                   Container = "jpeg",
-                   Type = DlnaProfileType.Photo
-               }
-           };
-
-            DirectPlayProfiles = new[]
-           {
-               new DirectPlayProfile
-               {
-                   Container = "mpeg,mpg",
-                   VideoCodec = "mpeg2video,mpeg4",
-                   AudioCodec = "ac3,mp3,pcm_dvd",
-                   Type = DlnaProfileType.Video
-               },
-
-               new DirectPlayProfile
-               {
-                   Container = "mkv",
-                   VideoCodec = "h264,mpeg2video",
-                   AudioCodec = "aac,ac3,dca,mp3,mp2,pcm,dts",
-                   Type = DlnaProfileType.Video
-               },
-
-               new DirectPlayProfile
-               {
-                   Container = "ts",
-                   VideoCodec = "h264,mpeg2video",
-                   AudioCodec = "aac,mp3,mp2",
-                   Type = DlnaProfileType.Video
-               },
-
-               new DirectPlayProfile
-               {
-                   Container = "mp4,m4v",
-                   VideoCodec = "h264",
-                   AudioCodec = "aac,ac3,mp3,pcm",
-                   Type = DlnaProfileType.Video
-               },
-
-               new DirectPlayProfile
-               {
-                   Container = "mov",
-                   VideoCodec = "h264",
-                   AudioCodec = "aac,pcm",
-                   Type = DlnaProfileType.Video
-               },
-
-               new DirectPlayProfile
-               {
-                   Container = "avi",
-                   VideoCodec = "mpeg4",
-                   AudioCodec = "pcm",
-                   Type = DlnaProfileType.Video
-               },
-
-               new DirectPlayProfile
-               {
-                   Container = "flv",
-                   VideoCodec = "h264",
-                   AudioCodec = "aac",
-                   Type = DlnaProfileType.Video
-               },
-
-               new DirectPlayProfile
-               {
-                   Container = "mp3",
-                   AudioCodec = "mp3",
-                   Type = DlnaProfileType.Audio
-               },
-
-               new DirectPlayProfile
-               {
-                   Container = "mp4",
-                   AudioCodec = "aac",
-                   Type = DlnaProfileType.Audio
-               },
-
-               new DirectPlayProfile
-               {
-                   Container = "jpeg",
-                   Type = DlnaProfileType.Photo
-               }
-           };
-
             ContainerProfiles = new[]
             {
                 new ContainerProfile

+ 5 - 4
Emby.Dlna/Ssdp/Extensions.cs

@@ -1,5 +1,4 @@
 using System;
-using System.Linq;
 using System.Net;
 using System.Threading.Tasks;
 using System.Xml.Linq;
@@ -24,10 +23,12 @@ namespace Emby.Dlna.Ssdp
 
         public static string GetDescendantValue(this XElement container, XName name)
         {
-            var node = container.Descendants(name)
-                .FirstOrDefault();
+            foreach (var node in container.Descendants(name))
+            {
+                return node.Value;
+            }
 
-            return node == null ? null : node.Value;
+            return null;
         }
     }
 }

+ 3 - 3
Emby.Drawing.ImageMagick/ImageHelpers.cs

@@ -6,13 +6,13 @@ namespace Emby.Drawing.ImageMagick
 {
     internal static class ImageHelpers
     {
-        internal static List<string> ProjectPaths(List<string> paths, int count)
+        internal static List<string> ProjectPaths(string[] paths, int count)
         {
             if (count <= 0)
             {
                 throw new ArgumentOutOfRangeException("count");
             }
-            if (paths.Count == 0)
+            if (paths.Length == 0)
             {
                 throw new ArgumentOutOfRangeException("paths");
             }
@@ -24,7 +24,7 @@ namespace Emby.Drawing.ImageMagick
             return list.Take(count).ToList();
         }
 
-        private static void AddToList(List<string> list, List<string> paths, int count)
+        private static void AddToList(List<string> list, string[] paths, int count)
         {
             while (list.Count < count)
             {

+ 3 - 4
Emby.Drawing.ImageMagick/ImageMagickEncoder.cs

@@ -7,7 +7,6 @@ using MediaBrowser.Model.Drawing;
 using MediaBrowser.Model.Logging;
 using System;
 using System.IO;
-using System.Linq;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.System;
 
@@ -306,15 +305,15 @@ namespace Emby.Drawing.ImageMagick
 
             if (ratio >= 1.4)
             {
-                new StripCollageBuilder(_appPaths, _fileSystem).BuildThumbCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height);
+                new StripCollageBuilder(_appPaths, _fileSystem).BuildThumbCollage(options.InputPaths, options.OutputPath, options.Width, options.Height);
             }
             else if (ratio >= .9)
             {
-                new StripCollageBuilder(_appPaths, _fileSystem).BuildSquareCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height);
+                new StripCollageBuilder(_appPaths, _fileSystem).BuildSquareCollage(options.InputPaths, options.OutputPath, options.Width, options.Height);
             }
             else
             {
-                new StripCollageBuilder(_appPaths, _fileSystem).BuildPosterCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height);
+                new StripCollageBuilder(_appPaths, _fileSystem).BuildPosterCollage(options.InputPaths, options.OutputPath, options.Width, options.Height);
             }
         }
 

+ 6 - 6
Emby.Drawing.ImageMagick/StripCollageBuilder.cs

@@ -19,7 +19,7 @@ namespace Emby.Drawing.ImageMagick
             _fileSystem = fileSystem;
         }
 
-        public void BuildPosterCollage(List<string> paths, string outputPath, int width, int height)
+        public void BuildPosterCollage(string[] paths, string outputPath, int width, int height)
         {
             using (var wand = BuildPosterCollageWand(paths, width, height))
             {
@@ -27,7 +27,7 @@ namespace Emby.Drawing.ImageMagick
             }
         }
 
-        public void BuildSquareCollage(List<string> paths, string outputPath, int width, int height)
+        public void BuildSquareCollage(string[] paths, string outputPath, int width, int height)
         {
             using (var wand = BuildSquareCollageWand(paths, width, height))
             {
@@ -35,7 +35,7 @@ namespace Emby.Drawing.ImageMagick
             }
         }
 
-        public void BuildThumbCollage(List<string> paths, string outputPath, int width, int height)
+        public void BuildThumbCollage(string[] paths, string outputPath, int width, int height)
         {
             using (var wand = BuildThumbCollageWand(paths, width, height))
             {
@@ -43,7 +43,7 @@ namespace Emby.Drawing.ImageMagick
             }
         }
 
-        private MagickWand BuildPosterCollageWand(List<string> paths, int width, int height)
+        private MagickWand BuildPosterCollageWand(string[] paths, int width, int height)
         {
             var inputPaths = ImageHelpers.ProjectPaths(paths, 3);
             using (var wandImages = new MagickWand(inputPaths.ToArray()))
@@ -108,7 +108,7 @@ namespace Emby.Drawing.ImageMagick
             }
         }
 
-        private MagickWand BuildThumbCollageWand(List<string> paths, int width, int height)
+        private MagickWand BuildThumbCollageWand(string[] paths, int width, int height)
         {
             var inputPaths = ImageHelpers.ProjectPaths(paths, 4);
             using (var wandImages = new MagickWand(inputPaths.ToArray()))
@@ -173,7 +173,7 @@ namespace Emby.Drawing.ImageMagick
             }
         }
 
-        private MagickWand BuildSquareCollageWand(List<string> paths, int width, int height)
+        private MagickWand BuildSquareCollageWand(string[] paths, int width, int height)
         {
             var inputPaths = ImageHelpers.ProjectPaths(paths, 4);
             var outputWand = new MagickWand(width, height, new PixelWand("none", 1));

+ 14 - 10
Emby.Drawing/ImageProcessor.cs

@@ -44,7 +44,7 @@ namespace Emby.Drawing
         /// Image processors are specialized metadata providers that run after the normal ones
         /// </summary>
         /// <value>The image enhancers.</value>
-        public IEnumerable<IImageEnhancer> ImageEnhancers { get; private set; }
+        public IImageEnhancer[] ImageEnhancers { get; private set; }
 
         /// <summary>
         /// The _logger
@@ -71,7 +71,7 @@ namespace Emby.Drawing
             _libraryManager = libraryManager;
             _appPaths = appPaths;
 
-            ImageEnhancers = new List<IImageEnhancer>();
+            ImageEnhancers = new IImageEnhancer[] {};
             _saveImageSizeTimer = timerFactory.Create(SaveImageSizeCallback, null, Timeout.Infinite, Timeout.Infinite);
             ImageHelper.ImageProcessor = this;
 
@@ -618,7 +618,7 @@ namespace Emby.Drawing
 
             var supportedEnhancers = GetSupportedEnhancers(item, image.Type);
 
-            return GetImageCacheTag(item, image, supportedEnhancers.ToList());
+            return GetImageCacheTag(item, image, supportedEnhancers);
         }
 
         /// <summary>
@@ -672,7 +672,7 @@ namespace Emby.Drawing
         /// <returns>Task{System.String}.</returns>
         public async Task<string> GetEnhancedImage(IHasMetadata item, ImageType imageType, int imageIndex)
         {
-            var enhancers = GetSupportedEnhancers(item, imageType).ToList();
+            var enhancers = GetSupportedEnhancers(item, imageType);
 
             var imageInfo = item.GetImageInfo(imageType, imageIndex);
 
@@ -866,21 +866,25 @@ namespace Emby.Drawing
             _logger.Info("Completed creation of image collage and saved to {0}", options.OutputPath);
         }
 
-        public IEnumerable<IImageEnhancer> GetSupportedEnhancers(IHasMetadata item, ImageType imageType)
+        public List<IImageEnhancer> GetSupportedEnhancers(IHasMetadata item, ImageType imageType)
         {
-            return ImageEnhancers.Where(i =>
+            var list = new List<IImageEnhancer>();
+
+            foreach (var i in ImageEnhancers)
             {
                 try
                 {
-                    return i.Supports(item, imageType);
+                    if (i.Supports(item, imageType))
+                    {
+                        list.Add(i);
+                    }
                 }
                 catch (Exception ex)
                 {
                     _logger.ErrorException("Error in image enhancer: {0}", ex, i.GetType().Name);
-
-                    return false;
                 }
-            });
+            }
+            return list;
         }
 
         private bool _disposed;

+ 9 - 1
Emby.Server.Implementations/ApplicationHost.cs

@@ -861,7 +861,7 @@ namespace Emby.Server.Implementations
             SecurityManager = new PluginSecurityManager(this, HttpClient, JsonSerializer, ApplicationPaths, LogManager, FileSystemManager, CryptographyProvider);
             RegisterSingleInstance(SecurityManager);
 
-            InstallationManager = new InstallationManager(LogManager.GetLogger("InstallationManager"), this, ApplicationPaths, HttpClient, JsonSerializer, SecurityManager, ConfigurationManager, FileSystemManager, CryptographyProvider);
+            InstallationManager = new InstallationManager(LogManager.GetLogger("InstallationManager"), this, ApplicationPaths, HttpClient, JsonSerializer, SecurityManager, ConfigurationManager, FileSystemManager, CryptographyProvider, PackageRuntime);
             RegisterSingleInstance(InstallationManager);
 
             ZipClient = new ZipClient(FileSystemManager);
@@ -1048,6 +1048,14 @@ namespace Emby.Server.Implementations
             await ((UserManager)UserManager).Initialize().ConfigureAwait(false);
         }
 
+        protected virtual string PackageRuntime
+        {
+            get
+            {
+                return "netframework";
+            }
+        }
+
         public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths, bool isStartup)
         {
             logger.LogMultiline("Emby", LogSeverity.Info, GetBaseExceptionMessage(appPaths));

+ 1 - 1
Emby.Server.Implementations/Channels/ChannelManager.cs

@@ -1330,7 +1330,7 @@ namespace Emby.Server.Implementations.Channels
             var hasArtists = item as IHasArtist;
             if (hasArtists != null)
             {
-                hasArtists.Artists = info.Artists;
+                hasArtists.Artists = info.Artists.ToArray();
             }
 
             var hasAlbumArtists = item as IHasAlbumArtist;

+ 3 - 3
Emby.Server.Implementations/Data/SqliteItemRepository.cs

@@ -1028,9 +1028,9 @@ namespace Emby.Server.Implementations.Data
             var hasArtists = item as IHasArtist;
             if (hasArtists != null)
             {
-                if (hasArtists.Artists.Count > 0)
+                if (hasArtists.Artists.Length > 0)
                 {
-                    artists = string.Join("|", hasArtists.Artists.ToArray());
+                    artists = string.Join("|", hasArtists.Artists);
                 }
             }
             saveItemStatement.TryBind("@Artists", artists);
@@ -1908,7 +1908,7 @@ namespace Emby.Server.Implementations.Data
                 var hasArtists = item as IHasArtist;
                 if (hasArtists != null && !reader.IsDBNull(index))
                 {
-                    hasArtists.Artists = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
+                    hasArtists.Artists = reader.GetString(index).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                 }
                 index++;
 

+ 1 - 1
Emby.Server.Implementations/Dto/DtoService.cs

@@ -1617,7 +1617,7 @@ namespace Emby.Server.Implementations.Dto
                 return null;
             }
 
-            var supportedEnhancers = _imageProcessor.GetSupportedEnhancers(item, ImageType.Primary).ToList();
+            var supportedEnhancers = _imageProcessor.GetSupportedEnhancers(item, ImageType.Primary);
 
             ImageSize size;
 

+ 1 - 1
Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs

@@ -53,7 +53,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
                     return new CollectionFolder
                     {
                         CollectionType = GetCollectionType(args),
-                        PhysicalLocationsList = args.PhysicalLocations.ToList()
+                        PhysicalLocationsList = args.PhysicalLocations
                     };
                 }
             }

+ 11 - 50
Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs

@@ -607,20 +607,22 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             var timer = _timerProvider.GetTimer(timerId);
             if (timer != null)
             {
+                timer.Status = RecordingStatus.Cancelled;
+
                 if (string.IsNullOrWhiteSpace(timer.SeriesTimerId) || isSeriesCancelled)
                 {
                     _timerProvider.Delete(timer);
                 }
                 else
                 {
-                    timer.Status = RecordingStatus.Cancelled;
                     _timerProvider.AddOrUpdate(timer, false);
                 }
             }
             ActiveRecordingInfo activeRecordingInfo;
 
             if (_activeRecordings.TryGetValue(timerId, out activeRecordingInfo))
-            {
+            { 
+                activeRecordingInfo.Timer = timer;
                 activeRecordingInfo.CancellationTokenSource.Cancel();
             }
         }
@@ -865,7 +867,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
         public async Task<IEnumerable<RecordingInfo>> GetRecordingsAsync(CancellationToken cancellationToken)
         {
             return new List<RecordingInfo>();
-            //return _activeRecordings.Values.ToList().Select(GetRecordingInfo).ToList();
         }
 
         public string GetActiveRecordingPath(string id)
@@ -881,7 +882,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 
         public IEnumerable<ActiveRecordingInfo> GetAllActiveRecordings()
         {
-            return _activeRecordings.Values;
+            return _activeRecordings.Values.Where(i => i.Timer.Status == RecordingStatus.InProgress && !i.CancellationTokenSource.IsCancellationRequested);
         }
 
         public ActiveRecordingInfo GetActiveRecordingInfo(string path)
@@ -893,59 +894,19 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 
             foreach (var recording in _activeRecordings.Values)
             {
-                if (string.Equals(recording.Path, path, StringComparison.Ordinal))
+                if (string.Equals(recording.Path, path, StringComparison.Ordinal) && !recording.CancellationTokenSource.IsCancellationRequested)
                 {
+                    var timer = recording.Timer;
+                    if (timer.Status != RecordingStatus.InProgress)
+                    {
+                        return null;
+                    }
                     return recording;
                 }
             }
             return null;
         }
 
-        private RecordingInfo GetRecordingInfo(ActiveRecordingInfo info)
-        {
-            var timer = info.Timer;
-            var program = info.Program;
-
-            var result = new RecordingInfo
-            {
-                ChannelId = timer.ChannelId,
-                CommunityRating = timer.CommunityRating,
-                DateLastUpdated = DateTime.UtcNow,
-                EndDate = timer.EndDate,
-                EpisodeTitle = timer.EpisodeTitle,
-                Genres = timer.Genres,
-                Id = "recording" + timer.Id,
-                IsKids = timer.IsKids,
-                IsMovie = timer.IsMovie,
-                IsNews = timer.IsNews,
-                IsRepeat = timer.IsRepeat,
-                IsSeries = timer.IsProgramSeries,
-                IsSports = timer.IsSports,
-                Name = timer.Name,
-                OfficialRating = timer.OfficialRating,
-                OriginalAirDate = timer.OriginalAirDate,
-                Overview = timer.Overview,
-                ProgramId = timer.ProgramId,
-                SeriesTimerId = timer.SeriesTimerId,
-                StartDate = timer.StartDate,
-                Status = RecordingStatus.InProgress,
-                TimerId = timer.Id
-            };
-
-            if (program != null)
-            {
-                result.Audio = program.Audio;
-                result.ImagePath = program.ImagePath;
-                result.ImageUrl = program.ImageUrl;
-                result.IsHD = program.IsHD;
-                result.IsLive = program.IsLive;
-                result.IsPremiere = program.IsPremiere;
-                result.ShowId = program.ShowId;
-            }
-
-            return result;
-        }
-
         public Task<IEnumerable<TimerInfo>> GetTimersAsync(CancellationToken cancellationToken)
         {
             var excludeStatues = new List<RecordingStatus>

+ 2 - 2
Emby.Server.Implementations/Notifications/Notifications.cs

@@ -422,7 +422,7 @@ namespace Emby.Server.Implementations.Notifications
             {
                 var artists = hasArtist.AllArtists;
 
-                if (artists.Count > 0)
+                if (artists.Length > 0)
                 {
                     name = hasArtist.AllArtists[0] + " - " + name;
                 }
@@ -440,7 +440,7 @@ namespace Emby.Server.Implementations.Notifications
                 name = item.SeriesName + " - " + name;
             }
 
-            if (item.Artists != null && item.Artists.Count > 0)
+            if (item.Artists != null && item.Artists.Length > 0)
             {
                 name = item.Artists[0] + " - " + name;
             }

+ 4 - 4
Emby.Server.Implementations/Services/ServiceHandler.cs

@@ -215,13 +215,13 @@ namespace Emby.Server.Implementations.Services
                 if (name == null) continue; //thank you ASP.NET
 
                 var values = request.QueryString.GetValues(name);
-                if (values.Length == 1)
+                if (values.Count == 1)
                 {
                     map[name] = values[0];
                 }
                 else
                 {
-                    for (var i = 0; i < values.Length; i++)
+                    for (var i = 0; i < values.Count; i++)
                     {
                         map[name + (i == 0 ? "" : "#" + i)] = values[i];
                     }
@@ -235,13 +235,13 @@ namespace Emby.Server.Implementations.Services
                     if (name == null) continue; //thank you ASP.NET
 
                     var values = request.FormData.GetValues(name);
-                    if (values.Length == 1)
+                    if (values.Count == 1)
                     {
                         map[name] = values[0];
                     }
                     else
                     {
-                        for (var i = 0; i < values.Length; i++)
+                        for (var i = 0; i < values.Count; i++)
                         {
                             map[name + (i == 0 ? "" : "#" + i)] = values[i];
                         }

+ 1 - 1
Emby.Server.Implementations/Sorting/ArtistComparer.cs

@@ -36,7 +36,7 @@ namespace Emby.Server.Implementations.Sorting
                 return string.Empty;
             }
 
-            return audio.Artists.Count == 0 ? null : audio.Artists[0];
+            return audio.Artists.Length == 0 ? null : audio.Artists[0];
         }
 
         /// <summary>

+ 61 - 30
Emby.Server.Implementations/Updates/InstallationManager.cs

@@ -122,7 +122,10 @@ namespace Emby.Server.Implementations.Updates
 
         private readonly ICryptoProvider _cryptographyProvider;
 
-        public InstallationManager(ILogger logger, IApplicationHost appHost, IApplicationPaths appPaths, IHttpClient httpClient, IJsonSerializer jsonSerializer, ISecurityManager securityManager, IConfigurationManager config, IFileSystem fileSystem, ICryptoProvider cryptographyProvider)
+        // netframework or netcore
+        private readonly string _packageRuntime;
+
+        public InstallationManager(ILogger logger, IApplicationHost appHost, IApplicationPaths appPaths, IHttpClient httpClient, IJsonSerializer jsonSerializer, ISecurityManager securityManager, IConfigurationManager config, IFileSystem fileSystem, ICryptoProvider cryptographyProvider, string packageRuntime)
         {
             if (logger == null)
             {
@@ -140,6 +143,7 @@ namespace Emby.Server.Implementations.Updates
             _config = config;
             _fileSystem = fileSystem;
             _cryptographyProvider = cryptographyProvider;
+            _packageRuntime = packageRuntime;
             _logger = logger;
         }
 
@@ -157,7 +161,7 @@ namespace Emby.Server.Implementations.Updates
         /// Gets all available packages.
         /// </summary>
         /// <returns>Task{List{PackageInfo}}.</returns>
-        public async Task<PackageInfo[]> GetAvailablePackages(CancellationToken cancellationToken,
+        public async Task<List<PackageInfo>> GetAvailablePackages(CancellationToken cancellationToken,
             bool withRegistration = true,
             string packageType = null,
             Version applicationVersion = null)
@@ -171,7 +175,7 @@ namespace Emby.Server.Implementations.Updates
                     { "systemid", _applicationHost.SystemId }
                 };
 
-                using (var json = await _httpClient.Post("https://www.mb3admin.com/admin/service/package/retrieveall", data, cancellationToken).ConfigureAwait(false))
+                using (var json = await _httpClient.Post("https://www.mb3admin.com/admin/service/package/retrieveall?includeAllRuntimes=true", data, cancellationToken).ConfigureAwait(false))
                 {
                     cancellationToken.ThrowIfCancellationRequested();
 
@@ -195,7 +199,7 @@ namespace Emby.Server.Implementations.Updates
         /// </summary>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task{List{PackageInfo}}.</returns>
-        public async Task<PackageInfo[]> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken)
+        public async Task<List<PackageInfo>> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken)
         {
             _logger.Info("Opening {0}", PackageCachePath);
             try
@@ -209,7 +213,7 @@ namespace Emby.Server.Implementations.Updates
                         UpdateCachedPackages(CancellationToken.None, false);
                     }
 
-                    return packages;
+                    return FilterPackages(packages);
                 }
             }
             catch (Exception)
@@ -221,7 +225,7 @@ namespace Emby.Server.Implementations.Updates
             await UpdateCachedPackages(cancellationToken, true).ConfigureAwait(false);
             using (var stream = _fileSystem.OpenRead(PackageCachePath))
             {
-                return _jsonSerializer.DeserializeFromStream<PackageInfo[]>(stream);
+                return FilterPackages(_jsonSerializer.DeserializeFromStream<PackageInfo[]>(stream));
             }
         }
 
@@ -244,7 +248,7 @@ namespace Emby.Server.Implementations.Updates
 
                 var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions
                 {
-                    Url = "https://www.mb3admin.com/admin/service/MB3Packages.json",
+                    Url = "https://www.mb3admin.com/admin/service/EmbyPackages.json",
                     CancellationToken = cancellationToken,
                     Progress = new SimpleProgress<Double>()
 
@@ -280,47 +284,74 @@ namespace Emby.Server.Implementations.Updates
             return TimeSpan.FromMinutes(3);
         }
 
-        protected PackageInfo[] FilterPackages(List<PackageInfo> packages)
+        protected List<PackageInfo> FilterPackages(IEnumerable<PackageInfo> packages)
         {
+            var list = new List<PackageInfo>();
 
             foreach (var package in packages)
             {
-                package.versions = package.versions.Where(v => !string.IsNullOrWhiteSpace(v.sourceUrl))
-                    .OrderByDescending(GetPackageVersion).ToArray();
+                var versions = new List<PackageVersionInfo>();
+                foreach (var version in package.versions)
+                {
+                    if (string.IsNullOrWhiteSpace(version.sourceUrl))
+                    {
+                        continue;
+                    }
+
+                    if (string.IsNullOrWhiteSpace(version.runtimes) || version.runtimes.IndexOf(_packageRuntime, StringComparison.OrdinalIgnoreCase) == -1)
+                    {
+                        continue;
+                    }
+
+                    versions.Add(version);
+                }
+
+                package.versions = versions
+                    .OrderByDescending(GetPackageVersion)
+                    .ToArray();
+
+                if (package.versions.Length == 0)
+                {
+                    continue;
+                }
+
+                list.Add(package);
             }
 
             // Remove packages with no versions
-            return packages.Where(p => p.versions.Any()).ToArray();
+            return list;
         }
 
-        protected PackageInfo[] FilterPackages(PackageInfo[] packages, string packageType, Version applicationVersion)
+        protected List<PackageInfo> FilterPackages(IEnumerable<PackageInfo> packages, string packageType, Version applicationVersion)
         {
-            foreach (var package in packages)
-            {
-                package.versions = package.versions.Where(v => !string.IsNullOrWhiteSpace(v.sourceUrl))
-                    .OrderByDescending(GetPackageVersion).ToArray();
-            }
+            var packagesList = FilterPackages(packages);
 
-            IEnumerable<PackageInfo> packagesList = packages;
+            var returnList = new List<PackageInfo>();
 
-            if (!string.IsNullOrWhiteSpace(packageType))
-            {
-                packagesList = packagesList.Where(p => string.Equals(p.type, packageType, StringComparison.OrdinalIgnoreCase));
-            }
+            var filterOnPackageType = !string.IsNullOrWhiteSpace(packageType);
 
-            // If an app version was supplied, filter the versions for each package to only include supported versions
-            if (applicationVersion != null)
+            foreach (var p in packagesList)
             {
-                foreach (var package in packages)
+                if (filterOnPackageType && !string.Equals(p.type, packageType, StringComparison.OrdinalIgnoreCase))
                 {
-                    package.versions = package.versions.Where(v => IsPackageVersionUpToDate(v, applicationVersion)).ToArray();
+                    continue;
                 }
-            }
 
-            // Remove packages with no versions
-            packagesList = packagesList.Where(p => p.versions.Any());
+                // If an app version was supplied, filter the versions for each package to only include supported versions
+                if (applicationVersion != null)
+                {
+                    p.versions = p.versions.Where(v => IsPackageVersionUpToDate(v, applicationVersion)).ToArray();
+                }
+
+                if (p.versions.Length == 0)
+                {
+                    continue;
+                }
+
+                returnList.Add(p);
+            }
 
-            return packagesList.ToArray();
+            return returnList;
         }
 
         /// <summary>

+ 1 - 1
MediaBrowser.Api/ChannelService.cs

@@ -231,7 +231,7 @@ namespace MediaBrowser.Api
                 SortOrder = request.SortOrder,
                 SortBy = (request.SortBy ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToArray(),
                 Filters = request.GetFilters().ToArray(),
-                Fields = request.GetItemFields().ToArray()
+                Fields = request.GetItemFields()
 
             }, CancellationToken.None).ConfigureAwait(false);
 

+ 0 - 1
MediaBrowser.Api/ConfigurationService.cs

@@ -6,7 +6,6 @@ using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Serialization;
 using System.Collections.Generic;
 using System.IO;
-using System.Linq;
 using System.Threading.Tasks;
 
 using MediaBrowser.Controller.IO;

+ 1 - 2
MediaBrowser.Api/Devices/DeviceService.cs

@@ -1,5 +1,4 @@
 using System;
-using System.Linq;
 using MediaBrowser.Controller.Devices;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Devices;
@@ -143,7 +142,7 @@ namespace MediaBrowser.Api.Devices
             }
             else
             {
-                var file = Request.Files.First();
+                var file = Request.Files.Length == 0 ? null : Request.Files[0];
 
                 var task = _deviceManager.AcceptCameraUpload(deviceId, file.InputStream, new LocalFileInfo
                 {

+ 0 - 1
MediaBrowser.Api/Dlna/DlnaServerService.cs

@@ -3,7 +3,6 @@ using System;
 using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
-using System.Linq;
 using System.Threading.Tasks;
 
 using MediaBrowser.Controller.IO;

+ 2 - 2
MediaBrowser.Api/Dlna/DlnaService.cs

@@ -1,7 +1,7 @@
-using MediaBrowser.Controller.Dlna;
+using System.Linq;
+using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Dlna;
-using System.Linq;
 using MediaBrowser.Model.Services;
 
 namespace MediaBrowser.Api.Dlna

+ 1 - 14
MediaBrowser.Api/Images/ImageService.cs

@@ -556,20 +556,7 @@ namespace MediaBrowser.Api.Images
                 throw new ResourceNotFoundException(string.Format("{0} does not have an image of type {1}", item.Name, request.Type));
             }
 
-            var supportedImageEnhancers = request.EnableImageEnhancers ? _imageProcessor.ImageEnhancers.Where(i =>
-            {
-                try
-                {
-                    return i.Supports(item, request.Type);
-                }
-                catch (Exception ex)
-                {
-                    Logger.ErrorException("Error in image enhancer: {0}", ex, i.GetType().Name);
-
-                    return false;
-                }
-
-            }).ToList() : new List<IImageEnhancer>();
+            var supportedImageEnhancers = request.EnableImageEnhancers ? _imageProcessor.GetSupportedEnhancers(item, request.Type) : new List<IImageEnhancer>();
 
             var cropwhitespace = request.Type == ImageType.Logo || 
                 request.Type == ImageType.Art

+ 1 - 1
MediaBrowser.Api/ItemUpdateService.cs

@@ -352,7 +352,7 @@ namespace MediaBrowser.Api
                     hasArtists.Artists = request
                         .ArtistItems
                         .Select(i => i.Name)
-                        .ToList();
+                        .ToArray();
                 }
             }
 

+ 0 - 1
MediaBrowser.Api/LocalizationService.cs

@@ -2,7 +2,6 @@
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Globalization;
 using System.Collections.Generic;
-using System.Linq;
 using MediaBrowser.Model.Services;
 
 namespace MediaBrowser.Api

+ 0 - 1
MediaBrowser.Api/Movies/CollectionService.cs

@@ -4,7 +4,6 @@ using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Collections;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using System.Threading.Tasks;
 using MediaBrowser.Model.Services;
 

+ 1 - 1
MediaBrowser.Api/Movies/MoviesService.cs

@@ -426,7 +426,7 @@ namespace MediaBrowser.Api.Movies
         {
             var people = _libraryManager.GetPeople(new InternalPeopleQuery
             {
-                PersonTypes = new List<string>
+                PersonTypes = new string[]
                 {
                     PersonType.Director
                 }

+ 2 - 2
MediaBrowser.Api/PlaylistService.cs

@@ -1,11 +1,11 @@
-using MediaBrowser.Controller.Dto;
+using System.Linq;
+using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Playlists;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Playlists;
 using MediaBrowser.Model.Querying;
-using System.Linq;
 using System.Threading.Tasks;
 using MediaBrowser.Model.Services;
 using MediaBrowser.Model.Extensions;

+ 1 - 1
MediaBrowser.Api/Reports/Data/ReportBuilder.cs

@@ -533,7 +533,7 @@ namespace MediaBrowser.Api.Reports
                     break;
 
                 case HeaderMetadata.Tracks:
-                    option.Column = (i, r) => this.GetObject<MusicAlbum, List<Audio>>(i, (x) => x.Tracks.ToList(), new List<Audio>()).Count();
+                    option.Column = (i, r) => this.GetObject<MusicAlbum, List<Audio>>(i, (x) => x.Tracks.Cast<Audio>().ToList(), new List<Audio>()).Count();
                     break;
 
                 case HeaderMetadata.Audio:

+ 4 - 4
MediaBrowser.Api/SearchService.cs

@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Drawing;
+using System.Linq;
+using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Audio;
@@ -7,7 +8,6 @@ using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Search;
-using System.Linq;
 using System.Threading.Tasks;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Model.Services;
@@ -240,7 +240,7 @@ namespace MediaBrowser.Api
 
             if (album != null)
             {
-                result.Artists = album.Artists.ToArray();
+                result.Artists = album.Artists;
                 result.AlbumArtist = album.AlbumArtist;
             }
 
@@ -250,7 +250,7 @@ namespace MediaBrowser.Api
             {
                 result.Album = song.Album;
                 result.AlbumArtist = song.AlbumArtists.FirstOrDefault();
-                result.Artists = song.Artists.ToArray();
+                result.Artists = song.Artists;
             }
 
             if (!string.IsNullOrWhiteSpace(item.ChannelId))

+ 0 - 1
MediaBrowser.Api/SuggestionsService.cs

@@ -5,7 +5,6 @@ using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Querying;
 using MediaBrowser.Model.Services;
 using System;
-using System.Linq;
 using System.Threading.Tasks;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Extensions;

+ 0 - 1
MediaBrowser.Api/TvShowsService.cs

@@ -14,7 +14,6 @@ using System.Linq;
 using System.Threading.Tasks;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Services;
-using MediaBrowser.Model.Extensions;
 
 namespace MediaBrowser.Api
 {

+ 1 - 1
MediaBrowser.Api/UserLibrary/ArtistsService.cs

@@ -132,7 +132,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         /// <param name="items">The items.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
+        protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IList<BaseItem> items)
         {
             throw new NotImplementedException();
         }

+ 6 - 6
MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs

@@ -257,7 +257,7 @@ namespace MediaBrowser.Api.UserLibrary
                 parentItem = string.IsNullOrEmpty(request.ParentId) ? LibraryManager.RootFolder : LibraryManager.GetItemById(request.ParentId);
             }
 
-            IEnumerable<BaseItem> items;
+            IList<BaseItem> items;
 
             var excludeItemTypes = request.GetExcludeItemTypes();
             var includeItemTypes = request.GetIncludeItemTypes();
@@ -280,19 +280,19 @@ namespace MediaBrowser.Api.UserLibrary
                 if (!string.IsNullOrWhiteSpace(request.UserId))
                 {
                     items = request.Recursive ?
-                        folder.GetRecursiveChildren(user, query) :
-                        folder.GetChildren(user, true).Where(filter);
+                        folder.GetRecursiveChildren(user, query).ToList() :
+                        folder.GetChildren(user, true).Where(filter).ToList();
                 }
                 else
                 {
                     items = request.Recursive ?
                         folder.GetRecursiveChildren(filter) :
-                        folder.Children.Where(filter);
+                        folder.Children.Where(filter).ToList();
                 }
             }
             else
             {
-                items = new[] { parentItem }.Where(filter);
+                items = new[] { parentItem }.Where(filter).ToList();
             }
 
             var extractedItems = GetAllItems(request, items);
@@ -500,7 +500,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         /// <param name="items">The items.</param>
         /// <returns>IEnumerable{Task{`0}}.</returns>
-        protected abstract IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items);
+        protected abstract IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IList<BaseItem> items);
     }
 
     /// <summary>

+ 1 - 1
MediaBrowser.Api/UserLibrary/GameGenresService.cs

@@ -93,7 +93,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         /// <param name="items">The items.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
+        protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IList<BaseItem> items)
         {
             throw new NotImplementedException();
         }

+ 1 - 1
MediaBrowser.Api/UserLibrary/GenresService.cs

@@ -115,7 +115,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         /// <param name="items">The items.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
+        protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IList<BaseItem> items)
         {
             throw new NotImplementedException();
         }

+ 1 - 1
MediaBrowser.Api/UserLibrary/MusicGenresService.cs

@@ -94,7 +94,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         /// <param name="items">The items.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
+        protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IList<BaseItem> items)
         {
             throw new NotImplementedException();
         }

+ 5 - 7
MediaBrowser.Api/UserLibrary/PersonsService.cs

@@ -96,15 +96,13 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         /// <param name="items">The items.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
+        protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IList<BaseItem> items)
         {
             var inputPersonTypes = ((GetPersons)request).PersonTypes;
             var personTypes = string.IsNullOrEmpty(inputPersonTypes) ? new string[] { } : inputPersonTypes.Split(',');
 
-            var itemsList = items.ToList();
-
             // Either get all people, or all people filtered by a specific person type
-            var allPeople = GetAllPeople(itemsList, personTypes);
+            var allPeople = GetAllPeople(items, personTypes);
 
             return allPeople
                 .Select(i => i.Name)
@@ -132,13 +130,13 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="itemsList">The items list.</param>
         /// <param name="personTypes">The person types.</param>
         /// <returns>IEnumerable{PersonInfo}.</returns>
-        private IEnumerable<PersonInfo> GetAllPeople(IEnumerable<BaseItem> itemsList, IEnumerable<string> personTypes)
+        private IEnumerable<PersonInfo> GetAllPeople(IList<BaseItem> itemsList, string[] personTypes)
         {
-            var allIds = itemsList.Select(i => i.Id).ToList();
+            var allIds = itemsList.Select(i => i.Id).ToArray();
 
             var allPeople = LibraryManager.GetPeople(new InternalPeopleQuery
             {
-                PersonTypes = personTypes.ToList()
+                PersonTypes = personTypes
             });
 
             return allPeople.Where(i => allIds.Contains(i.ItemId)).OrderBy(p => p.SortOrder ?? int.MaxValue).ThenBy(p => p.Type);

+ 2 - 4
MediaBrowser.Api/UserLibrary/StudiosService.cs

@@ -103,11 +103,9 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         /// <param name="items">The items.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
+        protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IList<BaseItem> items)
         {
-            var itemsList = items.Where(i => i.Studios != null).ToList();
-
-            return itemsList
+            return items
                 .SelectMany(i => i.Studios)
                 .DistinctNames()
                 .Select(name => LibraryManager.GetStudio(name));

+ 2 - 4
MediaBrowser.Api/UserLibrary/YearsService.cs

@@ -96,11 +96,9 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="request">The request.</param>
         /// <param name="items">The items.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items)
+        protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IList<BaseItem> items)
         {
-            var itemsList = items.Where(i => i.ProductionYear != null).ToList();
-
-            return itemsList
+            return items
                 .Select(i => i.ProductionYear ?? 0)
                 .Where(i => i > 0)
                 .Distinct()

+ 0 - 1
MediaBrowser.Api/VideosService.cs

@@ -140,7 +140,6 @@ namespace MediaBrowser.Api
         public async Task PostAsync(MergeVersions request)
         {
             var items = request.Ids.Split(',')
-                .Select(i => new Guid(i))
                 .Select(i => _libraryManager.GetItemById(i))
                 .OfType<Video>()
                 .ToList();

+ 2 - 2
MediaBrowser.Common/Updates/IInstallationManager.cs

@@ -48,7 +48,7 @@ namespace MediaBrowser.Common.Updates
         /// <param name="packageType">Type of the package.</param>
         /// <param name="applicationVersion">The application version.</param>
         /// <returns>Task{List{PackageInfo}}.</returns>
-        Task<PackageInfo[]> GetAvailablePackages(CancellationToken cancellationToken,
+        Task<List<PackageInfo>> GetAvailablePackages(CancellationToken cancellationToken,
             bool withRegistration = true,
                                                                                   string packageType = null,
                                                                                   Version applicationVersion = null);
@@ -58,7 +58,7 @@ namespace MediaBrowser.Common.Updates
         /// </summary>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task{List{PackageInfo}}.</returns>
-        Task<PackageInfo[]> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken);
+        Task<List<PackageInfo>> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken);
 
         /// <summary>
         /// Gets the package.

+ 2 - 2
MediaBrowser.Controller/Drawing/IImageProcessor.cs

@@ -24,7 +24,7 @@ namespace MediaBrowser.Controller.Drawing
         /// Gets the image enhancers.
         /// </summary>
         /// <value>The image enhancers.</value>
-        IEnumerable<IImageEnhancer> ImageEnhancers { get; }
+        IImageEnhancer[] ImageEnhancers { get; }
 
         /// <summary>
         /// Gets the size of the image.
@@ -54,7 +54,7 @@ namespace MediaBrowser.Controller.Drawing
         /// <param name="item">The item.</param>
         /// <param name="imageType">Type of the image.</param>
         /// <returns>IEnumerable{IImageEnhancer}.</returns>
-        IEnumerable<IImageEnhancer> GetSupportedEnhancers(IHasMetadata item, ImageType imageType);
+        List<IImageEnhancer> GetSupportedEnhancers(IHasMetadata item, ImageType imageType);
 
         /// <summary>
         /// Gets the image cache tag.

+ 19 - 12
MediaBrowser.Controller/Entities/AggregateFolder.cs

@@ -20,7 +20,7 @@ namespace MediaBrowser.Controller.Entities
     {
         public AggregateFolder()
         {
-            PhysicalLocationsList = new List<string>();
+            PhysicalLocationsList = EmptyStringArray;
         }
 
         [IgnoreDataMember]
@@ -58,7 +58,7 @@ namespace MediaBrowser.Controller.Entities
         }
 
         [IgnoreDataMember]
-        public override IEnumerable<string> PhysicalLocations
+        public override string[] PhysicalLocations
         {
             get
             {
@@ -66,23 +66,23 @@ namespace MediaBrowser.Controller.Entities
             }
         }
 
-        public List<string> PhysicalLocationsList { get; set; }
+        public string[] PhysicalLocationsList { get; set; }
 
         protected override FileSystemMetadata[] GetFileSystemChildren(IDirectoryService directoryService)
         {
-            return CreateResolveArgs(directoryService, true).FileSystemChildren.ToArray();
+            return CreateResolveArgs(directoryService, true).FileSystemChildren;
         }
 
-        private List<Guid> _childrenIds = null;
+        private Guid[] _childrenIds = null;
         private readonly object _childIdsLock = new object();
         protected override List<BaseItem> LoadChildren()
         {
             lock (_childIdsLock)
             {
-                if (_childrenIds == null || _childrenIds.Count == 0)
+                if (_childrenIds == null || _childrenIds.Length == 0)
                 {
-                    var list = base.LoadChildren().ToList();
-                    _childrenIds = list.Select(i => i.Id).ToList();
+                    var list = base.LoadChildren();
+                    _childrenIds = list.Select(i => i.Id).ToArray();
                     return list;
                 }
 
@@ -105,9 +105,9 @@ namespace MediaBrowser.Controller.Entities
 
             if (!changed)
             {
-                var locations = PhysicalLocations.ToList();
+                var locations = PhysicalLocations;
 
-                var newLocations = CreateResolveArgs(new DirectoryService(Logger, FileSystem), false).PhysicalLocations.ToList();
+                var newLocations = CreateResolveArgs(new DirectoryService(Logger, FileSystem), false).PhysicalLocations;
 
                 if (!locations.SequenceEqual(newLocations))
                 {
@@ -163,7 +163,7 @@ namespace MediaBrowser.Controller.Entities
             _requiresRefresh = _requiresRefresh || !args.PhysicalLocations.SequenceEqual(PhysicalLocations);
             if (setPhysicalLocations)
             {
-                PhysicalLocationsList = args.PhysicalLocations.ToList();
+                PhysicalLocationsList = args.PhysicalLocations;
             }
 
             return args;
@@ -212,7 +212,14 @@ namespace MediaBrowser.Controller.Entities
                 throw new ArgumentNullException("id");
             }
 
-            return _virtualChildren.FirstOrDefault(i => i.Id == id);
+            foreach (var child in _virtualChildren)
+            {
+                if (child.Id == id)
+                {
+                    return child;
+                }
+            }
+            return null;
         }
     }
 }

+ 16 - 6
MediaBrowser.Controller/Entities/Audio/Audio.cs

@@ -29,7 +29,7 @@ namespace MediaBrowser.Controller.Entities.Audio
         /// </summary>
         /// <value>The artist.</value>
         [IgnoreDataMember]
-        public List<string> Artists { get; set; }
+        public string[] Artists { get; set; }
 
         [IgnoreDataMember]
         public string[] AlbumArtists { get; set; }
@@ -42,7 +42,7 @@ namespace MediaBrowser.Controller.Entities.Audio
 
         public Audio()
         {
-            Artists = new List<string>();
+            Artists = EmptyStringArray;
             AlbumArtists = EmptyStringArray;
         }
 
@@ -98,13 +98,23 @@ namespace MediaBrowser.Controller.Entities.Audio
         }
 
         [IgnoreDataMember]
-        public List<string> AllArtists
+        public string[] AllArtists
         {
             get
             {
-                var list = AlbumArtists.ToList();
+                var list = new string[AlbumArtists.Length + Artists.Length];
 
-                list.AddRange(Artists);
+                var index = 0;
+                foreach (var artist in AlbumArtists)
+                {
+                    list[index] = artist;
+                    index++;
+                }
+                foreach (var artist in AlbumArtists)
+                {
+                    list[index] = artist;
+                    index++;
+                }
 
                 return list;
 
@@ -160,7 +170,7 @@ namespace MediaBrowser.Controller.Entities.Audio
                     songKey = Album + "-" + songKey;
                 }
 
-                var albumArtist = AlbumArtists.FirstOrDefault();
+                var albumArtist = AlbumArtists.Length == 0 ? null : AlbumArtists[0];
                 if (!string.IsNullOrWhiteSpace(albumArtist))
                 {
                     songKey = albumArtist + "-" + songKey;

+ 3 - 13
MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs

@@ -1,6 +1,4 @@
-using MediaBrowser.Controller.Library;
-using System.Collections.Generic;
-
+
 namespace MediaBrowser.Controller.Entities.Audio
 {
     public interface IHasAlbumArtist
@@ -10,16 +8,8 @@ namespace MediaBrowser.Controller.Entities.Audio
 
     public interface IHasArtist
     {
-        List<string> AllArtists { get; }
-
-        List<string> Artists { get; set; }
-    }
+        string[] AllArtists { get; }
 
-    public static class HasArtistExtensions
-    {
-        public static bool HasAnyArtist(this IHasArtist hasArtist, string artist)
-        {
-            return NameExtensions.EqualsAny(hasArtist.AllArtists, artist);
-        }
+        string[] Artists { get; set; }
     }
 }

+ 35 - 27
MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs

@@ -10,7 +10,6 @@ using System.Threading;
 using System.Threading.Tasks;
 using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Dto;
 
 namespace MediaBrowser.Controller.Entities.Audio
 {
@@ -20,11 +19,11 @@ namespace MediaBrowser.Controller.Entities.Audio
     public class MusicAlbum : Folder, IHasAlbumArtist, IHasArtist, IHasMusicGenres, IHasLookupInfo<AlbumInfo>, IMetadataContainer
     {
         public string[] AlbumArtists { get; set; }
-        public List<string> Artists { get; set; }
+        public string[] Artists { get; set; }
 
         public MusicAlbum()
         {
-            Artists = new List<string>();
+            Artists = EmptyStringArray;
             AlbumArtists = EmptyStringArray;
         }
 
@@ -48,17 +47,22 @@ namespace MediaBrowser.Controller.Entities.Audio
 
         public MusicArtist GetMusicArtist(DtoOptions options)
         {
-            var artist = GetParents().OfType<MusicArtist>().FirstOrDefault();
-
-            if (artist == null)
+            var parents = GetParents();
+            foreach (var parent in parents)
             {
-                var name = AlbumArtist;
-                if (!string.IsNullOrWhiteSpace(name))
+                var artist = parent as MusicArtist;
+                if (artist != null)
                 {
-                    artist = LibraryManager.GetArtist(name, options);
+                    return artist;
                 }
             }
-            return artist;
+
+            var name = AlbumArtist;
+            if (!string.IsNullOrWhiteSpace(name))
+            {
+                return LibraryManager.GetArtist(name, options);
+            }
+            return null;
         }
 
         [IgnoreDataMember]
@@ -80,23 +84,32 @@ namespace MediaBrowser.Controller.Entities.Audio
         }
 
         [IgnoreDataMember]
-        public List<string> AllArtists
+        public string[] AllArtists
         {
             get
             {
-                var list = AlbumArtists.ToList();
+                var list = new string[AlbumArtists.Length + Artists.Length];
 
-                list.AddRange(Artists);
+                var index = 0;
+                foreach (var artist in AlbumArtists)
+                {
+                    list[index] = artist;
+                    index++;
+                }
+                foreach (var artist in AlbumArtists)
+                {
+                    list[index] = artist;
+                    index++;
+                }
 
                 return list;
-
             }
         }
 
         [IgnoreDataMember]
         public string AlbumArtist
         {
-            get { return AlbumArtists.FirstOrDefault(); }
+            get { return AlbumArtists.Length == 0 ? null : AlbumArtists[0]; }
         }
 
         [IgnoreDataMember]
@@ -110,11 +123,11 @@ namespace MediaBrowser.Controller.Entities.Audio
         /// </summary>
         /// <value>The tracks.</value>
         [IgnoreDataMember]
-        public IEnumerable<Audio> Tracks
+        public IEnumerable<BaseItem> Tracks
         {
             get
             {
-                return GetRecursiveChildren(i => i is Audio).Cast<Audio>();
+                return GetRecursiveChildren(i => i is Audio);
             }
         }
 
@@ -200,7 +213,7 @@ namespace MediaBrowser.Controller.Entities.Audio
 
         public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken)
         {
-            var items = GetRecursiveChildren().ToList();
+            var items = GetRecursiveChildren();
 
             var totalItems = items.Count;
             var numComplete = 0;
@@ -239,27 +252,22 @@ namespace MediaBrowser.Controller.Entities.Audio
 
         private async Task RefreshArtists(MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)
         {
-            var artists = AllArtists.Select(i =>
+            var all = AllArtists;
+            foreach (var i in all)
             {
                 // This should not be necessary but we're seeing some cases of it
                 if (string.IsNullOrWhiteSpace(i))
                 {
-                    return null;
+                    continue;
                 }
 
                 var artist = LibraryManager.GetArtist(i);
 
                 if (!artist.IsAccessedByName)
                 {
-                    return null;
+                    continue;
                 }
 
-                return artist;
-
-            }).Where(i => i != null).ToList();
-
-            foreach (var artist in artists)
-            {
                 await artist.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
             }
         }

+ 13 - 7
MediaBrowser.Controller/Entities/Audio/MusicArtist.cs

@@ -214,18 +214,19 @@ namespace MediaBrowser.Controller.Entities.Audio
         {
             var items = GetRecursiveChildren();
 
-            var songs = items.OfType<Audio>().ToList();
-
-            var others = items.Except(songs).ToList();
-
-            var totalItems = songs.Count + others.Count;
+            var totalItems = items.Count;
             var numComplete = 0;
 
             var childUpdateType = ItemUpdateType.None;
 
             // Refresh songs
-            foreach (var item in songs)
+            foreach (var item in items)
             {
+                if (!(item is Audio))
+                {
+                    continue;
+                }
+
                 cancellationToken.ThrowIfCancellationRequested();
 
                 var updateType = await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
@@ -248,8 +249,13 @@ namespace MediaBrowser.Controller.Entities.Audio
             await RefreshMetadata(parentRefreshOptions, cancellationToken).ConfigureAwait(false);
 
             // Refresh all non-songs
-            foreach (var item in others)
+            foreach (var item in items)
             {
+                if (item is Audio)
+                {
+                    continue;
+                }
+
                 cancellationToken.ThrowIfCancellationRequested();
 
                 var updateType = await item.RefreshMetadata(parentRefreshOptions, cancellationToken).ConfigureAwait(false);

+ 0 - 1
MediaBrowser.Controller/Entities/Audio/MusicGenre.cs

@@ -1,6 +1,5 @@
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using MediaBrowser.Model.Serialization;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller.Extensions;

+ 1 - 1
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -570,7 +570,7 @@ namespace MediaBrowser.Controller.Entities
         }
 
         [IgnoreDataMember]
-        public virtual IEnumerable<string> PhysicalLocations
+        public virtual string[] PhysicalLocations
         {
             get
             {

+ 1 - 1
MediaBrowser.Controller/Entities/Book.cs

@@ -1,7 +1,7 @@
 using System;
+using System.Linq;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Configuration;
-using System.Linq;
 using MediaBrowser.Model.Serialization;
 using MediaBrowser.Model.Entities;
 

+ 13 - 13
MediaBrowser.Controller/Entities/CollectionFolder.cs

@@ -27,8 +27,8 @@ namespace MediaBrowser.Controller.Entities
 
         public CollectionFolder()
         {
-            PhysicalLocationsList = new List<string>();
-            PhysicalFolderIds = new List<Guid>();
+            PhysicalLocationsList = EmptyStringArray;
+            PhysicalFolderIds = EmptyGuidArray;
         }
 
         [IgnoreDataMember]
@@ -140,7 +140,7 @@ namespace MediaBrowser.Controller.Entities
         }
 
         [IgnoreDataMember]
-        public override IEnumerable<string> PhysicalLocations
+        public override string[] PhysicalLocations
         {
             get
             {
@@ -153,12 +153,12 @@ namespace MediaBrowser.Controller.Entities
             return true;
         }
 
-        public List<string> PhysicalLocationsList { get; set; }
-        public List<Guid> PhysicalFolderIds { get; set; }
+        public string[] PhysicalLocationsList { get; set; }
+        public Guid[] PhysicalFolderIds { get; set; }
 
         protected override FileSystemMetadata[] GetFileSystemChildren(IDirectoryService directoryService)
         {
-            return CreateResolveArgs(directoryService, true).FileSystemChildren.ToArray();
+            return CreateResolveArgs(directoryService, true).FileSystemChildren;
         }
 
         private bool _requiresRefresh;
@@ -168,9 +168,9 @@ namespace MediaBrowser.Controller.Entities
 
             if (!changed)
             {
-                var locations = PhysicalLocations.ToList();
+                var locations = PhysicalLocations;
 
-                var newLocations = CreateResolveArgs(new DirectoryService(Logger, FileSystem), false).PhysicalLocations.ToList();
+                var newLocations = CreateResolveArgs(new DirectoryService(Logger, FileSystem), false).PhysicalLocations;
 
                 if (!locations.SequenceEqual(newLocations))
                 {
@@ -180,7 +180,7 @@ namespace MediaBrowser.Controller.Entities
 
             if (!changed)
             {
-                var folderIds = PhysicalFolderIds.ToList();
+                var folderIds = PhysicalFolderIds;
 
                 var newFolderIds = GetPhysicalFolders(false).Select(i => i.Id).ToList();
 
@@ -242,15 +242,15 @@ namespace MediaBrowser.Controller.Entities
 
             LinkedChildren = linkedChildren.ToArray(linkedChildren.Count);
 
-            var folderIds = PhysicalFolderIds.ToList();
-            var newFolderIds = physicalFolders.Select(i => i.Id).ToList();
+            var folderIds = PhysicalFolderIds;
+            var newFolderIds = physicalFolders.Select(i => i.Id).ToArray();
 
             if (!folderIds.SequenceEqual(newFolderIds))
             {
                 changed = true;
                 if (setFolders)
                 {
-                    PhysicalFolderIds = newFolderIds.ToList();
+                    PhysicalFolderIds = newFolderIds;
                 }
             }
 
@@ -307,7 +307,7 @@ namespace MediaBrowser.Controller.Entities
             _requiresRefresh = _requiresRefresh || !args.PhysicalLocations.SequenceEqual(PhysicalLocations);
             if (setPhysicalLocations)
             {
-                PhysicalLocationsList = args.PhysicalLocations.ToList();
+                PhysicalLocationsList = args.PhysicalLocations;
             }
 
             return args;

+ 0 - 1
MediaBrowser.Controller/Entities/Game.cs

@@ -3,7 +3,6 @@ using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Entities;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Serialization;
 

+ 0 - 1
MediaBrowser.Controller/Entities/GameGenre.cs

@@ -1,6 +1,5 @@
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using MediaBrowser.Model.Serialization;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller.Extensions;

+ 0 - 1
MediaBrowser.Controller/Entities/Genre.cs

@@ -2,7 +2,6 @@
 using MediaBrowser.Controller.Entities.Audio;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller.Extensions;
 using MediaBrowser.Model.Extensions;

+ 1 - 1
MediaBrowser.Controller/Entities/ICollectionFolder.cs

@@ -13,7 +13,7 @@ namespace MediaBrowser.Controller.Entities
         string Path { get; }
         string Name { get; }
         Guid Id { get; }
-        IEnumerable<string> PhysicalLocations { get; }
+        string[] PhysicalLocations { get; }
     }
 
     public interface ISupportsUserSpecificView

+ 2 - 2
MediaBrowser.Controller/Entities/InternalPeopleQuery.cs

@@ -6,7 +6,7 @@ namespace MediaBrowser.Controller.Entities
     public class InternalPeopleQuery
     {
         public Guid ItemId { get; set; }
-        public List<string> PersonTypes { get; set; }
+        public string[] PersonTypes { get; set; }
         public List<string> ExcludePersonTypes { get; set; }
         public int? MaxListOrder { get; set; }
         public Guid AppearsInItemId { get; set; }
@@ -14,7 +14,7 @@ namespace MediaBrowser.Controller.Entities
 
         public InternalPeopleQuery()
         {
-            PersonTypes = new List<string>();
+            PersonTypes = new string[] {};
             ExcludePersonTypes = new List<string>();
         }
     }

+ 2 - 3
MediaBrowser.Controller/Entities/Movies/BoxSet.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Controller.Entities.TV;
-using MediaBrowser.Controller.Providers;
+using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Querying;
@@ -169,7 +168,7 @@ namespace MediaBrowser.Controller.Entities.Movies
 
             if (base.IsVisible(user))
             {
-                return base.GetChildren(user, true).Any();
+                return base.GetChildren(user, true).Count > 0;
             }
 
             return false;

+ 3 - 3
MediaBrowser.Controller/Entities/MusicVideo.cs

@@ -9,15 +9,15 @@ namespace MediaBrowser.Controller.Entities
     public class MusicVideo : Video, IHasArtist, IHasMusicGenres, IHasLookupInfo<MusicVideoInfo>
     {
         [IgnoreDataMember]
-        public List<string> Artists { get; set; }
+        public string[] Artists { get; set; }
 
         public MusicVideo()
         {
-            Artists = new List<string>();
+            Artists = EmptyStringArray;
         }
 
         [IgnoreDataMember]
-        public List<string> AllArtists
+        public string[] AllArtists
         {
             get
             {

+ 9 - 1
MediaBrowser.Controller/Entities/PeopleHelper.cs

@@ -105,7 +105,15 @@ namespace MediaBrowser.Controller.Entities
             {
                 throw new ArgumentNullException("name");
             }
-            return people.Any(i => string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase));
+
+            foreach (var i in people)
+            {
+                if (string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase))
+                {
+                    return true;
+                }
+            }
+            return false;
         }
     }
 }

+ 0 - 1
MediaBrowser.Controller/Entities/Person.cs

@@ -1,7 +1,6 @@
 using MediaBrowser.Controller.Providers;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller.Extensions;
 using MediaBrowser.Model.Entities;

+ 10 - 2
MediaBrowser.Controller/Entities/Photo.cs

@@ -1,5 +1,4 @@
 using MediaBrowser.Model.Drawing;
-using System.Linq;
 using MediaBrowser.Model.Serialization;
 
 namespace MediaBrowser.Controller.Entities
@@ -39,7 +38,16 @@ namespace MediaBrowser.Controller.Entities
         {
             get
             {
-                return GetParents().OfType<PhotoAlbum>().FirstOrDefault();
+                var parents = GetParents();
+                foreach (var parent in parents)
+                {
+                    var photoAlbum = parent as PhotoAlbum;
+                    if (photoAlbum != null)
+                    {
+                        return photoAlbum;
+                    }
+                }
+                return null;
             }
         }
 

+ 0 - 1
MediaBrowser.Controller/Entities/Studio.cs

@@ -1,6 +1,5 @@
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using MediaBrowser.Model.Serialization;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller.Extensions;

+ 1 - 1
MediaBrowser.Controller/Entities/TV/Season.cs

@@ -81,7 +81,7 @@ namespace MediaBrowser.Controller.Entities.TV
 
         public override int GetChildCount(User user)
         {
-            var result = GetChildren(user, true).Count();
+            var result = GetChildren(user, true).Count;
 
             return result;
         }

+ 9 - 1
MediaBrowser.Controller/Entities/TV/Series.cs

@@ -214,7 +214,15 @@ namespace MediaBrowser.Controller.Entities.TV
         {
             get
             {
-                return Children.OfType<Video>().Any();
+                var children = Children;
+                foreach (var child in children)
+                {
+                    if (child is Video)
+                    {
+                        return true;
+                    }
+                }
+                return false;
             }
         }
 

+ 16 - 3
MediaBrowser.Controller/Entities/User.cs

@@ -5,7 +5,6 @@ using MediaBrowser.Model.Connect;
 using MediaBrowser.Model.Serialization;
 using MediaBrowser.Model.Users;
 using System;
-using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 
@@ -279,7 +278,14 @@ namespace MediaBrowser.Controller.Entities
                 return true;
             }
 
-            return schedules.Any(i => IsParentalScheduleAllowed(i, date));
+            foreach (var i in schedules)
+            {
+                if (IsParentalScheduleAllowed(i, date))
+                {
+                    return true;
+                }
+            }
+            return false;
         }
 
         private bool IsParentalScheduleAllowed(AccessSchedule schedule, DateTime date)
@@ -304,7 +310,14 @@ namespace MediaBrowser.Controller.Entities
 
         public bool IsFolderGrouped(Guid id)
         {
-            return Configuration.GroupedFolders.Select(i => new Guid(i)).Contains(id);
+            foreach (var i in Configuration.GroupedFolders)
+            {
+                if (new Guid(i) == id)
+                {
+                    return true;
+                }
+            }
+            return false;
         }
 
         [IgnoreDataMember]

+ 1 - 1
MediaBrowser.Controller/Entities/UserRootFolder.cs

@@ -24,7 +24,7 @@ namespace MediaBrowser.Controller.Entities
             {
                 if (_childrenIds == null)
                 {
-                    var list = base.LoadChildren().ToList();
+                    var list = base.LoadChildren();
                     _childrenIds = list.Select(i => i.Id).ToList();
                     return list;
                 }

+ 2 - 2
MediaBrowser.Controller/Entities/UserView.cs

@@ -4,9 +4,9 @@ using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Querying;
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using MediaBrowser.Model.Serialization;
 using System.Threading.Tasks;
-using System.Linq;
 using MediaBrowser.Controller.Dto;
 
 namespace MediaBrowser.Controller.Entities
@@ -60,7 +60,7 @@ namespace MediaBrowser.Controller.Entities
 
         public override int GetChildCount(User user)
         {
-            return GetChildren(user, true).Count();
+            return GetChildren(user, true).Count;
         }
 
         protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery query)

+ 0 - 1
MediaBrowser.Controller/Entities/Year.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.Globalization;
-using System.Linq;
 using MediaBrowser.Model.Serialization;
 
 namespace MediaBrowser.Controller.Entities

+ 9 - 2
MediaBrowser.Controller/IO/FileData.cs

@@ -3,7 +3,6 @@ using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Logging;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using MediaBrowser.Model.IO;
 
 namespace MediaBrowser.Controller.IO
@@ -107,7 +106,15 @@ namespace MediaBrowser.Controller.IO
                 }
             }
 
-            return dict.Values.ToArray();
+            var returnResult = new FileSystemMetadata[dict.Count];
+            var index = 0;
+            var values = dict.Values;
+            foreach (var value in values)
+            {
+                returnResult[index] = value;
+                index++;
+            }
+            return returnResult;
         }
 
     }

+ 10 - 4
MediaBrowser.Controller/Library/ItemResolveArgs.cs

@@ -4,7 +4,6 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
-
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Model.Configuration;
@@ -134,7 +133,14 @@ namespace MediaBrowser.Controller.Library
                 // Not officially supported but in some cases we can handle it.
                 if (item == null)
                 {
-                    item = parent.GetParents().OfType<T>().FirstOrDefault();
+                    var parents = parent.GetParents();
+                    foreach (var currentParent in parents)
+                    {
+                        if (currentParent is T)
+                        {
+                            return true;
+                        }
+                    }
                 }
 
                 return item != null;
@@ -167,12 +173,12 @@ namespace MediaBrowser.Controller.Library
         /// Gets the physical locations.
         /// </summary>
         /// <value>The physical locations.</value>
-        public IEnumerable<string> PhysicalLocations
+        public string[] PhysicalLocations
         {
             get
             {
                 var paths = string.IsNullOrWhiteSpace(Path) ? new string[] { } : new[] { Path };
-                return AdditionalLocations == null ? paths : paths.Concat(AdditionalLocations);
+                return AdditionalLocations == null ? paths : paths.Concat(AdditionalLocations).ToArray();
             }
         }
 

+ 0 - 44
MediaBrowser.Controller/Library/NameExtensions.cs

@@ -1,7 +1,5 @@
 using System;
 using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
 using MediaBrowser.Controller.Extensions;
 using MediaBrowser.Model.Extensions;
 
@@ -9,25 +7,6 @@ namespace MediaBrowser.Controller.Library
 {
     public static class NameExtensions
     {
-        public static bool EqualsAny(IEnumerable<string> names, string x)
-        {
-            x = NormalizeForComparison(x);
-
-            return names.Any(y => string.Compare(x, y, StringComparison.OrdinalIgnoreCase) == 0);
-            //return names.Any(y => string.Compare(x, y, CultureInfo.InvariantCulture, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace) == 0);
-        }
-
-        private static string NormalizeForComparison(string name)
-        {
-            if (name == null)
-            {
-                return string.Empty;
-            }
-
-            return name;
-            //return name.RemoveDiacritics();
-        }
-
         private static string RemoveDiacritics(string name)
         {
             if (name == null)
@@ -44,27 +23,4 @@ namespace MediaBrowser.Controller.Library
             return names.DistinctBy(RemoveDiacritics, StringComparer.OrdinalIgnoreCase);
         }
     }
-
-    public class DistinctNameComparer : IComparer<string>, IEqualityComparer<string>
-    {
-        public int Compare(string x, string y)
-        {
-            if (string.IsNullOrWhiteSpace(x) && string.IsNullOrWhiteSpace(y))
-            {
-                return 0;
-            }
-
-            return string.Compare(x.RemoveDiacritics(), y.RemoveDiacritics(), StringComparison.OrdinalIgnoreCase);
-        }
-
-        public bool Equals(string x, string y)
-        {
-            return Compare(x, y) == 0;
-        }
-
-        public int GetHashCode(string obj)
-        {
-            return (obj ?? string.Empty).GetHashCode();
-        }
-    }
 }

+ 0 - 1
MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs

@@ -6,7 +6,6 @@ using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.LiveTv;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using MediaBrowser.Model.Serialization;
 using System.Threading.Tasks;
 using MediaBrowser.Controller.Library;

+ 0 - 1
MediaBrowser.Controller/LiveTv/LiveTvProgram.cs

@@ -9,7 +9,6 @@ using MediaBrowser.Common.Configuration;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Providers;
 using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Extensions;
 
 namespace MediaBrowser.Controller.LiveTv
 {

+ 0 - 1
MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs

@@ -5,7 +5,6 @@ using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.LiveTv;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using MediaBrowser.Model.Serialization;
 using System.Threading.Tasks;
 using MediaBrowser.Controller.Library;

+ 12 - 4
MediaBrowser.Controller/Providers/DirectoryService.cs

@@ -4,7 +4,6 @@ using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
-
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Model.IO;
 
@@ -73,14 +72,23 @@ namespace MediaBrowser.Controller.Providers
             return entries;
         }
 
-        public IEnumerable<FileSystemMetadata> GetFiles(string path)
+        public List<FileSystemMetadata> GetFiles(string path)
         {
             return GetFiles(path, false);
         }
 
-        public IEnumerable<FileSystemMetadata> GetFiles(string path, bool clearCache)
+        public List<FileSystemMetadata> GetFiles(string path, bool clearCache)
         {
-            return GetFileSystemEntries(path, clearCache).Where(i => !i.IsDirectory);
+            var list = new List<FileSystemMetadata>();
+            var items = GetFileSystemEntries(path, clearCache);
+            foreach (var item in items)
+            {
+                if (!item.IsDirectory)
+                {
+                    list.Add(item);
+                }
+            }
+            return list;
         }
 
         public FileSystemMetadata GetFile(string path)

+ 1 - 1
MediaBrowser.Controller/Providers/IDirectoryService.cs

@@ -6,7 +6,7 @@ namespace MediaBrowser.Controller.Providers
     public interface IDirectoryService
     {
         FileSystemMetadata[] GetFileSystemEntries(string path);
-        IEnumerable<FileSystemMetadata> GetFiles(string path);
+        List<FileSystemMetadata> GetFiles(string path);
         FileSystemMetadata GetFile(string path);
     }
 }

+ 9 - 2
MediaBrowser.Controller/Providers/MetadataResult.cs

@@ -1,7 +1,6 @@
 using MediaBrowser.Controller.Entities;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 
 namespace MediaBrowser.Controller.Providers
 {
@@ -51,7 +50,15 @@ namespace MediaBrowser.Controller.Providers
                 UserDataList = new List<UserItemData>();
             }
 
-            var userData = UserDataList.FirstOrDefault(i => string.Equals(userId, i.UserId.ToString("N"), StringComparison.OrdinalIgnoreCase));
+            UserItemData userData = null;
+
+            foreach (var i in UserDataList)
+            {
+                if (string.Equals(userId, i.UserId.ToString("N"), StringComparison.OrdinalIgnoreCase))
+                {
+                    userData = i;
+                }
+            }
 
             if (userData == null)
             {

+ 2 - 3
MediaBrowser.Controller/Providers/SongInfo.cs

@@ -1,4 +1,3 @@
-using System.Collections.Generic;
 
 namespace MediaBrowser.Controller.Providers
 {
@@ -6,11 +5,11 @@ namespace MediaBrowser.Controller.Providers
     {
         public string[] AlbumArtists { get; set; }
         public string Album { get; set; }
-        public List<string> Artists { get; set; }
+        public string[] Artists { get; set; }
 
         public SongInfo()
         {
-            Artists = new List<string>();
+            Artists = EmptyStringArray;
             AlbumArtists = EmptyStringArray;
         }
     }

+ 13 - 2
MediaBrowser.Controller/Session/SessionInfo.cs

@@ -2,7 +2,6 @@
 using MediaBrowser.Model.Session;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Threading;
@@ -194,7 +193,19 @@ namespace MediaBrowser.Controller.Session
 
         public bool ContainsUser(Guid userId)
         {
-            return (UserId ?? Guid.Empty) == userId || AdditionalUsers.Any(i => userId == new Guid(i.UserId));
+            if ((UserId ?? Guid.Empty) == userId)
+            {
+                return true;
+            }
+
+            foreach (var additionalUser in AdditionalUsers)
+            {
+                if (userId == new Guid(additionalUser.UserId))
+                {
+                    return true;
+                }
+            }
+            return false;
         }
 
         private readonly object _progressLock = new object();

+ 35 - 36
MediaBrowser.LocalMetadata/Images/EpisodeLocalImageProvider.cs

@@ -4,10 +4,8 @@ using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
 using System;
 using System.Collections.Generic;
-using System.IO;
 using System.Linq;
 
-using MediaBrowser.Controller.IO;
 using MediaBrowser.Model.IO;
 
 namespace MediaBrowser.LocalMetadata.Images
@@ -40,49 +38,50 @@ namespace MediaBrowser.LocalMetadata.Images
         {
             var parentPath = _fileSystem.GetDirectoryName(item.Path);
 
-            var parentPathFiles = directoryService.GetFiles(parentPath)
-                .ToList();
+            var parentPathFiles = directoryService.GetFiles(parentPath);
 
             var nameWithoutExtension = _fileSystem.GetFileNameWithoutExtension(item.Path);
 
             return GetFilesFromParentFolder(nameWithoutExtension, parentPathFiles);
         }
 
-        private List<LocalImageInfo> GetFilesFromParentFolder(string filenameWithoutExtension, IEnumerable<FileSystemMetadata> parentPathFiles)
+        private List<LocalImageInfo> GetFilesFromParentFolder(string filenameWithoutExtension, List<FileSystemMetadata> parentPathFiles)
         {
             var thumbName = filenameWithoutExtension + "-thumb";
 
-            return parentPathFiles
-              .Where(i =>
-              {
-                  if (i.IsDirectory)
-                  {
-                      return false;
-                  }
-                  
-                  if (BaseItem.SupportedImageExtensions.Contains(i.Extension, StringComparer.OrdinalIgnoreCase))
-                  {
-                      var currentNameWithoutExtension = _fileSystem.GetFileNameWithoutExtension(i);
-
-                      if (string.Equals(filenameWithoutExtension, currentNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
-                      {
-                          return true;
-                      }
-
-                      if (string.Equals(thumbName, currentNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
-                      {
-                          return true;
-                      }
-                  }
-
-                  return false;
-              })
-              .Select(i => new LocalImageInfo
-              {
-                  FileInfo = i,
-                  Type = ImageType.Primary
-              })
-              .ToList();
+            var list = new List<LocalImageInfo>(1);
+
+            foreach (var i in parentPathFiles)
+            {
+                if (i.IsDirectory)
+                {
+                    continue;
+                }
+
+                if (BaseItem.SupportedImageExtensions.Contains(i.Extension, StringComparer.OrdinalIgnoreCase))
+                {
+                    var currentNameWithoutExtension = _fileSystem.GetFileNameWithoutExtension(i);
+
+                    if (string.Equals(filenameWithoutExtension, currentNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
+                    {
+                        list.Add(new LocalImageInfo
+                        {
+                            FileInfo = i,
+                            Type = ImageType.Primary
+                        });
+                    }
+
+                    else if (string.Equals(thumbName, currentNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
+                    {
+                        list.Add(new LocalImageInfo
+                        {
+                            FileInfo = i,
+                            Type = ImageType.Primary
+                        });
+                    }
+                }
+            }
+            return list;
         }
     }
 }

+ 0 - 1
MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs

@@ -7,7 +7,6 @@ using System;
 using System.Collections.Generic;
 using System.Globalization;
 using System.Linq;
-
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Model.IO;
 

+ 1 - 1
MediaBrowser.Model/Dto/BaseItemDto.cs

@@ -432,7 +432,7 @@ namespace MediaBrowser.Model.Dto
         /// Gets or sets the artists.
         /// </summary>
         /// <value>The artists.</value>
-        public List<string> Artists { get; set; }
+        public string[] Artists { get; set; }
 
         /// <summary>
         /// Gets or sets the artist items.

+ 6 - 11
MediaBrowser.Model/Dto/MediaSourceInfo.cs

@@ -2,7 +2,6 @@
 using MediaBrowser.Model.Extensions;
 using MediaBrowser.Model.MediaInfo;
 using System.Collections.Generic;
-using System.Linq;
 using MediaBrowser.Model.Serialization;
 using MediaBrowser.Model.Session;
 
@@ -91,19 +90,15 @@ namespace MediaBrowser.Model.Dto
                 return;
             }
 
-            var internalStreams = MediaStreams
-                .Where(i => !i.IsExternal)
-                .ToList();
-
-            if (internalStreams.Count == 0)
+            var bitrate = 0;
+            foreach (var stream in MediaStreams)
             {
-                return;
+                if (!stream.IsExternal)
+                {
+                    bitrate += stream.BitRate ?? 0;
+                }
             }
 
-            var bitrate = internalStreams
-                .Select(m => m.BitRate ?? 0)
-                .Sum();
-
             if (bitrate > 0)
             {
                 Bitrate = bitrate;

+ 8 - 3
MediaBrowser.Model/Extensions/ListHelper.cs

@@ -1,6 +1,4 @@
 using System;
-using System.Collections.Generic;
-using System.Linq;
 
 namespace MediaBrowser.Model.Extensions
 {
@@ -13,7 +11,14 @@ namespace MediaBrowser.Model.Extensions
                 throw new ArgumentNullException("value");
             }
 
-            return list.Contains(value, StringComparer.OrdinalIgnoreCase);
+            foreach (var item in list)
+            {
+                if (string.Equals(item, value, StringComparison.OrdinalIgnoreCase))
+                {
+                    return true;
+                }
+            }
+            return false;
         }
 
         public static bool ContainsAnyIgnoreCase(string[] list, string[] values)

+ 50 - 17
MediaBrowser.Model/Services/QueryParamCollection.cs

@@ -58,9 +58,7 @@ namespace MediaBrowser.Model.Services
         {
             if (string.IsNullOrWhiteSpace(value))
             {
-                var stringComparison = GetStringComparison();
-
-                var parameters = this.Where(p => string.Equals(key, p.Name, stringComparison)).ToArray();
+                var parameters = GetItems(key);
 
                 foreach (var p in parameters)
                 {
@@ -84,14 +82,6 @@ namespace MediaBrowser.Model.Services
             Add(key, value);
         }
 
-        /// <summary>
-        /// True if the collection contains a query parameter with the given name.
-        /// </summary>
-        public bool ContainsKey(string name)
-        {
-            return this.Any(p => p.Name == name);
-        }
-
         /// <summary>
         /// Removes all parameters of the given name.
         /// </summary>
@@ -106,16 +96,49 @@ namespace MediaBrowser.Model.Services
         {
             var stringComparison = GetStringComparison();
 
-            return this.Where(p => string.Equals(p.Name, name, stringComparison))
-                .Select(p => p.Value)
-                .FirstOrDefault();
+            foreach (var pair in this)
+            {
+                if (string.Equals(pair.Name, name, stringComparison))
+                {
+                    return pair.Value;
+                }
+            }
+
+            return null;
+        }
+
+        public virtual List<NameValuePair> GetItems(string name)
+        {
+            var stringComparison = GetStringComparison();
+
+            var list = new List<NameValuePair>();
+
+            foreach (var pair in this)
+            {
+                if (string.Equals(pair.Name, name, stringComparison))
+                {
+                    list.Add(pair);
+                }
+            }
+
+            return list;
         }
 
-        public virtual string[] GetValues(string name)
+        public virtual List<string> GetValues(string name)
         {
             var stringComparison = GetStringComparison();
 
-            return this.Where(p => string.Equals(p.Name, name, stringComparison)).Select(p => p.Value).ToArray();
+            var list = new List<string>();
+
+            foreach (var pair in this)
+            {
+                if (string.Equals(pair.Name, name, stringComparison))
+                {
+                    list.Add(pair.Value);
+                }
+            }
+
+            return list;
         }
 
         public Dictionary<string, string> ToDictionary()
@@ -134,7 +157,17 @@ namespace MediaBrowser.Model.Services
 
         public IEnumerable<string> Keys
         {
-            get { return this.Select(i => i.Name); }
+            get
+            {
+                var keys = new string[this.Count];
+
+                for (var i = 0; i < keys.Length; i++)
+                {
+                    keys[i] = this[i].Name;
+                }
+
+                return keys;
+            }
         }
 
         /// <summary>

+ 2 - 0
MediaBrowser.Model/Updates/PackageVersionInfo.cs

@@ -89,5 +89,7 @@ namespace MediaBrowser.Model.Updates
         public string targetFilename { get; set; }
 
         public string infoUrl { get; set; }
+
+        public string runtimes { get; set; }
     }
 }

+ 2 - 2
MediaBrowser.Providers/Books/AudioBookMetadataService.cs

@@ -23,9 +23,9 @@ namespace MediaBrowser.Providers.Books
             var sourceItem = source.Item;
             var targetItem = target.Item;
 
-            if (replaceData || targetItem.Artists.Count == 0)
+            if (replaceData || targetItem.Artists.Length == 0)
             {
-                targetItem.Artists = sourceItem.Artists.ToList();
+                targetItem.Artists = sourceItem.Artists;
             }
 
             if (replaceData || string.IsNullOrEmpty(targetItem.Album))

+ 2 - 2
MediaBrowser.Providers/Books/AudioPodcastMetadataService.cs

@@ -23,9 +23,9 @@ namespace MediaBrowser.Providers.Books
             var sourceItem = source.Item;
             var targetItem = target.Item;
 
-            if (replaceData || targetItem.Artists.Count == 0)
+            if (replaceData || targetItem.Artists.Length == 0)
             {
-                targetItem.Artists = sourceItem.Artists.ToList();
+                targetItem.Artists = sourceItem.Artists;
             }
 
             if (replaceData || string.IsNullOrEmpty(targetItem.Album))

+ 1 - 5
MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs

@@ -41,11 +41,7 @@ namespace MediaBrowser.Providers.BoxSets
 
             if (mergeMetadataSettings)
             {
-                // Retain shortcut children
-                var linkedChildren = sourceItem.LinkedChildren.ToList();
-                linkedChildren.AddRange(sourceItem.LinkedChildren.Where(i => i.Type == LinkedChildType.Shortcut));
-
-                targetItem.LinkedChildren = linkedChildren.ToArray(linkedChildren.Count);
+                targetItem.LinkedChildren = sourceItem.LinkedChildren;
                 targetItem.Shares = sourceItem.Shares;
             }
         }

+ 0 - 1
MediaBrowser.Providers/Chapters/ChapterManager.cs

@@ -13,7 +13,6 @@ using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 

+ 0 - 1
MediaBrowser.Providers/Manager/GenericPriorityQueue.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
-using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 

+ 0 - 1
MediaBrowser.Providers/Manager/GenericPriorityQueueNode.cs

@@ -1,6 +1,5 @@
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 

+ 0 - 1
MediaBrowser.Providers/Manager/IFixedSizePriorityQueue.cs

@@ -1,6 +1,5 @@
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 

+ 0 - 1
MediaBrowser.Providers/Manager/IPriorityQueue.cs

@@ -1,6 +1,5 @@
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 

+ 0 - 1
MediaBrowser.Providers/Manager/SimplePriorityQueue.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
-using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 

+ 1 - 1
MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs

@@ -93,7 +93,7 @@ namespace MediaBrowser.Providers.MediaInfo
         private string GetAudioImagePath(Audio item)
         {
             var filename = item.Album ?? string.Empty;
-            filename += string.Join(",", item.Artists.ToArray(item.Artists.Count));
+            filename += string.Join(",", item.Artists);
 
             if (!string.IsNullOrWhiteSpace(item.Album))
             {

Some files were not shown because too many files changed in this diff