diff --git a/lib/TweetLib.Browser.CEF/Data/ContextMenuActionRegistry.cs b/lib/TweetLib.Browser.CEF/Data/ContextMenuActionRegistry.cs
index d310fb2b..48279266 100644
--- a/lib/TweetLib.Browser.CEF/Data/ContextMenuActionRegistry.cs
+++ b/lib/TweetLib.Browser.CEF/Data/ContextMenuActionRegistry.cs
@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 
 namespace TweetLib.Browser.CEF.Data {
-	public abstract class ContextMenuActionRegistry<T> {
+	abstract class ContextMenuActionRegistry<T> {
 		private readonly Dictionary<T, Action> actions = new ();
 
 		protected abstract T NextId(int n);
diff --git a/lib/TweetLib.Browser.CEF/Logic/ContextMenuLogic.cs b/lib/TweetLib.Browser.CEF/Logic/ContextMenuLogic.cs
index 62ba5310..d9e42a82 100644
--- a/lib/TweetLib.Browser.CEF/Logic/ContextMenuLogic.cs
+++ b/lib/TweetLib.Browser.CEF/Logic/ContextMenuLogic.cs
@@ -28,7 +28,7 @@ public abstract class ContextMenuLogic {
 			206  // AddToDictionary
 		};
 
-		protected sealed class ContextMenuActionRegistry : ContextMenuActionRegistry<int> {
+		private protected sealed class ContextMenuActionRegistry : ContextMenuActionRegistry<int> {
 			private const int CommandUserFirst = 26500;
 
 			protected override int NextId(int n) {
diff --git a/lib/TweetLib.Browser.CEF/Logic/ResourceRequestHandlerLogic.cs b/lib/TweetLib.Browser.CEF/Logic/ResourceRequestHandlerLogic.cs
index 7c1bb524..0d59c10f 100644
--- a/lib/TweetLib.Browser.CEF/Logic/ResourceRequestHandlerLogic.cs
+++ b/lib/TweetLib.Browser.CEF/Logic/ResourceRequestHandlerLogic.cs
@@ -30,19 +30,16 @@ public bool OnBeforeResourceLoad(TRequest request, IDisposable callback) {
 			if (resourceRequestHandler != null) {
 				var result = resourceRequestHandler.Handle(requestAdapter.GetUrl(request), requestAdapter.GetResourceType(request));
 
-				switch (result) {
-					case RequestHandleResult.Redirect redirect:
-						requestAdapter.SetUrl(request, redirect.Url);
-						break;
-
-					case RequestHandleResult.Process process:
-						requestAdapter.SetHeader(request, "Accept-Encoding", "identity");
-						responseProcessors[requestAdapter.GetIdentifier(request)] = process.Processor;
-						break;
-
-					case RequestHandleResult.Cancel:
-						callback.Dispose();
-						return false;
+				if (result is RequestHandleResult.Redirect redirect) {
+					requestAdapter.SetUrl(request, redirect.Url);
+				}
+				else if (result is RequestHandleResult.Process process) {
+					requestAdapter.SetHeader(request, "Accept-Encoding", "identity");
+					responseProcessors[requestAdapter.GetIdentifier(request)] = process.Processor;
+				}
+				else if (result == RequestHandleResult.Cancel) {
+					callback.Dispose();
+					return false;
 				}
 			}
 
diff --git a/lib/TweetLib.Browser.CEF/Logic/SchemeResourceVisitor.cs b/lib/TweetLib.Browser.CEF/Logic/SchemeResourceVisitor.cs
index 4ed41243..70ba8549 100644
--- a/lib/TweetLib.Browser.CEF/Logic/SchemeResourceVisitor.cs
+++ b/lib/TweetLib.Browser.CEF/Logic/SchemeResourceVisitor.cs
@@ -6,11 +6,11 @@
 using TweetLib.Browser.Request;
 
 namespace TweetLib.Browser.CEF.Logic {
-	internal abstract class SchemeResourceVisitor {
+	abstract class SchemeResourceVisitor {
 		protected static readonly SchemeResource.Status FileIsEmpty = new (HttpStatusCode.NoContent, "File is empty.");
 	}
 
-	internal sealed class SchemeResourceVisitor<TResourceHandler> : SchemeResourceVisitor, ISchemeResourceVisitor<TResourceHandler> {
+	sealed class SchemeResourceVisitor<TResourceHandler> : SchemeResourceVisitor, ISchemeResourceVisitor<TResourceHandler> {
 		private readonly IResourceHandlerFactory<TResourceHandler> factory;
 
 		public SchemeResourceVisitor(IResourceHandlerFactory<TResourceHandler> factory) {
diff --git a/lib/TweetLib.Browser/Interfaces/IResourceProvider.cs b/lib/TweetLib.Browser/Interfaces/IResourceProvider.cs
deleted file mode 100644
index 71eaa48b..00000000
--- a/lib/TweetLib.Browser/Interfaces/IResourceProvider.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using System.Net;
-
-namespace TweetLib.Browser.Interfaces {
-	public interface IResourceProvider<T> {
-		T Status(HttpStatusCode code, string message);
-		T File(byte[] contents, string extension);
-	}
-}
diff --git a/lib/TweetLib.Browser/Request/RequestHandleResult.cs b/lib/TweetLib.Browser/Request/RequestHandleResult.cs
index a905528b..c0732138 100644
--- a/lib/TweetLib.Browser/Request/RequestHandleResult.cs
+++ b/lib/TweetLib.Browser/Request/RequestHandleResult.cs
@@ -1,7 +1,9 @@
 using TweetLib.Browser.Interfaces;
 
 namespace TweetLib.Browser.Request {
-	public abstract class RequestHandleResult {
+	public class RequestHandleResult {
+		public static RequestHandleResult Cancel { get; } = new ();
+		
 		private RequestHandleResult() {}
 
 		public sealed class Redirect : RequestHandleResult {
@@ -19,11 +21,5 @@ public Process(IResponseProcessor processor) {
 				Processor = processor;
 			}
 		}
-
-		public sealed class Cancel : RequestHandleResult {
-			public static Cancel Instance { get; } = new ();
-
-			private Cancel() {}
-		}
 	}
 }
diff --git a/lib/TweetLib.Core/App.cs b/lib/TweetLib.Core/App.cs
index d67961a4..e871d2d4 100644
--- a/lib/TweetLib.Core/App.cs
+++ b/lib/TweetLib.Core/App.cs
@@ -17,22 +17,23 @@ public static class App {
 		public static readonly string ProgramPath = AppDomain.CurrentDomain.BaseDirectory;
 		public static readonly bool IsPortable = Setup.IsPortable;
 
-		public static readonly string ResourcesPath = Path.Combine(ProgramPath, "resources");
-		public static readonly string PluginPath    = Path.Combine(ProgramPath, "plugins");
-		public static readonly string GuidePath     = Path.Combine(ProgramPath, "guide");
+		internal static readonly string ResourcesPath = Path.Combine(ProgramPath, "resources");
+		internal static readonly string PluginPath    = Path.Combine(ProgramPath, "plugins");
+		internal static readonly string GuidePath     = Path.Combine(ProgramPath, "guide");
 
 		public static readonly string StoragePath = IsPortable ? Path.Combine(ProgramPath, "portable", "storage") : GetDataFolder();
+		public static readonly string LogoPath    = Path.Combine(ResourcesPath, "images/logo.png");
 
 		public static Logger Logger               { get; } = new (Path.Combine(StoragePath, "TD_Log.txt"), Setup.IsDebugLogging);
 		public static ConfigManager ConfigManager { get; } = Setup.CreateConfigManager(StoragePath);
 
 		public static IAppErrorHandler ErrorHandler     { get; } = Validate(Builder.ErrorHandler, nameof(Builder.ErrorHandler));
 		public static IAppSystemHandler SystemHandler   { get; } = Validate(Builder.SystemHandler, nameof(Builder.SystemHandler));
-		public static IAppMessageDialogs MessageDialogs { get; } = Validate(Builder.MessageDialogs, nameof(Builder.MessageDialogs));
-		public static IAppFileDialogs? FileDialogs      { get; } = Builder.FileDialogs;
-
+		
+		internal static IAppMessageDialogs MessageDialogs { get; } = Validate(Builder.MessageDialogs, nameof(Builder.MessageDialogs));
+		internal static IAppFileDialogs? FileDialogs      { get; } = Builder.FileDialogs;
+		
 		internal static IAppUserConfiguration UserConfiguration => ConfigManager.User;
-		internal static IAppSystemConfiguration SystemConfiguration => ConfigManager.System;
 
 		private static string GetDataFolder() {
 			string? custom = Setup.CustomDataFolder;
@@ -75,7 +76,7 @@ internal static void Launch() {
 
 			WebUtils.DefaultUserAgent = Lib.BrandName + " " + Version.Tag;
 
-			if (SystemConfiguration.UseSystemProxyForAllConnections) {
+			if (ConfigManager.System.UseSystemProxyForAllConnections) {
 				WebUtils.EnableSystemProxy();
 			}
 
diff --git a/lib/TweetLib.Core/Features/Notifications/DesktopNotification.cs b/lib/TweetLib.Core/Features/Notifications/DesktopNotification.cs
index 59f01225..9dce895f 100644
--- a/lib/TweetLib.Core/Features/Notifications/DesktopNotification.cs
+++ b/lib/TweetLib.Core/Features/Notifications/DesktopNotification.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using System.Text;
 using TweetLib.Utils.Data;
 
@@ -46,7 +47,7 @@ public int GetDisplayDuration(int value) {
 			return 2000 + Math.Max(1000, value * characters);
 		}
 
-		public string GenerateHtml(string bodyClasses, string? headLayout, string? customStyles, IEnumerable<InjectedString> injections, string[] scripts) { // TODO
+		internal string GenerateHtml(string bodyClasses, string? headLayout, string? customStyles, IEnumerable<InjectedString> injections, string[] scripts) { // TODO
 			headLayout ??= DefaultHeadLayout;
 			customStyles ??= string.Empty;
 
@@ -71,12 +72,7 @@ public string GenerateHtml(string bodyClasses, string? headLayout, string? custo
 			build.Append("<tweetduck-script-placeholder></body></html>");
 
 			string result = build.ToString();
-
-			foreach (var injection in injections) {
-				result = injection.InjectInto(result);
-			}
-
-			return result.Replace("<tweetduck-script-placeholder>", GenerateScripts(scripts));
+			return injections.Aggregate(result, static (current, injection) => injection.InjectInto(current)).Replace("<tweetduck-script-placeholder>", GenerateScripts(scripts));
 		}
 
 		private string GenerateScripts(string[] scripts) {
diff --git a/lib/TweetLib.Core/Features/Notifications/NotificationBrowser.cs b/lib/TweetLib.Core/Features/Notifications/NotificationBrowser.cs
index 360af353..2547aa65 100644
--- a/lib/TweetLib.Core/Features/Notifications/NotificationBrowser.cs
+++ b/lib/TweetLib.Core/Features/Notifications/NotificationBrowser.cs
@@ -13,7 +13,7 @@ internal static void SetNotificationLayout(string? fontSize, string? headLayout)
 		}
 
 		public static string? FontSize { get; private set; }
-		public static string? HeadLayout { get; private set; }
+		private static string? HeadLayout { get; set; }
 
 		private NotificationBrowser(IBrowserComponent browserComponent, Func<NotificationBrowser, BrowserSetup> setup) : base(browserComponent, setup) {}
 
diff --git a/lib/TweetLib.Core/Features/Plugins/Config/PluginConfig.cs b/lib/TweetLib.Core/Features/Plugins/Config/PluginConfig.cs
index fd0ee996..7cc95db9 100644
--- a/lib/TweetLib.Core/Features/Plugins/Config/PluginConfig.cs
+++ b/lib/TweetLib.Core/Features/Plugins/Config/PluginConfig.cs
@@ -7,7 +7,7 @@ namespace TweetLib.Core.Features.Plugins.Config {
 	public sealed class PluginConfig : IConfigObject<PluginConfig> {
 		internal IEnumerable<string> DisabledPlugins => disabled;
 
-		public event EventHandler<PluginChangedStateEventArgs>? PluginChangedState;
+		internal event EventHandler<PluginChangedStateEventArgs>? PluginChangedState;
 
 		private readonly HashSet<string> defaultDisabled;
 		private readonly HashSet<string> disabled;
diff --git a/lib/TweetLib.Core/Features/Plugins/Config/PluginConfigInstance.cs b/lib/TweetLib.Core/Features/Plugins/Config/PluginConfigInstance.cs
index b80b1b97..f6c2ac40 100644
--- a/lib/TweetLib.Core/Features/Plugins/Config/PluginConfigInstance.cs
+++ b/lib/TweetLib.Core/Features/Plugins/Config/PluginConfigInstance.cs
@@ -6,12 +6,11 @@
 
 namespace TweetLib.Core.Features.Plugins.Config {
 	sealed class PluginConfigInstance : IConfigInstance {
-		public PluginConfig Instance { get; }
-
+		private readonly PluginConfig instance;
 		private readonly string filename;
 
 		public PluginConfigInstance(string filename, PluginConfig instance) {
-			this.Instance = instance;
+			this.instance = instance;
 			this.filename = filename;
 		}
 
@@ -27,7 +26,7 @@ public void Load() {
 						newDisabled.Add(line);
 					}
 
-					Instance.Reset(newDisabled);
+					instance.Reset(newDisabled);
 				}
 			} catch (FileNotFoundException) {
 				// ignore
@@ -43,7 +42,7 @@ public void Save() {
 				using var writer = new StreamWriter(new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None), Encoding.UTF8);
 				writer.WriteLine("#Disabled");
 
-				foreach (string identifier in Instance.DisabledPlugins) {
+				foreach (string identifier in instance.DisabledPlugins) {
 					writer.WriteLine(identifier);
 				}
 			} catch (Exception e) {
@@ -58,7 +57,7 @@ public void Reload() {
 		public void Reset() {
 			try {
 				File.Delete(filename);
-				Instance.ResetToDefault();
+				instance.ResetToDefault();
 			} catch (Exception e) {
 				OnException("Could not delete the plugin configuration file.", e);
 				return;
diff --git a/lib/TweetLib.Core/Features/Plugins/Enums/PluginEnvironment.cs b/lib/TweetLib.Core/Features/Plugins/Enums/PluginEnvironment.cs
index 281906b3..b500013c 100644
--- a/lib/TweetLib.Core/Features/Plugins/Enums/PluginEnvironment.cs
+++ b/lib/TweetLib.Core/Features/Plugins/Enums/PluginEnvironment.cs
@@ -2,12 +2,12 @@
 using System.Collections.Generic;
 
 namespace TweetLib.Core.Features.Plugins.Enums {
-	public enum PluginEnvironment {
+	enum PluginEnvironment {
 		Browser,
 		Notification
 	}
 
-	internal static class PluginEnvironments {
+	static class PluginEnvironments {
 		public static IEnumerable<PluginEnvironment> All { get; } = new PluginEnvironment[] {
 			PluginEnvironment.Browser,
 			PluginEnvironment.Notification
diff --git a/lib/TweetLib.Core/Features/Plugins/Enums/PluginGroup.cs b/lib/TweetLib.Core/Features/Plugins/Enums/PluginGroup.cs
index 7190a094..4716079a 100644
--- a/lib/TweetLib.Core/Features/Plugins/Enums/PluginGroup.cs
+++ b/lib/TweetLib.Core/Features/Plugins/Enums/PluginGroup.cs
@@ -7,7 +7,7 @@ public enum PluginGroup {
 		Custom
 	}
 
-	internal static class PluginGroups {
+	static class PluginGroups {
 		public static IEnumerable<PluginGroup> All { get; } = new PluginGroup[] {
 			PluginGroup.Official,
 			PluginGroup.Custom
diff --git a/lib/TweetLib.Core/Features/Plugins/Events/PluginChangedStateEventArgs.cs b/lib/TweetLib.Core/Features/Plugins/Events/PluginChangedStateEventArgs.cs
index 16fbf620..414b5bbe 100644
--- a/lib/TweetLib.Core/Features/Plugins/Events/PluginChangedStateEventArgs.cs
+++ b/lib/TweetLib.Core/Features/Plugins/Events/PluginChangedStateEventArgs.cs
@@ -1,7 +1,7 @@
 using System;
 
 namespace TweetLib.Core.Features.Plugins.Events {
-	public sealed class PluginChangedStateEventArgs : EventArgs {
+	internal sealed class PluginChangedStateEventArgs : EventArgs {
 		public Plugin Plugin { get; }
 		public bool IsEnabled { get; }
 
diff --git a/lib/TweetLib.Core/Features/Plugins/Events/PluginErrorEventArgs.cs b/lib/TweetLib.Core/Features/Plugins/Events/PluginErrorEventArgs.cs
index b1b9bb75..14106866 100644
--- a/lib/TweetLib.Core/Features/Plugins/Events/PluginErrorEventArgs.cs
+++ b/lib/TweetLib.Core/Features/Plugins/Events/PluginErrorEventArgs.cs
@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 
 namespace TweetLib.Core.Features.Plugins.Events {
-	public sealed class PluginErrorEventArgs : EventArgs {
+	internal sealed class PluginErrorEventArgs : EventArgs {
 		public bool HasErrors => Errors.Count > 0;
 
 		public IList<string> Errors { get; }
diff --git a/lib/TweetLib.Core/Features/Plugins/Plugin.cs b/lib/TweetLib.Core/Features/Plugins/Plugin.cs
index 7562ba6f..7caee371 100644
--- a/lib/TweetLib.Core/Features/Plugins/Plugin.cs
+++ b/lib/TweetLib.Core/Features/Plugins/Plugin.cs
@@ -17,31 +17,32 @@ public sealed class Plugin {
 		public string Author { get; }
 		public string Version { get; }
 		public string Website { get; }
-		public string ConfigFile { get; }
-		public string ConfigDefault { get; }
 		public Version RequiredVersion { get; }
 
 		public bool CanRun { get; }
 
-		public bool HasConfig {
-			get => ConfigFile.Length > 0 && GetFullPathIfSafe(PluginFolder.Data, ConfigFile).Length > 0;
+		internal bool HasConfig {
+			get => configFile.Length > 0 && GetFullPathIfSafe(PluginFolder.Data, configFile).Length > 0;
 		}
 
-		public string ConfigPath {
-			get => HasConfig ? Path.Combine(GetPluginFolder(PluginFolder.Data), ConfigFile) : string.Empty;
+		internal string ConfigPath {
+			get => HasConfig ? Path.Combine(GetPluginFolder(PluginFolder.Data), configFile) : string.Empty;
 		}
 
-		public bool HasDefaultConfig {
-			get => ConfigDefault.Length > 0 && GetFullPathIfSafe(PluginFolder.Root, ConfigDefault).Length > 0;
+		private bool HasDefaultConfig {
+			get => configDefault.Length > 0 && GetFullPathIfSafe(PluginFolder.Root, configDefault).Length > 0;
 		}
 
-		public string DefaultConfigPath {
-			get => HasDefaultConfig ? Path.Combine(GetPluginFolder(PluginFolder.Root), ConfigDefault) : string.Empty;
+		private string DefaultConfigPath {
+			get => HasDefaultConfig ? Path.Combine(GetPluginFolder(PluginFolder.Root), configDefault) : string.Empty;
 		}
 
 		private readonly string pathRoot;
 		private readonly string pathData;
 		private readonly ISet<PluginEnvironment> environments;
+		
+		private readonly string configFile;
+		private readonly string configDefault;
 
 		private Plugin(PluginGroup group, string identifier, string pathRoot, string pathData, Builder builder) {
 			this.pathRoot = pathRoot;
@@ -56,18 +57,18 @@ private Plugin(PluginGroup group, string identifier, string pathRoot, string pat
 			this.Author = builder.Author;
 			this.Version = builder.Version;
 			this.Website = builder.Website;
-			this.ConfigFile = builder.ConfigFile;
-			this.ConfigDefault = builder.ConfigDefault;
+			this.configFile = builder.ConfigFile;
+			this.configDefault = builder.ConfigDefault;
 			this.RequiredVersion = builder.RequiredVersion;
 
 			this.CanRun = AppVersion >= RequiredVersion;
 		}
 
-		public bool HasEnvironment(PluginEnvironment environment) {
+		internal bool HasEnvironment(PluginEnvironment environment) {
 			return environments.Contains(environment);
 		}
 
-		public string GetScriptPath(PluginEnvironment environment) {
+		internal string GetScriptPath(PluginEnvironment environment) {
 			return environments.Contains(environment) ? Path.Combine(pathRoot, environment.GetPluginScriptFile()) : string.Empty;
 		}
 
@@ -79,7 +80,7 @@ public string GetPluginFolder(PluginFolder folder) {
 			};
 		}
 
-		public string GetFullPathIfSafe(PluginFolder folder, string relativePath) {
+		internal string GetFullPathIfSafe(PluginFolder folder, string relativePath) {
 			string rootFolder = GetPluginFolder(folder);
 			return FileUtils.ResolveRelativePathSafely(rootFolder, relativePath);
 		}
@@ -98,7 +99,7 @@ public override bool Equals(object obj) {
 
 		// Builder
 
-		public sealed class Builder {
+		internal sealed class Builder {
 			private static readonly Version DefaultRequiredVersion = new (0, 0, 0, 0);
 
 			public string Name             { get; set; } = string.Empty;
diff --git a/lib/TweetLib.Core/Features/Plugins/PluginLoader.cs b/lib/TweetLib.Core/Features/Plugins/PluginLoader.cs
index 71401462..d8faf0dc 100644
--- a/lib/TweetLib.Core/Features/Plugins/PluginLoader.cs
+++ b/lib/TweetLib.Core/Features/Plugins/PluginLoader.cs
@@ -7,7 +7,7 @@
 using TweetLib.Utils.Data;
 
 namespace TweetLib.Core.Features.Plugins {
-	internal static class PluginLoader {
+	static class PluginLoader {
 		private static readonly string[] EndTag = { "[END]" };
 
 		public static IEnumerable<Result<Plugin>> AllInFolder(string pluginFolder, string pluginDataFolder, PluginGroup group) {
@@ -38,7 +38,7 @@ public static IEnumerable<Result<Plugin>> AllInFolder(string pluginFolder, strin
 			}
 		}
 
-		public static Plugin FromFolder(string name, string pathRoot, string pathData, PluginGroup group) {
+		private static Plugin FromFolder(string name, string pathRoot, string pathData, PluginGroup group) {
 			Plugin.Builder builder = new Plugin.Builder(group, name, pathRoot, pathData);
 
 			foreach (var environment in Directory.EnumerateFiles(pathRoot, "*.js", SearchOption.TopDirectoryOnly).Select(Path.GetFileName).Select(EnvironmentFromFileName)) {
diff --git a/lib/TweetLib.Core/Features/Plugins/PluginManager.cs b/lib/TweetLib.Core/Features/Plugins/PluginManager.cs
index 066c482c..12cb7495 100644
--- a/lib/TweetLib.Core/Features/Plugins/PluginManager.cs
+++ b/lib/TweetLib.Core/Features/Plugins/PluginManager.cs
@@ -18,15 +18,15 @@ public sealed class PluginManager {
 		public string PluginFolder { get; }
 		public string PluginDataFolder { get; }
 
-		public event EventHandler<PluginErrorEventArgs>? Reloaded;
-		public event EventHandler<PluginErrorEventArgs>? Executed;
+		internal event EventHandler<PluginErrorEventArgs>? Reloaded;
+		internal event EventHandler<PluginErrorEventArgs>? Executed;
 
 		internal readonly PluginBridge bridge;
 		private IScriptExecutor? browserExecutor;
 
 		private readonly HashSet<Plugin> plugins = new ();
 
-		public PluginManager(PluginConfig config, string pluginFolder, string pluginDataFolder) {
+		internal PluginManager(PluginConfig config, string pluginFolder, string pluginDataFolder) {
 			this.Config = config;
 			this.Config.PluginChangedState += Config_PluginChangedState;
 			this.PluginFolder = pluginFolder;
diff --git a/lib/TweetLib.Core/Features/Plugins/PluginScriptGenerator.cs b/lib/TweetLib.Core/Features/Plugins/PluginScriptGenerator.cs
index dc7d96d6..a008f8f4 100644
--- a/lib/TweetLib.Core/Features/Plugins/PluginScriptGenerator.cs
+++ b/lib/TweetLib.Core/Features/Plugins/PluginScriptGenerator.cs
@@ -3,7 +3,7 @@
 using TweetLib.Core.Features.Plugins.Enums;
 
 namespace TweetLib.Core.Features.Plugins {
-	internal static class PluginScriptGenerator {
+	static class PluginScriptGenerator {
 		public static string GenerateConfig(PluginConfig config) {
 			return "window.TD_PLUGINS_DISABLE = [" + string.Join(",", config.DisabledPlugins.Select(static id => '"' + id + '"')) + "]";
 		}
diff --git a/lib/TweetLib.Core/Features/PropertyObjectScript.cs b/lib/TweetLib.Core/Features/PropertyObjectScript.cs
index 946145f4..f5449a29 100644
--- a/lib/TweetLib.Core/Features/PropertyObjectScript.cs
+++ b/lib/TweetLib.Core/Features/PropertyObjectScript.cs
@@ -3,8 +3,8 @@
 using TweetLib.Core.Features.Twitter;
 
 namespace TweetLib.Core.Features {
-	public static class PropertyObjectScript {
-		public enum Environment {
+	static class PropertyObjectScript {
+		internal enum Environment {
 			Browser,
 			Notification
 		}
diff --git a/lib/TweetLib.Core/Features/TweetDeck/TweetDeckBrowser.cs b/lib/TweetLib.Core/Features/TweetDeck/TweetDeckBrowser.cs
index c8a2f447..6c968fe1 100644
--- a/lib/TweetLib.Core/Features/TweetDeck/TweetDeckBrowser.cs
+++ b/lib/TweetLib.Core/Features/TweetDeck/TweetDeckBrowser.cs
@@ -247,10 +247,10 @@ private sealed class ResourceRequestHandler : BaseResourceRequestHandler {
 						return new RequestHandleResult.Process(VendorScriptProcessor.Instance);
 
 					case ResourceType.Script when url.Contains("analytics."):
-						return RequestHandleResult.Cancel.Instance;
+						return RequestHandleResult.Cancel;
 
 					case ResourceType.Xhr when url.Contains(UrlVersionCheck):
-						return RequestHandleResult.Cancel.Instance;
+						return RequestHandleResult.Cancel;
 
 					case ResourceType.Xhr when url.Contains("://api.twitter.com/") && url.Contains("include_entities=1") && !url.Contains("&include_ext_has_nft_avatar=1"):
 						return new RequestHandleResult.Redirect(url.Replace("include_entities=1", "include_entities=1&include_ext_has_nft_avatar=1"));
diff --git a/lib/TweetLib.Core/Features/Twitter/TwitterUrls.cs b/lib/TweetLib.Core/Features/Twitter/TwitterUrls.cs
index ef1e620c..47f75ab3 100644
--- a/lib/TweetLib.Core/Features/Twitter/TwitterUrls.cs
+++ b/lib/TweetLib.Core/Features/Twitter/TwitterUrls.cs
@@ -1,9 +1,11 @@
 using System;
+using System.Diagnostics.CodeAnalysis;
 using System.IO;
 using System.Text.RegularExpressions;
 using TweetLib.Utils.Static;
 
 namespace TweetLib.Core.Features.Twitter {
+	[SuppressMessage("ReSharper", "MemberCanBeInternal")]
 	public static class TwitterUrls {
 		public const string TweetDeck = "https://tweetdeck.twitter.com";
 		private const string TwitterTrackingUrl = "t.co";
diff --git a/lib/TweetLib.Core/Systems/Configuration/FileConfigInstance.cs b/lib/TweetLib.Core/Systems/Configuration/FileConfigInstance.cs
index a26a34df..a92ae392 100644
--- a/lib/TweetLib.Core/Systems/Configuration/FileConfigInstance.cs
+++ b/lib/TweetLib.Core/Systems/Configuration/FileConfigInstance.cs
@@ -4,8 +4,7 @@
 
 namespace TweetLib.Core.Systems.Configuration {
 	sealed class FileConfigInstance<T> : IConfigInstance where T : IConfigObject<T> {
-		public T Instance { get; }
-
+		private readonly T instance;
 		private readonly SimpleObjectSerializer<T> serializer;
 
 		private readonly string filenameMain;
@@ -13,7 +12,7 @@ sealed class FileConfigInstance<T> : IConfigInstance where T : IConfigObject<T>
 		private readonly string identifier;
 
 		public FileConfigInstance(string filename, T instance, string identifier, TypeConverterRegistry converterRegistry) {
-			this.Instance = instance;
+			this.instance = instance;
 			this.serializer = new SimpleObjectSerializer<T>(converterRegistry);
 
 			this.filenameMain = filename ?? throw new ArgumentNullException(nameof(filename), "Config file name must not be null!");
@@ -22,7 +21,7 @@ public FileConfigInstance(string filename, T instance, string identifier, TypeCo
 		}
 
 		private void LoadInternal(bool backup) {
-			serializer.Read(backup ? filenameBackup : filenameMain, Instance);
+			serializer.Read(backup ? filenameBackup : filenameMain, instance);
 		}
 
 		public void Load() {
@@ -64,7 +63,7 @@ public void Save() {
 					File.Move(filenameMain, filenameBackup);
 				}
 
-				serializer.Write(filenameMain, Instance);
+				serializer.Write(filenameMain, instance);
 			} catch (SerializationSoftException e) {
 				OnException($"{e.Errors.Count} error{(e.Errors.Count == 1 ? " was" : "s were")} encountered while saving the configuration file for {identifier}.", e);
 			} catch (Exception e) {
@@ -77,7 +76,7 @@ public void Reload() {
 				LoadInternal(false);
 			} catch (FileNotFoundException) {
 				try {
-					serializer.Write(filenameMain, Instance.ConstructWithDefaults());
+					serializer.Write(filenameMain, instance.ConstructWithDefaults());
 					LoadInternal(false);
 				} catch (Exception e) {
 					OnException($"Could not regenerate the configuration file for {identifier}.", e);
diff --git a/lib/TweetLib.Core/Systems/Dialogs/Dialogs.cs b/lib/TweetLib.Core/Systems/Dialogs/Dialogs.cs
index bfd1f6db..0c63c033 100644
--- a/lib/TweetLib.Core/Systems/Dialogs/Dialogs.cs
+++ b/lib/TweetLib.Core/Systems/Dialogs/Dialogs.cs
@@ -1,5 +1,5 @@
 namespace TweetLib.Core.Systems.Dialogs {
-	public static class Dialogs {
+	internal static class Dialogs {
 		public const string OK = "OK";
 	}
 }
diff --git a/lib/TweetLib.Core/Systems/Dialogs/FileDialogFilter.cs b/lib/TweetLib.Core/Systems/Dialogs/FileDialogFilter.cs
index 80ca2da5..bd518e5c 100644
--- a/lib/TweetLib.Core/Systems/Dialogs/FileDialogFilter.cs
+++ b/lib/TweetLib.Core/Systems/Dialogs/FileDialogFilter.cs
@@ -5,7 +5,7 @@ public sealed class FileDialogFilter {
 		public string Name { get; }
 		public IReadOnlyList<string> Extensions { get; }
 
-		public FileDialogFilter(string name, params string[] extensions) {
+		internal FileDialogFilter(string name, params string[] extensions) {
 			Name = name;
 			Extensions = extensions;
 		}
diff --git a/lib/TweetLib.Core/Systems/Startup/LockFile.cs b/lib/TweetLib.Core/Systems/Startup/LockFile.cs
index 93fe657e..f08e8043 100644
--- a/lib/TweetLib.Core/Systems/Startup/LockFile.cs
+++ b/lib/TweetLib.Core/Systems/Startup/LockFile.cs
@@ -99,7 +99,11 @@ private LockResult DetermineLockingProcessOrFail(Exception originalException) {
 
 				using (var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
 					byte[] bytes = new byte[sizeof(int)];
-					fileStream.Read(bytes, 0, bytes.Length);
+					
+					if (fileStream.Read(bytes, 0, bytes.Length) != bytes.Length) {
+						throw new IOException("Read fewer bytes than requested!");
+					}
+					
 					pid = BitConverter.ToInt32(bytes, 0);
 				}
 
diff --git a/lib/TweetLib.Core/Systems/Updates/UpdateDownloadStatus.cs b/lib/TweetLib.Core/Systems/Updates/UpdateDownloadStatus.cs
index 906eef59..773976e5 100644
--- a/lib/TweetLib.Core/Systems/Updates/UpdateDownloadStatus.cs
+++ b/lib/TweetLib.Core/Systems/Updates/UpdateDownloadStatus.cs
@@ -10,7 +10,7 @@ public enum UpdateDownloadStatus {
 
 	public static class UpdateDownloadStatusExtensions {
 		public static bool IsFinished(this UpdateDownloadStatus status, bool canRetry) {
-			return status == UpdateDownloadStatus.AssetMissing || status == UpdateDownloadStatus.Done || (status == UpdateDownloadStatus.Failed && !canRetry);
+			return status is UpdateDownloadStatus.AssetMissing or UpdateDownloadStatus.Done || (status == UpdateDownloadStatus.Failed && !canRetry);
 		}
 	}
 }
diff --git a/lib/TweetLib.Core/Systems/Updates/UpdateInfo.cs b/lib/TweetLib.Core/Systems/Updates/UpdateInfo.cs
index 4eb86ac2..f56593ab 100644
--- a/lib/TweetLib.Core/Systems/Updates/UpdateInfo.cs
+++ b/lib/TweetLib.Core/Systems/Updates/UpdateInfo.cs
@@ -66,7 +66,7 @@ internal void BeginSilentDownload() {
 		internal void DeleteInstaller() {
 			DownloadStatus = UpdateDownloadStatus.None;
 
-			if (currentDownload != null && currentDownload.IsBusy) {
+			if (currentDownload is { IsBusy: true }) {
 				currentDownload.CancelAsync(); // deletes file when cancelled
 				return;
 			}
diff --git a/lib/TweetLib.Utils/Collections/CommandLineArgs.cs b/lib/TweetLib.Utils/Collections/CommandLineArgs.cs
index ca02949f..4bf1ac9f 100644
--- a/lib/TweetLib.Utils/Collections/CommandLineArgs.cs
+++ b/lib/TweetLib.Utils/Collections/CommandLineArgs.cs
@@ -12,7 +12,7 @@ public static CommandLineArgs FromStringArray(char entryChar, string[] array) {
 			return args;
 		}
 
-		public static void ReadStringArray(char entryChar, string[] array, CommandLineArgs targetArgs) {
+		private static void ReadStringArray(char entryChar, string[] array, CommandLineArgs targetArgs) {
 			for (int index = 0; index < array.Length; index++) {
 				string entry = array[index];
 
diff --git a/lib/TweetLib.Utils/Collections/TwoKeyDictionary.cs b/lib/TweetLib.Utils/Collections/TwoKeyDictionary.cs
index ec92162b..92757f47 100644
--- a/lib/TweetLib.Utils/Collections/TwoKeyDictionary.cs
+++ b/lib/TweetLib.Utils/Collections/TwoKeyDictionary.cs
@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Linq;
 
 namespace TweetLib.Utils.Collections {
@@ -8,6 +9,8 @@ namespace TweetLib.Utils.Collections {
 	/// <typeparam name="K1">The type of the outer key.</typeparam>
 	/// <typeparam name="K2">The type of the inner key.</typeparam>
 	/// <typeparam name="V">The type of the values.</typeparam>
+	[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
+	[SuppressMessage("ReSharper", "UnusedMember.Global")]
 	public sealed class TwoKeyDictionary<K1, K2, V> {
 		private readonly Dictionary<K1, Dictionary<K2, V>> dict;
 		private readonly int innerCapacity;
diff --git a/lib/TweetLib.Utils/Data/InjectedString.cs b/lib/TweetLib.Utils/Data/InjectedString.cs
index 1cc04dad..8a58850d 100644
--- a/lib/TweetLib.Utils/Data/InjectedString.cs
+++ b/lib/TweetLib.Utils/Data/InjectedString.cs
@@ -30,10 +30,13 @@ public string InjectInto(string targetHTML) {
 				case Position.Before:
 					cutIndex = index;
 					break;
+
 				case Position.After:
 					cutIndex = index + search.Length;
 					break;
-				default: return targetHTML;
+
+				default:
+					return targetHTML;
 			}
 
 			return targetHTML.Insert(cutIndex, html);
diff --git a/lib/TweetLib.Utils/IO/CombinedFileStream.cs b/lib/TweetLib.Utils/IO/CombinedFileStream.cs
index 0e1743a0..41bb6932 100644
--- a/lib/TweetLib.Utils/IO/CombinedFileStream.cs
+++ b/lib/TweetLib.Utils/IO/CombinedFileStream.cs
@@ -21,6 +21,15 @@ private static string JoinIdentifier(string[] identifier) {
 			return string.Join(KeySeparator.ToString(), identifier.Select(ValidateIdentifier));
 		}
 
+		private static void ReadExactly(Stream stream, byte[] buffer) {
+			var length = buffer.Length;
+			var read = stream.Read(buffer, 0, length);
+			
+			if (read != length) {
+				throw new IOException("Read fewer bytes than requested: " + read + " < " + length);
+			}
+		}
+
 		private readonly Stream stream;
 
 		public CombinedFileStream(Stream stream) {
@@ -79,13 +88,13 @@ private void WriteStreamImpl(string identifier, Stream sourceStream) {
 			}
 
 			byte[] name = new byte[nameLength];
-			stream.Read(name, 0, nameLength);
+			ReadExactly(stream, name);
 
 			byte[] contentLength = new byte[4];
-			stream.Read(contentLength, 0, 4);
+			ReadExactly(stream, contentLength);
 
 			byte[] contents = new byte[BitConverter.ToInt32(contentLength, 0)];
-			stream.Read(contents, 0, contents.Length);
+			ReadExactly(stream, contents);
 
 			return new Entry(Encoding.UTF8.GetString(name), contents);
 		}
@@ -98,10 +107,10 @@ private void WriteStreamImpl(string identifier, Stream sourceStream) {
 			}
 
 			byte[] name = new byte[nameLength];
-			stream.Read(name, 0, nameLength);
+			ReadExactly(stream, name);
 
 			byte[] contentLength = new byte[4];
-			stream.Read(contentLength, 0, 4);
+			ReadExactly(stream, contentLength);
 
 			stream.Position += BitConverter.ToInt32(contentLength, 0);
 
@@ -120,9 +129,7 @@ void IDisposable.Dispose() {
 		public sealed class Entry {
 			private string Identifier { get; }
 
-			public string KeyName {
-				get { return StringUtils.ExtractBefore(Identifier, KeySeparator); }
-			}
+			public string KeyName => StringUtils.ExtractBefore(Identifier, KeySeparator);
 
 			public string[] KeyValue {
 				get {
diff --git a/lib/TweetLib.Utils/Serialization/TypeConverterRegistry.cs b/lib/TweetLib.Utils/Serialization/TypeConverterRegistry.cs
index ea2fee13..637dc146 100644
--- a/lib/TweetLib.Utils/Serialization/TypeConverterRegistry.cs
+++ b/lib/TweetLib.Utils/Serialization/TypeConverterRegistry.cs
@@ -9,7 +9,7 @@ public void Register(Type type, ITypeConverter converter) {
 			converters[type] = converter;
 		}
 
-		public ITypeConverter? TryGet(Type type) {
+		internal ITypeConverter? TryGet(Type type) {
 			return converters.TryGetValue(type, out var converter) ? converter : null;
 		}
 	}
diff --git a/windows/TweetDuck.Video/FormPlayer.cs b/windows/TweetDuck.Video/FormPlayer.cs
index 47f8428d..db950d9a 100644
--- a/windows/TweetDuck.Video/FormPlayer.cs
+++ b/windows/TweetDuck.Video/FormPlayer.cs
@@ -77,7 +77,7 @@ public FormPlayer(IntPtr handle, int dpi, int volume, string url, string token)
 
 				Marshal.ReleaseComObject(media);
 
-				return $"{(progress / 60).ToString("00")}:{(progress % 60).ToString("00")}";
+				return $"{(progress / 60):00}:{(progress % 60):00}";
 			});
 
 			labelTooltip.AttachTooltip(trackBarVolume, false, args => $"Volume : {trackBarVolume.Value}%");
diff --git a/windows/TweetDuck.Video/Program.cs b/windows/TweetDuck.Video/Program.cs
index 08d6a59e..4fa8ceb8 100644
--- a/windows/TweetDuck.Video/Program.cs
+++ b/windows/TweetDuck.Video/Program.cs
@@ -8,8 +8,8 @@ namespace TweetDuck.Video {
 	static class Program {
 		// referenced in VideoPlayer
 		// set by task manager -- public const int "CodeProcessKilled" = 1;
-		public const int CodeInvalidArgs = 2;
-		public const int CodeLaunchFail = 3;
+		private const int CodeInvalidArgs = 2;
+		private const int CodeLaunchFail = 3;
 		public const int CodeMediaError = 4;
 		public const int CodeOwnerGone = 5;
 		public const int CodeUserRequested = 6;
diff --git a/windows/TweetDuck/Browser/Notification/FormNotificationExample.cs b/windows/TweetDuck/Browser/Notification/FormNotificationExample.cs
index b41a7937..23efde65 100644
--- a/windows/TweetDuck/Browser/Notification/FormNotificationExample.cs
+++ b/windows/TweetDuck/Browser/Notification/FormNotificationExample.cs
@@ -18,14 +18,17 @@ private static NotificationBrowser CreateBrowserImpl(IBrowserComponent browserCo
 
 		protected override FormBorderStyle NotificationBorderStyle {
 			get {
+				var style = base.NotificationBorderStyle;
+				
 				if (Config.NotificationSize == DesktopNotification.Size.Custom) {
-					switch (base.NotificationBorderStyle) {
-						case FormBorderStyle.FixedSingle: return FormBorderStyle.Sizable;
-						case FormBorderStyle.FixedToolWindow: return FormBorderStyle.SizableToolWindow;
-					}
+					return style switch {
+						FormBorderStyle.FixedSingle     => FormBorderStyle.Sizable,
+						FormBorderStyle.FixedToolWindow => FormBorderStyle.SizableToolWindow,
+						_                               => style
+					};
 				}
 
-				return base.NotificationBorderStyle;
+				return style;
 			}
 		}
 
diff --git a/windows/TweetDuck/Browser/Notification/FormNotificationMain.cs b/windows/TweetDuck/Browser/Notification/FormNotificationMain.cs
index ccfa9c2c..12a6790e 100644
--- a/windows/TweetDuck/Browser/Notification/FormNotificationMain.cs
+++ b/windows/TweetDuck/Browser/Notification/FormNotificationMain.cs
@@ -48,7 +48,8 @@ private static int FontSizeLevel {
 
 		private readonly int timerBarHeight;
 
-		protected int timeLeft, totalTime;
+		private int timeLeft;
+		protected int totalTime;
 		protected bool pausedDuringNotification;
 
 		private readonly NativeMethods.HookProc mouseHookDelegate;
diff --git a/windows/TweetDuck/Browser/TrayIcon.cs b/windows/TweetDuck/Browser/TrayIcon.cs
index 44b83ccb..31463570 100644
--- a/windows/TweetDuck/Browser/TrayIcon.cs
+++ b/windows/TweetDuck/Browser/TrayIcon.cs
@@ -48,7 +48,7 @@ public bool HasNotifications {
 		private readonly ContextMenu contextMenu;
 		private bool hasNotifications;
 
-		public TrayIcon() {
+		private TrayIcon() {
 			InitializeComponent();
 
 			this.contextMenu = new ContextMenu();
diff --git a/windows/TweetDuck/Configuration/Arguments.cs b/windows/TweetDuck/Configuration/Arguments.cs
index 9f78fa95..157ed314 100644
--- a/windows/TweetDuck/Configuration/Arguments.cs
+++ b/windows/TweetDuck/Configuration/Arguments.cs
@@ -32,7 +32,7 @@ public static CommandLineArgs GetCurrentClean() {
 			return args;
 		}
 
-		public static CommandLineArgs GetCurrentForInstaller() {
+		private static CommandLineArgs GetCurrentForInstaller() {
 			CommandLineArgs args = GetCurrentClean();
 			args.AddFlag(ArgUpdated);
 			return args;
diff --git a/windows/TweetDuck/Configuration/UserConfig.cs b/windows/TweetDuck/Configuration/UserConfig.cs
index 1344818d..26a3fcda 100644
--- a/windows/TweetDuck/Configuration/UserConfig.cs
+++ b/windows/TweetDuck/Configuration/UserConfig.cs
@@ -11,6 +11,7 @@
 using TweetLib.Utils.Data;
 
 namespace TweetDuck.Configuration {
+	[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global")]
 	sealed class UserConfig : BaseConfig<UserConfig>, IAppUserConfiguration {
 		public bool FirstRun { get; set; } = true;
 
diff --git a/windows/TweetDuck/Dialogs/FormAbout.cs b/windows/TweetDuck/Dialogs/FormAbout.cs
index 96eacbc0..0ea02c3e 100644
--- a/windows/TweetDuck/Dialogs/FormAbout.cs
+++ b/windows/TweetDuck/Dialogs/FormAbout.cs
@@ -1,7 +1,6 @@
 using System;
 using System.ComponentModel;
 using System.Drawing;
-using System.IO;
 using System.Windows.Forms;
 using TweetDuck.Management;
 using TweetLib.Core;
@@ -22,7 +21,7 @@ public FormAbout() {
 			labelIssues.Links.Add(new LinkLabel.Link(0, labelIssues.Text.Length, Lib.IssueTrackerUrl));
 
 			try {
-				pictureLogo.Image = Image.FromFile(Path.Combine(App.ResourcesPath, "images/logo.png"));
+				pictureLogo.Image = Image.FromFile(App.LogoPath);
 			} catch (Exception) {
 				// ignore
 			}
diff --git a/windows/TweetDuck/Dialogs/FormPlugins.cs b/windows/TweetDuck/Dialogs/FormPlugins.cs
index eb690f25..216be1eb 100644
--- a/windows/TweetDuck/Dialogs/FormPlugins.cs
+++ b/windows/TweetDuck/Dialogs/FormPlugins.cs
@@ -16,7 +16,7 @@ sealed partial class FormPlugins : Form, FormManager.IAppDialog {
 
 		private readonly PluginManager pluginManager;
 
-		public FormPlugins() {
+		private FormPlugins() {
 			InitializeComponent();
 
 			Text = Program.BrandName + " Plugins";
diff --git a/windows/TweetDuck/Dialogs/Settings/TabSettingsSounds.cs b/windows/TweetDuck/Dialogs/Settings/TabSettingsSounds.cs
index 81100d77..46459845 100644
--- a/windows/TweetDuck/Dialogs/Settings/TabSettingsSounds.cs
+++ b/windows/TweetDuck/Dialogs/Settings/TabSettingsSounds.cs
@@ -24,7 +24,7 @@ public TabSettingsSounds(Action playSoundNotification) {
 
 			tbCustomSound.Text = Config.NotificationSoundPath;
 			tbCustomSound_TextChanged(tbCustomSound, EventArgs.Empty);
-			NativeMethods.SendMessage(tbCustomSound.Handle, NativeMethods.EM_SETCUEBANNER, 0, "(default TweetDeck sound)");
+			NativeMethods.SetCueBanner(tbCustomSound, "(default TweetDeck sound)");
 		}
 
 		public override void OnReady() {
diff --git a/windows/TweetDuck/Plugins/PluginControl.cs b/windows/TweetDuck/Plugins/PluginControl.cs
index 2dfef825..17071d0f 100644
--- a/windows/TweetDuck/Plugins/PluginControl.cs
+++ b/windows/TweetDuck/Plugins/PluginControl.cs
@@ -16,7 +16,7 @@ sealed partial class PluginControl : UserControl {
 
 		private int nextHeight;
 
-		public PluginControl() {
+		private PluginControl() {
 			InitializeComponent();
 		}
 
diff --git a/windows/TweetDuck/Program.cs b/windows/TweetDuck/Program.cs
index 5199888e..c3eecad3 100644
--- a/windows/TweetDuck/Program.cs
+++ b/windows/TweetDuck/Program.cs
@@ -71,7 +71,7 @@ private static void Main() {
 					ErrorHandler = reporter,
 					SystemHandler = new SystemHandler(),
 					MessageDialogs = new MessageDialogs(),
-					FileDialogs = new FileDialogs(),
+					FileDialogs = new FileDialogs()
 				});
 
 				errorReporter = reporter;
diff --git a/windows/TweetDuck/Utils/NativeMethods.cs b/windows/TweetDuck/Utils/NativeMethods.cs
index cee7fde7..a1e938d3 100644
--- a/windows/TweetDuck/Utils/NativeMethods.cs
+++ b/windows/TweetDuck/Utils/NativeMethods.cs
@@ -8,16 +8,16 @@ namespace TweetDuck.Utils {
 	[SuppressMessage("ReSharper", "MemberCanBePrivate.Local")]
 	[SuppressMessage("ReSharper", "InconsistentNaming")]
 	static class NativeMethods {
-		public static readonly IntPtr HWND_BROADCAST = new IntPtr(0xFFFF);
+		private static readonly IntPtr HWND_BROADCAST = new IntPtr(0xFFFF);
 		public static readonly IntPtr HOOK_HANDLED = new IntPtr(-1);
 
 		public const int HWND_TOPMOST = -1;
 		public const uint SWP_NOACTIVATE = 0x0010;
-		public const int WS_DISABLED = 0x08000000;
-		public const int GWL_STYLE = -16;
-
 		public const int SB_HORZ = 0;
-		public const int EM_SETCUEBANNER = 0x1501;
+		
+		private const int WS_DISABLED = 0x08000000;
+		private const int GWL_STYLE = -16;
+		private const int EM_SETCUEBANNER = 0x1501;
 
 		public const int WM_MOUSE_LL = 14;
 		public const int WM_MOUSEWHEEL = 0x020A;
@@ -57,10 +57,10 @@ private struct MSLLHOOKSTRUCT {
 		private static extern bool SetWindowPos(int hWnd, int hWndOrder, int x, int y, int width, int height, uint flags);
 
 		[DllImport("user32.dll")]
-		public static extern bool SendMessage(IntPtr hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
+		private static extern bool SendMessage(IntPtr hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
 
 		[DllImport("user32.dll")]
-		public static extern bool PostMessage(IntPtr hWnd, uint msg, UIntPtr wParam, IntPtr lParam);
+		private static extern bool PostMessage(IntPtr hWnd, uint msg, UIntPtr wParam, IntPtr lParam);
 
 		[DllImport("user32.dll")]
 		public static extern uint RegisterWindowMessage(string messageName);
@@ -100,6 +100,10 @@ public static void SetFormDisabled(Form form, bool disabled) {
 			}
 		}
 
+		public static void SetCueBanner(Control control, string cueText) {
+			SendMessage(control.Handle, EM_SETCUEBANNER, 0, cueText);
+		}
+
 		public static void BroadcastMessage(uint msg, uint wParam, int lParam) {
 			PostMessage(HWND_BROADCAST, msg, new UIntPtr(wParam), new IntPtr(lParam));
 		}