From 49fe5e0a21907797248daada0a0446b37bb304ba Mon Sep 17 00:00:00 2001
From: Bond_009 <bond.009@outlook.com>
Date: Sat, 11 Apr 2020 12:03:10 +0200
Subject: [PATCH] Fix some warnings

---
 .../Activity/ActivityLogEntryPoint.cs         |  38 ++--
 .../Activity/ActivityManager.cs               |  11 +-
 .../Activity/ActivityRepository.cs            | 104 +++++------
 .../ApplicationHost.cs                        |   2 +-
 .../Archiving/ZipClient.cs                    |   3 +
 .../Channels/ChannelImageProvider.cs          |   4 +-
 .../Channels/ChannelManager.cs                | 168 +++++++++---------
 .../Channels/ChannelPostScanTask.cs           |   4 +-
 .../Channels/RefreshChannelsScheduledTask.cs  |   8 +-
 .../Collections/CollectionImageProvider.cs    |   4 +-
 .../Collections/CollectionManager.cs          |  20 ++-
 .../LiveTv/LiveTvDtoService.cs                |  25 ++-
 .../LiveTv/LiveTvManager.cs                   |  24 ++-
 .../IDisplayPreferencesRepository.cs          |  22 ++-
 .../LiveTv/SeriesTimerInfoDto.cs              |   2 +-
 15 files changed, 231 insertions(+), 208 deletions(-)

diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
index d900520b2a..9f1d5096d3 100644
--- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
+++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
@@ -1,5 +1,3 @@
-#pragma warning disable CS1591
-
 using System;
 using System.Collections.Generic;
 using System.Globalization;
@@ -27,6 +25,9 @@ using Microsoft.Extensions.Logging;
 
 namespace Emby.Server.Implementations.Activity
 {
+    /// <summary>
+    /// Entry point for the activity logger.
+    /// </summary>
     public sealed class ActivityLogEntryPoint : IServerEntryPoint
     {
         private readonly ILogger _logger;
@@ -42,16 +43,15 @@ namespace Emby.Server.Implementations.Activity
         /// <summary>
         /// Initializes a new instance of the <see cref="ActivityLogEntryPoint"/> class.
         /// </summary>
-        /// <param name="logger"></param>
-        /// <param name="sessionManager"></param>
-        /// <param name="deviceManager"></param>
-        /// <param name="taskManager"></param>
-        /// <param name="activityManager"></param>
-        /// <param name="localization"></param>
-        /// <param name="installationManager"></param>
-        /// <param name="subManager"></param>
-        /// <param name="userManager"></param>
-        /// <param name="appHost"></param>
+        /// <param name="logger">The logger.</param>
+        /// <param name="sessionManager">The session manager.</param>
+        /// <param name="deviceManager">The device manager.</param>
+        /// <param name="taskManager">The task manager.</param>
+        /// <param name="activityManager">The activity manager.</param>
+        /// <param name="localization">The localization manager.</param>
+        /// <param name="installationManager">The installation manager.</param>
+        /// <param name="subManager">The subtitle manager.</param>
+        /// <param name="userManager">The user manager.</param>
         public ActivityLogEntryPoint(
             ILogger<ActivityLogEntryPoint> logger,
             ISessionManager sessionManager,
@@ -74,6 +74,7 @@ namespace Emby.Server.Implementations.Activity
             _userManager = userManager;
         }
 
+        /// <inheritdoc />
         public Task RunAsync()
         {
             _taskManager.TaskCompleted += OnTaskCompleted;
@@ -168,7 +169,12 @@ namespace Emby.Server.Implementations.Activity
 
             CreateLogEntry(new ActivityLogEntry
             {
-                Name = string.Format(_localization.GetLocalizedString("UserStoppedPlayingItemWithValues"), user.Name, GetItemName(item), e.DeviceName),
+                Name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("UserStoppedPlayingItemWithValues"),
+                    user.Name,
+                    GetItemName(item),
+                    e.DeviceName),
                 Type = GetPlaybackStoppedNotificationType(item.MediaType),
                 UserId = user.Id
             });
@@ -485,8 +491,8 @@ namespace Emby.Server.Implementations.Activity
             var result = e.Result;
             var task = e.Task;
 
-            var activityTask = task.ScheduledTask as IConfigurableScheduledTask;
-            if (activityTask != null && !activityTask.IsLogged)
+            if (task.ScheduledTask is IConfigurableScheduledTask activityTask
+                && !activityTask.IsLogged)
             {
                 return;
             }
@@ -560,7 +566,7 @@ namespace Emby.Server.Implementations.Activity
         /// <summary>
         /// Constructs a user-friendly string for this TimeSpan instance.
         /// </summary>
-        public static string ToUserFriendlyString(TimeSpan span)
+        private static string ToUserFriendlyString(TimeSpan span)
         {
             const int DaysInYear = 365;
             const int DaysInMonth = 30;
diff --git a/Emby.Server.Implementations/Activity/ActivityManager.cs b/Emby.Server.Implementations/Activity/ActivityManager.cs
index ee10845cfa..c1d8dd8da8 100644
--- a/Emby.Server.Implementations/Activity/ActivityManager.cs
+++ b/Emby.Server.Implementations/Activity/ActivityManager.cs
@@ -11,22 +11,17 @@ namespace Emby.Server.Implementations.Activity
 {
     public class ActivityManager : IActivityManager
     {
-        public event EventHandler<GenericEventArgs<ActivityLogEntry>> EntryCreated;
-
         private readonly IActivityRepository _repo;
-        private readonly ILogger _logger;
         private readonly IUserManager _userManager;
 
-        public ActivityManager(
-            ILoggerFactory loggerFactory,
-            IActivityRepository repo,
-            IUserManager userManager)
+        public ActivityManager(IActivityRepository repo, IUserManager userManager)
         {
-            _logger = loggerFactory.CreateLogger(nameof(ActivityManager));
             _repo = repo;
             _userManager = userManager;
         }
 
+        public event EventHandler<GenericEventArgs<ActivityLogEntry>> EntryCreated;
+
         public void Create(ActivityLogEntry entry)
         {
             entry.Date = DateTime.UtcNow;
diff --git a/Emby.Server.Implementations/Activity/ActivityRepository.cs b/Emby.Server.Implementations/Activity/ActivityRepository.cs
index 7be72319ea..26fc229f73 100644
--- a/Emby.Server.Implementations/Activity/ActivityRepository.cs
+++ b/Emby.Server.Implementations/Activity/ActivityRepository.cs
@@ -17,11 +17,12 @@ namespace Emby.Server.Implementations.Activity
 {
     public class ActivityRepository : BaseSqliteRepository, IActivityRepository
     {
-        private static readonly CultureInfo _usCulture = CultureInfo.ReadOnly(new CultureInfo("en-US"));
+        private const string BaseActivitySelectText = "select Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity from ActivityLog";
+
         private readonly IFileSystem _fileSystem;
 
-        public ActivityRepository(ILoggerFactory loggerFactory, IServerApplicationPaths appPaths, IFileSystem fileSystem)
-            : base(loggerFactory.CreateLogger(nameof(ActivityRepository)))
+        public ActivityRepository(ILogger<ActivityRepository> logger, IServerApplicationPaths appPaths, IFileSystem fileSystem)
+            : base(logger)
         {
             DbFilePath = Path.Combine(appPaths.DataPath, "activitylog.db");
             _fileSystem = fileSystem;
@@ -76,8 +77,6 @@ namespace Emby.Server.Implementations.Activity
             }
         }
 
-        private const string BaseActivitySelectText = "select Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity from ActivityLog";
-
         public void Create(ActivityLogEntry entry)
         {
             if (entry == null)
@@ -87,32 +86,34 @@ namespace Emby.Server.Implementations.Activity
 
             using (var connection = GetConnection())
             {
-                connection.RunInTransaction(db =>
-                {
-                    using (var statement = db.PrepareStatement("insert into ActivityLog (Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) values (@Name, @Overview, @ShortOverview, @Type, @ItemId, @UserId, @DateCreated, @LogSeverity)"))
+                connection.RunInTransaction(
+                    db =>
                     {
-                        statement.TryBind("@Name", entry.Name);
+                        using (var statement = db.PrepareStatement("insert into ActivityLog (Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) values (@Name, @Overview, @ShortOverview, @Type, @ItemId, @UserId, @DateCreated, @LogSeverity)"))
+                        {
+                            statement.TryBind("@Name", entry.Name);
 
-                        statement.TryBind("@Overview", entry.Overview);
-                        statement.TryBind("@ShortOverview", entry.ShortOverview);
-                        statement.TryBind("@Type", entry.Type);
-                        statement.TryBind("@ItemId", entry.ItemId);
+                            statement.TryBind("@Overview", entry.Overview);
+                            statement.TryBind("@ShortOverview", entry.ShortOverview);
+                            statement.TryBind("@Type", entry.Type);
+                            statement.TryBind("@ItemId", entry.ItemId);
 
-                        if (entry.UserId.Equals(Guid.Empty))
-                        {
-                            statement.TryBindNull("@UserId");
-                        }
-                        else
-                        {
-                            statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
-                        }
+                            if (entry.UserId.Equals(Guid.Empty))
+                            {
+                                statement.TryBindNull("@UserId");
+                            }
+                            else
+                            {
+                                statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
+                            }
 
-                        statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
-                        statement.TryBind("@LogSeverity", entry.Severity.ToString());
+                            statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
+                            statement.TryBind("@LogSeverity", entry.Severity.ToString());
 
-                        statement.MoveNext();
-                    }
-                }, TransactionMode);
+                            statement.MoveNext();
+                        }
+                    },
+                    TransactionMode);
             }
         }
 
@@ -125,33 +126,35 @@ namespace Emby.Server.Implementations.Activity
 
             using (var connection = GetConnection())
             {
-                connection.RunInTransaction(db =>
-                {
-                    using (var statement = db.PrepareStatement("Update ActivityLog set Name=@Name,Overview=@Overview,ShortOverview=@ShortOverview,Type=@Type,ItemId=@ItemId,UserId=@UserId,DateCreated=@DateCreated,LogSeverity=@LogSeverity where Id=@Id"))
+                connection.RunInTransaction(
+                    db =>
                     {
-                        statement.TryBind("@Id", entry.Id);
+                        using (var statement = db.PrepareStatement("Update ActivityLog set Name=@Name,Overview=@Overview,ShortOverview=@ShortOverview,Type=@Type,ItemId=@ItemId,UserId=@UserId,DateCreated=@DateCreated,LogSeverity=@LogSeverity where Id=@Id"))
+                        {
+                            statement.TryBind("@Id", entry.Id);
 
-                        statement.TryBind("@Name", entry.Name);
-                        statement.TryBind("@Overview", entry.Overview);
-                        statement.TryBind("@ShortOverview", entry.ShortOverview);
-                        statement.TryBind("@Type", entry.Type);
-                        statement.TryBind("@ItemId", entry.ItemId);
+                            statement.TryBind("@Name", entry.Name);
+                            statement.TryBind("@Overview", entry.Overview);
+                            statement.TryBind("@ShortOverview", entry.ShortOverview);
+                            statement.TryBind("@Type", entry.Type);
+                            statement.TryBind("@ItemId", entry.ItemId);
 
-                        if (entry.UserId.Equals(Guid.Empty))
-                        {
-                            statement.TryBindNull("@UserId");
-                        }
-                        else
-                        {
-                            statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
-                        }
+                            if (entry.UserId.Equals(Guid.Empty))
+                            {
+                                statement.TryBindNull("@UserId");
+                            }
+                            else
+                            {
+                                statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
+                            }
 
-                        statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
-                        statement.TryBind("@LogSeverity", entry.Severity.ToString());
+                            statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
+                            statement.TryBind("@LogSeverity", entry.Severity.ToString());
 
-                        statement.MoveNext();
-                    }
-                }, TransactionMode);
+                            statement.MoveNext();
+                        }
+                    },
+                    TransactionMode);
             }
         }
 
@@ -164,6 +167,7 @@ namespace Emby.Server.Implementations.Activity
             {
                 whereClauses.Add("DateCreated>=@DateCreated");
             }
+
             if (hasUserId.HasValue)
             {
                 if (hasUserId.Value)
@@ -204,7 +208,7 @@ namespace Emby.Server.Implementations.Activity
 
             if (limit.HasValue)
             {
-                commandText += " LIMIT " + limit.Value.ToString(_usCulture);
+                commandText += " LIMIT " + limit.Value.ToString(CultureInfo.InvariantCulture);
             }
 
             var statementTexts = new[]
@@ -304,7 +308,7 @@ namespace Emby.Server.Implementations.Activity
             index++;
             if (reader[index].SQLiteType != SQLiteType.Null)
             {
-                info.Severity = (LogLevel)Enum.Parse(typeof(LogLevel), reader[index].ToString(), true);
+                info.Severity = Enum.Parse<LogLevel>(reader[index].ToString(), true);
             }
 
             return info;
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 49d3b4d6ae..76416392f1 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -841,7 +841,7 @@ namespace Emby.Server.Implementations
 
             var activityLogRepo = GetActivityLogRepository();
             serviceCollection.AddSingleton(activityLogRepo);
-            serviceCollection.AddSingleton<IActivityManager>(new ActivityManager(LoggerFactory, activityLogRepo, UserManager));
+            serviceCollection.AddSingleton<IActivityManager>(new ActivityManager(activityLogRepo, UserManager));
 
             var authContext = new AuthorizationContext(AuthenticationRepository, UserManager);
             serviceCollection.AddSingleton<IAuthorizationContext>(authContext);
diff --git a/Emby.Server.Implementations/Archiving/ZipClient.cs b/Emby.Server.Implementations/Archiving/ZipClient.cs
index 4a6e5cfd75..e01495e192 100644
--- a/Emby.Server.Implementations/Archiving/ZipClient.cs
+++ b/Emby.Server.Implementations/Archiving/ZipClient.cs
@@ -50,6 +50,7 @@ namespace Emby.Server.Implementations.Archiving
             }
         }
 
+        /// <inheritdoc />
         public void ExtractAllFromZip(Stream source, string targetPath, bool overwriteExistingFiles)
         {
             using (var reader = ZipReader.Open(source))
@@ -66,6 +67,7 @@ namespace Emby.Server.Implementations.Archiving
             }
         }
 
+        /// <inheritdoc />
         public void ExtractAllFromGz(Stream source, string targetPath, bool overwriteExistingFiles)
         {
             using (var reader = GZipReader.Open(source))
@@ -82,6 +84,7 @@ namespace Emby.Server.Implementations.Archiving
             }
         }
 
+        /// <inheritdoc />
         public void ExtractFirstFileFromGz(Stream source, string targetPath, string defaultFileName)
         {
             using (var reader = GZipReader.Open(source))
diff --git a/Emby.Server.Implementations/Channels/ChannelImageProvider.cs b/Emby.Server.Implementations/Channels/ChannelImageProvider.cs
index 62aeb9bcb9..cf56a5faef 100644
--- a/Emby.Server.Implementations/Channels/ChannelImageProvider.cs
+++ b/Emby.Server.Implementations/Channels/ChannelImageProvider.cs
@@ -20,6 +20,8 @@ namespace Emby.Server.Implementations.Channels
             _channelManager = channelManager;
         }
 
+        public string Name => "Channel Image Provider";
+
         public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
         {
             return GetChannel(item).GetSupportedChannelImages();
@@ -32,8 +34,6 @@ namespace Emby.Server.Implementations.Channels
             return channel.GetChannelImage(type, cancellationToken);
         }
 
-        public string Name => "Channel Image Provider";
-
         public bool Supports(BaseItem item)
         {
             return item is Channel;
diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs
index 6e1baddfed..8502af97a9 100644
--- a/Emby.Server.Implementations/Channels/ChannelManager.cs
+++ b/Emby.Server.Implementations/Channels/ChannelManager.cs
@@ -31,8 +31,6 @@ namespace Emby.Server.Implementations.Channels
 {
     public class ChannelManager : IChannelManager
     {
-        internal IChannel[] Channels { get; private set; }
-
         private readonly IUserManager _userManager;
         private readonly IUserDataManager _userDataManager;
         private readonly IDtoService _dtoService;
@@ -43,11 +41,16 @@ namespace Emby.Server.Implementations.Channels
         private readonly IJsonSerializer _jsonSerializer;
         private readonly IProviderManager _providerManager;
 
+        private readonly ConcurrentDictionary<string, Tuple<DateTime, List<MediaSourceInfo>>> _channelItemMediaInfo =
+            new ConcurrentDictionary<string, Tuple<DateTime, List<MediaSourceInfo>>>();
+
+        private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1);
+
         public ChannelManager(
             IUserManager userManager,
             IDtoService dtoService,
             ILibraryManager libraryManager,
-            ILoggerFactory loggerFactory,
+            ILogger<ChannelManager> logger,
             IServerConfigurationManager config,
             IFileSystem fileSystem,
             IUserDataManager userDataManager,
@@ -57,7 +60,7 @@ namespace Emby.Server.Implementations.Channels
             _userManager = userManager;
             _dtoService = dtoService;
             _libraryManager = libraryManager;
-            _logger = loggerFactory.CreateLogger(nameof(ChannelManager));
+            _logger = logger;
             _config = config;
             _fileSystem = fileSystem;
             _userDataManager = userDataManager;
@@ -65,6 +68,8 @@ namespace Emby.Server.Implementations.Channels
             _providerManager = providerManager;
         }
 
+        internal IChannel[] Channels { get; private set; }
+
         private static TimeSpan CacheLength => TimeSpan.FromHours(3);
 
         public void AddParts(IEnumerable<IChannel> channels)
@@ -85,8 +90,7 @@ namespace Emby.Server.Implementations.Channels
             var internalChannel = _libraryManager.GetItemById(item.ChannelId);
             var channel = Channels.FirstOrDefault(i => GetInternalChannelId(i.Name).Equals(internalChannel.Id));
 
-            var supportsDelete = channel as ISupportsDelete;
-            return supportsDelete != null && supportsDelete.CanDelete(item);
+            return channel is ISupportsDelete supportsDelete && supportsDelete.CanDelete(item);
         }
 
         public bool EnableMediaProbe(BaseItem item)
@@ -146,15 +150,13 @@ namespace Emby.Server.Implementations.Channels
                 {
                     try
                     {
-                        var hasAttributes = GetChannelProvider(i) as IHasFolderAttributes;
-
-                        return (hasAttributes != null && hasAttributes.Attributes.Contains("Recordings", StringComparer.OrdinalIgnoreCase)) == val;
+                        return (GetChannelProvider(i) is IHasFolderAttributes hasAttributes
+                            && hasAttributes.Attributes.Contains("Recordings", StringComparer.OrdinalIgnoreCase)) == val;
                     }
                     catch
                     {
                         return false;
                     }
-
                 }).ToList();
             }
 
@@ -171,7 +173,6 @@ namespace Emby.Server.Implementations.Channels
                     {
                         return false;
                     }
-
                 }).ToList();
             }
 
@@ -188,9 +189,9 @@ namespace Emby.Server.Implementations.Channels
                     {
                         return false;
                     }
-
                 }).ToList();
             }
+
             if (query.IsFavorite.HasValue)
             {
                 var val = query.IsFavorite.Value;
@@ -215,7 +216,6 @@ namespace Emby.Server.Implementations.Channels
                     {
                         return false;
                     }
-
                 }).ToList();
             }
 
@@ -226,6 +226,7 @@ namespace Emby.Server.Implementations.Channels
             {
                 all = all.Skip(query.StartIndex.Value).ToList();
             }
+
             if (query.Limit.HasValue)
             {
                 all = all.Take(query.Limit.Value).ToList();
@@ -256,11 +257,9 @@ namespace Emby.Server.Implementations.Channels
 
             var internalResult = GetChannelsInternal(query);
 
-            var dtoOptions = new DtoOptions()
-            {
-            };
+            var dtoOptions = new DtoOptions();
 
-            //TODO Fix The co-variant conversion (internalResult.Items) between Folder[] and BaseItem[], this can generate runtime issues.
+            // TODO Fix The co-variant conversion (internalResult.Items) between Folder[] and BaseItem[], this can generate runtime issues.
             var returnItems = _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user);
 
             var result = new QueryResult<BaseItemDto>
@@ -341,8 +340,8 @@ namespace Emby.Server.Implementations.Channels
                 }
                 catch
                 {
-
                 }
+
                 return;
             }
 
@@ -365,11 +364,9 @@ namespace Emby.Server.Implementations.Channels
             var channel = GetChannel(item.ChannelId);
             var channelPlugin = GetChannelProvider(channel);
 
-            var requiresCallback = channelPlugin as IRequiresMediaInfoCallback;
-
             IEnumerable<MediaSourceInfo> results;
 
-            if (requiresCallback != null)
+            if (channelPlugin is IRequiresMediaInfoCallback requiresCallback)
             {
                 results = await GetChannelItemMediaSourcesInternal(requiresCallback, item.ExternalId, cancellationToken)
                     .ConfigureAwait(false);
@@ -384,9 +381,6 @@ namespace Emby.Server.Implementations.Channels
                 .ToList();
         }
 
-        private readonly ConcurrentDictionary<string, Tuple<DateTime, List<MediaSourceInfo>>> _channelItemMediaInfo =
-            new ConcurrentDictionary<string, Tuple<DateTime, List<MediaSourceInfo>>>();
-
         private async Task<IEnumerable<MediaSourceInfo>> GetChannelItemMediaSourcesInternal(IRequiresMediaInfoCallback channel, string id, CancellationToken cancellationToken)
         {
             if (_channelItemMediaInfo.TryGetValue(id, out Tuple<DateTime, List<MediaSourceInfo>> cachedInfo))
@@ -444,18 +438,21 @@ namespace Emby.Server.Implementations.Channels
             {
                 isNew = true;
             }
+
             item.Path = path;
 
             if (!item.ChannelId.Equals(id))
             {
                 forceUpdate = true;
             }
+
             item.ChannelId = id;
 
             if (item.ParentId != parentFolderId)
             {
                 forceUpdate = true;
             }
+
             item.ParentId = parentFolderId;
 
             item.OfficialRating = GetOfficialRating(channelInfo.ParentalRating);
@@ -472,10 +469,12 @@ namespace Emby.Server.Implementations.Channels
                 _libraryManager.CreateItem(item, null);
             }
 
-            await item.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_fileSystem))
-            {
-                ForceSave = !isNew && forceUpdate
-            }, cancellationToken).ConfigureAwait(false);
+            await item.RefreshMetadata(
+                new MetadataRefreshOptions(new DirectoryService(_fileSystem))
+                {
+                    ForceSave = !isNew && forceUpdate
+                },
+                cancellationToken).ConfigureAwait(false);
 
             return item;
         }
@@ -509,12 +508,12 @@ namespace Emby.Server.Implementations.Channels
 
         public ChannelFeatures[] GetAllChannelFeatures()
         {
-            return _libraryManager.GetItemIds(new InternalItemsQuery
-            {
-                IncludeItemTypes = new[] { typeof(Channel).Name },
-                OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) }
-
-            }).Select(i => GetChannelFeatures(i.ToString("N", CultureInfo.InvariantCulture))).ToArray();
+            return _libraryManager.GetItemIds(
+                new InternalItemsQuery
+                {
+                    IncludeItemTypes = new[] { typeof(Channel).Name },
+                    OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) }
+                }).Select(i => GetChannelFeatures(i.ToString("N", CultureInfo.InvariantCulture))).ToArray();
         }
 
         public ChannelFeatures GetChannelFeatures(string id)
@@ -532,13 +531,13 @@ namespace Emby.Server.Implementations.Channels
 
         public bool SupportsExternalTransfer(Guid channelId)
         {
-            //var channel = GetChannel(channelId);
             var channelProvider = GetChannelProvider(channelId);
 
             return channelProvider.GetChannelFeatures().SupportsContentDownloading;
         }
 
-        public ChannelFeatures GetChannelFeaturesDto(Channel channel,
+        public ChannelFeatures GetChannelFeaturesDto(
+            Channel channel,
             IChannel provider,
             InternalChannelFeatures features)
         {
@@ -567,6 +566,7 @@ namespace Emby.Server.Implementations.Channels
             {
                 throw new ArgumentNullException(nameof(name));
             }
+
             return _libraryManager.GetNewItemId("Channel " + name, typeof(Channel));
         }
 
@@ -614,7 +614,7 @@ namespace Emby.Server.Implementations.Channels
             query.IsFolder = false;
 
             // hack for trailers, figure out a better way later
-            var sortByPremiereDate = channels.Length == 1 && channels[0].GetType().Name.IndexOf("Trailer") != -1;
+            var sortByPremiereDate = channels.Length == 1 && channels[0].GetType().Name.Contains("Trailer", StringComparison.Ordinal);
 
             if (sortByPremiereDate)
             {
@@ -640,10 +640,12 @@ namespace Emby.Server.Implementations.Channels
         {
             var internalChannel = await GetChannel(channel, cancellationToken).ConfigureAwait(false);
 
-            var query = new InternalItemsQuery();
-            query.Parent = internalChannel;
-            query.EnableTotalRecordCount = false;
-            query.ChannelIds = new Guid[] { internalChannel.Id };
+            var query = new InternalItemsQuery
+            {
+                Parent = internalChannel,
+                EnableTotalRecordCount = false,
+                ChannelIds = new Guid[] { internalChannel.Id }
+            };
 
             var result = await GetChannelItemsInternal(query, new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false);
 
@@ -651,13 +653,15 @@ namespace Emby.Server.Implementations.Channels
             {
                 if (item is Folder folder)
                 {
-                    await GetChannelItemsInternal(new InternalItemsQuery
-                    {
-                        Parent = folder,
-                        EnableTotalRecordCount = false,
-                        ChannelIds = new Guid[] { internalChannel.Id }
-
-                    }, new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false);
+                    await GetChannelItemsInternal(
+                        new InternalItemsQuery
+                        {
+                            Parent = folder,
+                            EnableTotalRecordCount = false,
+                            ChannelIds = new Guid[] { internalChannel.Id }
+                        },
+                        new SimpleProgress<double>(),
+                        cancellationToken).ConfigureAwait(false);
                 }
             }
         }
@@ -672,7 +676,8 @@ namespace Emby.Server.Implementations.Channels
 
             var parentItem = query.ParentId == Guid.Empty ? channel : _libraryManager.GetItemById(query.ParentId);
 
-            var itemsResult = await GetChannelItems(channelProvider,
+            var itemsResult = await GetChannelItems(
+                channelProvider,
                 query.User,
                 parentItem is Channel ? null : parentItem.ExternalId,
                 null,
@@ -684,13 +689,12 @@ namespace Emby.Server.Implementations.Channels
             {
                 query.Parent = channel;
             }
+
             query.ChannelIds = Array.Empty<Guid>();
 
             // Not yet sure why this is causing a problem
             query.GroupByPresentationUniqueKey = false;
 
-            //_logger.LogDebug("GetChannelItemsInternal");
-
             // null if came from cache
             if (itemsResult != null)
             {
@@ -707,12 +711,15 @@ namespace Emby.Server.Implementations.Channels
                     var deadItem = _libraryManager.GetItemById(deadId);
                     if (deadItem != null)
                     {
-                        _libraryManager.DeleteItem(deadItem, new DeleteOptions
-                        {
-                            DeleteFileLocation = false,
-                            DeleteFromExternalProvider = false
-
-                        }, parentItem, false);
+                        _libraryManager.DeleteItem(
+                            deadItem,
+                            new DeleteOptions
+                            {
+                                DeleteFileLocation = false,
+                                DeleteFromExternalProvider = false
+                            },
+                            parentItem,
+                            false);
                     }
                 }
             }
@@ -735,7 +742,6 @@ namespace Emby.Server.Implementations.Channels
             return result;
         }
 
-        private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1);
         private async Task<ChannelItemResult> GetChannelItems(IChannel channel,
             User user,
             string externalFolderId,
@@ -743,7 +749,7 @@ namespace Emby.Server.Implementations.Channels
             bool sortDescending,
             CancellationToken cancellationToken)
         {
-            var userId = user == null ? null : user.Id.ToString("N", CultureInfo.InvariantCulture);
+            var userId = user?.Id.ToString("N", CultureInfo.InvariantCulture);
 
             var cacheLength = CacheLength;
             var cachePath = GetChannelDataCachePath(channel, userId, externalFolderId, sortField, sortDescending);
@@ -761,11 +767,9 @@ namespace Emby.Server.Implementations.Channels
             }
             catch (FileNotFoundException)
             {
-
             }
             catch (IOException)
             {
-
             }
 
             await _resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
@@ -785,11 +789,9 @@ namespace Emby.Server.Implementations.Channels
                 }
                 catch (FileNotFoundException)
                 {
-
                 }
                 catch (IOException)
                 {
-
                 }
 
                 var query = new InternalChannelItemQuery
@@ -833,7 +835,8 @@ namespace Emby.Server.Implementations.Channels
             }
         }
 
-        private string GetChannelDataCachePath(IChannel channel,
+        private string GetChannelDataCachePath(
+            IChannel channel,
             string userId,
             string externalFolderId,
             ChannelItemSortField? sortField,
@@ -843,8 +846,7 @@ namespace Emby.Server.Implementations.Channels
 
             var userCacheKey = string.Empty;
 
-            var hasCacheKey = channel as IHasCacheKey;
-            if (hasCacheKey != null)
+            if (channel is IHasCacheKey hasCacheKey)
             {
                 userCacheKey = hasCacheKey.GetCacheKey(userId) ?? string.Empty;
             }
@@ -858,6 +860,7 @@ namespace Emby.Server.Implementations.Channels
             {
                 filename += "-sortField-" + sortField.Value;
             }
+
             if (sortDescending)
             {
                 filename += "-sortDescending";
@@ -865,7 +868,8 @@ namespace Emby.Server.Implementations.Channels
 
             filename = filename.GetMD5().ToString("N", CultureInfo.InvariantCulture);
 
-            return Path.Combine(_config.ApplicationPaths.CachePath,
+            return Path.Combine(
+                _config.ApplicationPaths.CachePath,
                 "channels",
                 channelId,
                 version,
@@ -981,7 +985,6 @@ namespace Emby.Server.Implementations.Channels
             {
                 item.RunTimeTicks = null;
             }
-
             else if (isNew || !enableMediaProbe)
             {
                 item.RunTimeTicks = info.RunTimeTicks;
@@ -1014,26 +1017,24 @@ namespace Emby.Server.Implementations.Channels
                 }
             }
 
-            var hasArtists = item as IHasArtist;
-            if (hasArtists != null)
+            if (item is IHasArtist hasArtists)
             {
                 hasArtists.Artists = info.Artists.ToArray();
             }
 
-            var hasAlbumArtists = item as IHasAlbumArtist;
-            if (hasAlbumArtists != null)
+            if (item is IHasAlbumArtist hasAlbumArtists)
             {
                 hasAlbumArtists.AlbumArtists = info.AlbumArtists.ToArray();
             }
 
-            var trailer = item as Trailer;
-            if (trailer != null)
+            if (item is Trailer trailer)
             {
                 if (!info.TrailerTypes.SequenceEqual(trailer.TrailerTypes))
                 {
                     _logger.LogDebug("Forcing update due to TrailerTypes {0}", item.Name);
                     forceUpdate = true;
                 }
+
                 trailer.TrailerTypes = info.TrailerTypes.ToArray();
             }
 
@@ -1057,6 +1058,7 @@ namespace Emby.Server.Implementations.Channels
                 forceUpdate = true;
                 _logger.LogDebug("Forcing update due to ChannelId {0}", item.Name);
             }
+
             item.ChannelId = internalChannelId;
 
             if (!item.ParentId.Equals(parentFolderId))
@@ -1064,16 +1066,17 @@ namespace Emby.Server.Implementations.Channels
                 forceUpdate = true;
                 _logger.LogDebug("Forcing update due to parent folder Id {0}", item.Name);
             }
+
             item.ParentId = parentFolderId;
 
-            var hasSeries = item as IHasSeries;
-            if (hasSeries != null)
+            if (item is IHasSeries hasSeries)
             {
                 if (!string.Equals(hasSeries.SeriesName, info.SeriesName, StringComparison.OrdinalIgnoreCase))
                 {
                     forceUpdate = true;
                     _logger.LogDebug("Forcing update due to SeriesName {0}", item.Name);
                 }
+
                 hasSeries.SeriesName = info.SeriesName;
             }
 
@@ -1082,24 +1085,23 @@ namespace Emby.Server.Implementations.Channels
                 forceUpdate = true;
                 _logger.LogDebug("Forcing update due to ExternalId {0}", item.Name);
             }
+
             item.ExternalId = info.Id;
 
-            var channelAudioItem = item as Audio;
-            if (channelAudioItem != null)
+            if (item is Audio channelAudioItem)
             {
                 channelAudioItem.ExtraType = info.ExtraType;
 
                 var mediaSource = info.MediaSources.FirstOrDefault();
-                item.Path = mediaSource == null ? null : mediaSource.Path;
+                item.Path = mediaSource?.Path;
             }
 
-            var channelVideoItem = item as Video;
-            if (channelVideoItem != null)
+            if (item is Video channelVideoItem)
             {
                 channelVideoItem.ExtraType = info.ExtraType;
 
                 var mediaSource = info.MediaSources.FirstOrDefault();
-                item.Path = mediaSource == null ? null : mediaSource.Path;
+                item.Path = mediaSource?.Path;
             }
 
             if (!string.IsNullOrEmpty(info.ImageUrl) && !item.HasImage(ImageType.Primary))
@@ -1156,7 +1158,7 @@ namespace Emby.Server.Implementations.Channels
                 }
             }
 
-            if (isNew || forceUpdate || item.DateLastRefreshed == default(DateTime))
+            if (isNew || forceUpdate || item.DateLastRefreshed == default)
             {
                 _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), RefreshPriority.Normal);
             }
diff --git a/Emby.Server.Implementations/Channels/ChannelPostScanTask.cs b/Emby.Server.Implementations/Channels/ChannelPostScanTask.cs
index 266d539d0a..250e9da649 100644
--- a/Emby.Server.Implementations/Channels/ChannelPostScanTask.cs
+++ b/Emby.Server.Implementations/Channels/ChannelPostScanTask.cs
@@ -14,14 +14,12 @@ namespace Emby.Server.Implementations.Channels
     public class ChannelPostScanTask
     {
         private readonly IChannelManager _channelManager;
-        private readonly IUserManager _userManager;
         private readonly ILogger _logger;
         private readonly ILibraryManager _libraryManager;
 
-        public ChannelPostScanTask(IChannelManager channelManager, IUserManager userManager, ILogger logger, ILibraryManager libraryManager)
+        public ChannelPostScanTask(IChannelManager channelManager, ILogger logger, ILibraryManager libraryManager)
         {
             _channelManager = channelManager;
-            _userManager = userManager;
             _logger = logger;
             _libraryManager = libraryManager;
         }
diff --git a/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs b/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs
index 367efcb134..e1d35f2b0e 100644
--- a/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs
+++ b/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs
@@ -7,29 +7,26 @@ using System.Threading.Tasks;
 using MediaBrowser.Common.Progress;
 using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Globalization;
 using MediaBrowser.Model.Tasks;
 using Microsoft.Extensions.Logging;
-using MediaBrowser.Model.Globalization;
 
 namespace Emby.Server.Implementations.Channels
 {
     public class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask
     {
         private readonly IChannelManager _channelManager;
-        private readonly IUserManager _userManager;
         private readonly ILogger _logger;
         private readonly ILibraryManager _libraryManager;
         private readonly ILocalizationManager _localization;
 
         public RefreshChannelsScheduledTask(
             IChannelManager channelManager,
-            IUserManager userManager,
             ILogger<RefreshChannelsScheduledTask> logger,
             ILibraryManager libraryManager,
             ILocalizationManager localization)
         {
             _channelManager = channelManager;
-            _userManager = userManager;
             _logger = logger;
             _libraryManager = libraryManager;
             _localization = localization;
@@ -63,7 +60,7 @@ namespace Emby.Server.Implementations.Channels
 
             await manager.RefreshChannels(new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false);
 
-            await new ChannelPostScanTask(_channelManager, _userManager, _logger, _libraryManager).Run(progress, cancellationToken)
+            await new ChannelPostScanTask(_channelManager, _logger, _libraryManager).Run(progress, cancellationToken)
                     .ConfigureAwait(false);
         }
 
@@ -72,7 +69,6 @@ namespace Emby.Server.Implementations.Channels
         {
             return new[]
             {
-
                 // Every so often
                 new TaskTriggerInfo
                 {
diff --git a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs
index 21ba0288ec..320552465e 100644
--- a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs
+++ b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs
@@ -46,9 +46,7 @@ namespace Emby.Server.Implementations.Collections
                 {
                     var subItem = i;
 
-                    var episode = subItem as Episode;
-
-                    if (episode != null)
+                    if (subItem is Episode episode)
                     {
                         var series = episode.Series;
                         if (series != null && series.HasImage(ImageType.Primary))
diff --git a/Emby.Server.Implementations/Collections/CollectionManager.cs b/Emby.Server.Implementations/Collections/CollectionManager.cs
index 3219528749..68bcc5a4f4 100644
--- a/Emby.Server.Implementations/Collections/CollectionManager.cs
+++ b/Emby.Server.Implementations/Collections/CollectionManager.cs
@@ -52,7 +52,9 @@ namespace Emby.Server.Implementations.Collections
         }
 
         public event EventHandler<CollectionCreatedEventArgs> CollectionCreated;
+
         public event EventHandler<CollectionModifiedEventArgs> ItemsAddedToCollection;
+
         public event EventHandler<CollectionModifiedEventArgs> ItemsRemovedFromCollection;
 
         private IEnumerable<Folder> FindFolders(string path)
@@ -109,9 +111,9 @@ namespace Emby.Server.Implementations.Collections
         {
             var folder = GetCollectionsFolder(false).Result;
 
-            return folder == null ?
-                new List<BoxSet>() :
-                folder.GetChildren(user, true).OfType<BoxSet>();
+            return folder == null
+                ? Enumerable.Empty<BoxSet>()
+                : folder.GetChildren(user, true).OfType<BoxSet>();
         }
 
         public BoxSet CreateCollection(CollectionCreationOptions options)
@@ -191,7 +193,6 @@ namespace Emby.Server.Implementations.Collections
         private void AddToCollection(Guid collectionId, IEnumerable<string> ids, bool fireEvent, MetadataRefreshOptions refreshOptions)
         {
             var collection = _libraryManager.GetItemById(collectionId) as BoxSet;
-
             if (collection == null)
             {
                 throw new ArgumentException("No collection exists with the supplied Id");
@@ -289,10 +290,13 @@ namespace Emby.Server.Implementations.Collections
             }
 
             collection.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
-            _providerManager.QueueRefresh(collection.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem))
-            {
-                ForceSave = true
-            }, RefreshPriority.High);
+            _providerManager.QueueRefresh(
+                collection.Id,
+                new MetadataRefreshOptions(new DirectoryService(_fileSystem))
+                {
+                    ForceSave = true
+                },
+                RefreshPriority.High);
 
             ItemsRemovedFromCollection?.Invoke(this, new CollectionModifiedEventArgs
             {
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs b/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs
index 6e903a18ef..3b36247a9f 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs
@@ -22,6 +22,10 @@ namespace Emby.Server.Implementations.LiveTv
 {
     public class LiveTvDtoService
     {
+        private const string InternalVersionNumber = "4";
+
+        private const string ServiceName = "Emby";
+
         private readonly ILogger _logger;
         private readonly IImageProcessor _imageProcessor;
 
@@ -32,13 +36,13 @@ namespace Emby.Server.Implementations.LiveTv
         public LiveTvDtoService(
             IDtoService dtoService,
             IImageProcessor imageProcessor,
-            ILoggerFactory loggerFactory,
+            ILogger<LiveTvDtoService> logger,
             IApplicationHost appHost,
             ILibraryManager libraryManager)
         {
             _dtoService = dtoService;
             _imageProcessor = imageProcessor;
-            _logger = loggerFactory.CreateLogger(nameof(LiveTvDtoService));
+            _logger = logger;
             _appHost = appHost;
             _libraryManager = libraryManager;
         }
@@ -161,7 +165,6 @@ namespace Emby.Server.Implementations.LiveTv
                 Limit = 1,
                 ImageTypes = new ImageType[] { ImageType.Thumb },
                 DtoOptions = new DtoOptions(false)
-
             }).FirstOrDefault();
 
             if (librarySeries != null)
@@ -179,6 +182,7 @@ namespace Emby.Server.Implementations.LiveTv
                         _logger.LogError(ex, "Error");
                     }
                 }
+
                 image = librarySeries.GetImageInfo(ImageType.Backdrop, 0);
                 if (image != null)
                 {
@@ -199,13 +203,12 @@ namespace Emby.Server.Implementations.LiveTv
 
             var program = _libraryManager.GetItemList(new InternalItemsQuery
             {
-                IncludeItemTypes = new string[] { typeof(LiveTvProgram).Name },
+                IncludeItemTypes = new string[] { nameof(LiveTvProgram) },
                 ExternalSeriesId = programSeriesId,
                 Limit = 1,
                 ImageTypes = new ImageType[] { ImageType.Primary },
                 DtoOptions = new DtoOptions(false),
                 Name = string.IsNullOrEmpty(programSeriesId) ? seriesName : null
-
             }).FirstOrDefault();
 
             if (program != null)
@@ -232,9 +235,10 @@ namespace Emby.Server.Implementations.LiveTv
                         try
                         {
                             dto.ParentBackdropImageTags = new string[]
-                        {
+                            {
                                 _imageProcessor.GetImageCacheTag(program, image)
-                        };
+                            };
+
                             dto.ParentBackdropItemId = program.Id.ToString("N", CultureInfo.InvariantCulture);
                         }
                         catch (Exception ex)
@@ -255,7 +259,6 @@ namespace Emby.Server.Implementations.LiveTv
                 Limit = 1,
                 ImageTypes = new ImageType[] { ImageType.Thumb },
                 DtoOptions = new DtoOptions(false)
-
             }).FirstOrDefault();
 
             if (librarySeries != null)
@@ -273,6 +276,7 @@ namespace Emby.Server.Implementations.LiveTv
                         _logger.LogError(ex, "Error");
                     }
                 }
+
                 image = librarySeries.GetImageInfo(ImageType.Backdrop, 0);
                 if (image != null)
                 {
@@ -298,7 +302,6 @@ namespace Emby.Server.Implementations.LiveTv
                 Limit = 1,
                 ImageTypes = new ImageType[] { ImageType.Primary },
                 DtoOptions = new DtoOptions(false)
-
             }).FirstOrDefault();
 
             if (program == null)
@@ -311,7 +314,6 @@ namespace Emby.Server.Implementations.LiveTv
                     ImageTypes = new ImageType[] { ImageType.Primary },
                     DtoOptions = new DtoOptions(false),
                     Name = string.IsNullOrEmpty(programSeriesId) ? seriesName : null
-
                 }).FirstOrDefault();
             }
 
@@ -396,8 +398,6 @@ namespace Emby.Server.Implementations.LiveTv
             return null;
         }
 
-        private const string InternalVersionNumber = "4";
-
         public Guid GetInternalChannelId(string serviceName, string externalId)
         {
             var name = serviceName + externalId + InternalVersionNumber;
@@ -405,7 +405,6 @@ namespace Emby.Server.Implementations.LiveTv
             return _libraryManager.GetNewItemId(name.ToLowerInvariant(), typeof(LiveTvChannel));
         }
 
-        private const string ServiceName = "Emby";
         public string GetInternalTimerId(string externalId)
         {
             var name = ServiceName + externalId + InternalVersionNumber;
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index b64fe8634c..bbc064a247 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -41,6 +41,10 @@ namespace Emby.Server.Implementations.LiveTv
     /// </summary>
     public class LiveTvManager : ILiveTvManager, IDisposable
     {
+        private const string ExternalServiceTag = "ExternalServiceId";
+
+        private const string EtagKey = "ProgramEtag";
+
         private readonly IServerConfigurationManager _config;
         private readonly ILogger _logger;
         private readonly IItemRepository _itemRepo;
@@ -91,7 +95,7 @@ namespace Emby.Server.Implementations.LiveTv
             _userDataManager = userDataManager;
             _channelManager = channelManager;
 
-            _tvDtoService = new LiveTvDtoService(dtoService, imageProcessor, loggerFactory, appHost, _libraryManager);
+            _tvDtoService = new LiveTvDtoService(dtoService, imageProcessor, loggerFactory.CreateLogger<LiveTvDtoService>(), appHost, _libraryManager);
         }
 
         public event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCancelled;
@@ -178,7 +182,6 @@ namespace Emby.Server.Implementations.LiveTv
             {
                 Name = i.Name,
                 Id = i.Type
-
             }).ToList();
         }
 
@@ -261,6 +264,7 @@ namespace Emby.Server.Implementations.LiveTv
                 var endTime = DateTime.UtcNow;
                 _logger.LogInformation("Live stream opened after {0}ms", (endTime - startTime).TotalMilliseconds);
             }
+
             info.RequiresClosing = true;
 
             var idPrefix = service.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture) + "_";
@@ -362,30 +366,37 @@ namespace Emby.Server.Implementations.LiveTv
                 {
                     stream.BitRate = null;
                 }
+
                 if (stream.Channels.HasValue && stream.Channels <= 0)
                 {
                     stream.Channels = null;
                 }
+
                 if (stream.AverageFrameRate.HasValue && stream.AverageFrameRate <= 0)
                 {
                     stream.AverageFrameRate = null;
                 }
+
                 if (stream.RealFrameRate.HasValue && stream.RealFrameRate <= 0)
                 {
                     stream.RealFrameRate = null;
                 }
+
                 if (stream.Width.HasValue && stream.Width <= 0)
                 {
                     stream.Width = null;
                 }
+
                 if (stream.Height.HasValue && stream.Height <= 0)
                 {
                     stream.Height = null;
                 }
+
                 if (stream.SampleRate.HasValue && stream.SampleRate <= 0)
                 {
                     stream.SampleRate = null;
                 }
+
                 if (stream.Level.HasValue && stream.Level <= 0)
                 {
                     stream.Level = null;
@@ -427,7 +438,6 @@ namespace Emby.Server.Implementations.LiveTv
             }
         }
 
-        private const string ExternalServiceTag = "ExternalServiceId";
         private LiveTvChannel GetChannel(ChannelInfo channelInfo, string serviceName, BaseItem parentFolder, CancellationToken cancellationToken)
         {
             var parentFolderId = parentFolder.Id;
@@ -456,6 +466,7 @@ namespace Emby.Server.Implementations.LiveTv
                 {
                     isNew = true;
                 }
+
                 item.Tags = channelInfo.Tags;
             }
 
@@ -463,6 +474,7 @@ namespace Emby.Server.Implementations.LiveTv
             {
                 isNew = true;
             }
+
             item.ParentId = parentFolderId;
 
             item.ChannelType = channelInfo.ChannelType;
@@ -472,24 +484,28 @@ namespace Emby.Server.Implementations.LiveTv
             {
                 forceUpdate = true;
             }
+
             item.SetProviderId(ExternalServiceTag, serviceName);
 
             if (!string.Equals(channelInfo.Id, item.ExternalId, StringComparison.Ordinal))
             {
                 forceUpdate = true;
             }
+
             item.ExternalId = channelInfo.Id;
 
             if (!string.Equals(channelInfo.Number, item.Number, StringComparison.Ordinal))
             {
                 forceUpdate = true;
             }
+
             item.Number = channelInfo.Number;
 
             if (!string.Equals(channelInfo.Name, item.Name, StringComparison.Ordinal))
             {
                 forceUpdate = true;
             }
+
             item.Name = channelInfo.Name;
 
             if (!item.HasImage(ImageType.Primary))
@@ -518,8 +534,6 @@ namespace Emby.Server.Implementations.LiveTv
             return item;
         }
 
-        private const string EtagKey = "ProgramEtag";
-
         private Tuple<LiveTvProgram, bool, bool> GetProgram(ProgramInfo info, Dictionary<Guid, LiveTvProgram> allExistingPrograms, LiveTvChannel channel, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
         {
             var id = _tvDtoService.GetInternalProgramId(info.Id);
diff --git a/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs b/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs
index 4424e044bb..c2dcb66d7c 100644
--- a/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs
+++ b/MediaBrowser.Controller/Persistence/IDisplayPreferencesRepository.cs
@@ -6,30 +6,34 @@ using MediaBrowser.Model.Entities;
 namespace MediaBrowser.Controller.Persistence
 {
     /// <summary>
-    /// Interface IDisplayPreferencesRepository
+    /// Interface IDisplayPreferencesRepository.
     /// </summary>
     public interface IDisplayPreferencesRepository : IRepository
     {
         /// <summary>
-        /// Saves display preferences for an item
+        /// Saves display preferences for an item.
         /// </summary>
         /// <param name="displayPreferences">The display preferences.</param>
         /// <param name="userId">The user id.</param>
         /// <param name="client">The client.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
-        /// <returns>Task.</returns>
-        void SaveDisplayPreferences(DisplayPreferences displayPreferences, string userId, string client,
-                                    CancellationToken cancellationToken);
+        void SaveDisplayPreferences(
+            DisplayPreferences displayPreferences,
+            string userId,
+            string client,
+            CancellationToken cancellationToken);
 
         /// <summary>
-        /// Saves all display preferences for a user
+        /// Saves all display preferences for a user.
         /// </summary>
         /// <param name="displayPreferences">The display preferences.</param>
         /// <param name="userId">The user id.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
-        /// <returns>Task.</returns>
-        void SaveAllDisplayPreferences(IEnumerable<DisplayPreferences> displayPreferences, Guid userId,
-                                    CancellationToken cancellationToken);
+        void SaveAllDisplayPreferences(
+            IEnumerable<DisplayPreferences> displayPreferences,
+            Guid userId,
+            CancellationToken cancellationToken);
+
         /// <summary>
         /// Gets the display preferences.
         /// </summary>
diff --git a/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs
index e30dd84dcd..29f417489a 100644
--- a/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs
+++ b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs
@@ -14,7 +14,7 @@ namespace MediaBrowser.Model.LiveTv
         public SeriesTimerInfoDto()
         {
             ImageTags = new Dictionary<ImageType, string>();
-            Days = new DayOfWeek[] { };
+            Days = Array.Empty<DayOfWeek>();
             Type = "SeriesTimer";
         }