diff --git a/ICSharpCode.Decompiler.Console/ICSharpCode.Decompiler.Console.csproj b/ICSharpCode.Decompiler.Console/ICSharpCode.Decompiler.Console.csproj
index 6c4ffe35e..a67b9bcc8 100644
--- a/ICSharpCode.Decompiler.Console/ICSharpCode.Decompiler.Console.csproj
+++ b/ICSharpCode.Decompiler.Console/ICSharpCode.Decompiler.Console.csproj
@@ -31,17 +31,12 @@
 
   <Import Project="..\packages.props" />
 
-  <ItemGroup>
-    <Compile Include="..\ICSharpCode.Decompiler.PdbProvider.Cecil\MonoCecilDebugInfoProvider.cs" Link="MonoCecilDebugInfoProvider.cs" />
-    <Compile Include="..\ILSpy\DebugInfo\PortableDebugInfoProvider.cs" Link="PortableDebugInfoProvider.cs" />
-    <Compile Include="..\ILSpy\DebugInfo\DebugInfoUtils.cs" Link="DebugInfoUtils.cs" />
-  </ItemGroup>
-
   <ItemGroup>
     <None Include="ILSpyCmdNuGetPackageIcon.png" Pack="true" PackagePath="\" />
   </ItemGroup>
 
   <ItemGroup>
+    <ProjectReference Include="..\ICSharpCode.ILSpyX\ICSharpCode.ILSpyX.csproj" />
     <ProjectReference Include="..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj" />
   </ItemGroup>
 
diff --git a/ICSharpCode.Decompiler.Console/IlspyCmdProgram.cs b/ICSharpCode.Decompiler.Console/IlspyCmdProgram.cs
index 3459e8554..1d52dca0b 100644
--- a/ICSharpCode.Decompiler.Console/IlspyCmdProgram.cs
+++ b/ICSharpCode.Decompiler.Console/IlspyCmdProgram.cs
@@ -14,8 +14,8 @@ using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
 using ICSharpCode.Decompiler.DebugInfo;
 using ICSharpCode.Decompiler.Disassembler;
 using ICSharpCode.Decompiler.Metadata;
-using ICSharpCode.Decompiler.PdbProvider;
 using ICSharpCode.Decompiler.TypeSystem;
+using ICSharpCode.ILSpyX.PdbProvider;
 
 using McMaster.Extensions.CommandLineUtils;
 // ReSharper disable All
diff --git a/ICSharpCode.Decompiler.PdbProvider.Cecil/ICSharpCode.Decompiler.PdbProvider.Cecil.csproj b/ICSharpCode.Decompiler.PdbProvider.Cecil/ICSharpCode.Decompiler.PdbProvider.Cecil.csproj
deleted file mode 100644
index 4993983fd..000000000
--- a/ICSharpCode.Decompiler.PdbProvider.Cecil/ICSharpCode.Decompiler.PdbProvider.Cecil.csproj
+++ /dev/null
@@ -1,19 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <TargetFramework>netstandard2.0</TargetFramework>
-    <LangVersion>8.0</LangVersion>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-  </PropertyGroup>
-
-  <Import Project="..\packages.props" />
-
-  <ItemGroup>
-    <PackageReference Include="Mono.Cecil" Version="$(MonoCecilVersion)" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj" />
-  </ItemGroup>
-  
-</Project>
diff --git a/ICSharpCode.Decompiler.PowerShell/GetDecompilerCmdlet.cs b/ICSharpCode.Decompiler.PowerShell/GetDecompilerCmdlet.cs
index 5252ceff7..141305e2a 100644
--- a/ICSharpCode.Decompiler.PowerShell/GetDecompilerCmdlet.cs
+++ b/ICSharpCode.Decompiler.PowerShell/GetDecompilerCmdlet.cs
@@ -7,7 +7,7 @@ using System.Text;
 
 using ICSharpCode.Decompiler.CSharp;
 using ICSharpCode.Decompiler.Metadata;
-using ICSharpCode.Decompiler.PdbProvider;
+using ICSharpCode.ILSpyX.PdbProvider;
 
 namespace ICSharpCode.Decompiler.PowerShell
 {
diff --git a/ICSharpCode.Decompiler.PowerShell/ICSharpCode.Decompiler.PowerShell.csproj b/ICSharpCode.Decompiler.PowerShell/ICSharpCode.Decompiler.PowerShell.csproj
index 1945d651a..d185475b1 100644
--- a/ICSharpCode.Decompiler.PowerShell/ICSharpCode.Decompiler.PowerShell.csproj
+++ b/ICSharpCode.Decompiler.PowerShell/ICSharpCode.Decompiler.PowerShell.csproj
@@ -19,9 +19,9 @@
   </ItemGroup>
 
   <ItemGroup>
-    <Compile Include="..\ICSharpCode.Decompiler.PdbProvider.Cecil\MonoCecilDebugInfoProvider.cs" Link="MonoCecilDebugInfoProvider.cs" />
-    <Compile Include="..\ILSpy\DebugInfo\PortableDebugInfoProvider.cs" Link="PortableDebugInfoProvider.cs" />
-    <Compile Include="..\ILSpy\DebugInfo\DebugInfoUtils.cs" Link="DebugInfoUtils.cs" />
+    <Compile Include="..\ICSharpCode.ILSpyX\PdbProvider\MonoCecilDebugInfoProvider.cs" Link="MonoCecilDebugInfoProvider.cs" />
+    <Compile Include="..\ICSharpCode.ILSpyX\PdbProvider\PortableDebugInfoProvider.cs" Link="PortableDebugInfoProvider.cs" />
+    <Compile Include="..\ICSharpCode.ILSpyX\PdbProvider\DebugInfoUtils.cs" Link="DebugInfoUtils.cs" />
   </ItemGroup>
 
 </Project>
diff --git a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
index a342dbb0b..dc67938d7 100644
--- a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
+++ b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
@@ -37,6 +37,7 @@ using ICSharpCode.Decompiler.CSharp.Transforms;
 using ICSharpCode.Decompiler.Disassembler;
 using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.Decompiler.TypeSystem;
+using ICSharpCode.ILSpyX.PdbProvider;
 
 using Microsoft.CodeAnalysis;
 using Microsoft.CodeAnalysis.CSharp;
@@ -672,7 +673,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
 				decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());
 				var pdbFileName = Path.ChangeExtension(assemblyFileName, ".pdb");
 				if (File.Exists(pdbFileName))
-					decompiler.DebugInfoProvider = PdbProvider.DebugInfoUtils.FromFile(module, pdbFileName);
+					decompiler.DebugInfoProvider = DebugInfoUtils.FromFile(module, pdbFileName);
 				var syntaxTree = decompiler.DecompileWholeModuleAsSingleFile(sortTypes: true);
 
 				StringWriter output = new StringWriter();
diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
index b8cce13c2..c2a6a708c 100644
--- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
+++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
@@ -62,6 +62,7 @@
   </ItemGroup>
 
   <ItemGroup>
+    <ProjectReference Include="..\ICSharpCode.ILSpyX\ICSharpCode.ILSpyX.csproj" />
     <ProjectReference Include="..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj" />
   </ItemGroup>
 
@@ -100,9 +101,6 @@
   </ItemGroup>
 
   <ItemGroup>
-    <Compile Include="..\ICSharpCode.Decompiler.PdbProvider.Cecil\MonoCecilDebugInfoProvider.cs" Link="MonoCecilDebugInfoProvider.cs" />
-    <Compile Include="..\ILSpy\DebugInfo\DebugInfoUtils.cs" Link="DebugInfoUtils.cs" />
-    <Compile Include="..\ILSpy\DebugInfo\PortableDebugInfoProvider.cs" Link="PortableDebugInfoProvider.cs" />
     <Compile Include="DisassemblerPrettyTestRunner.cs" />
     <Compile Include="Helpers\RoslynToolset.cs" />
     <Compile Include="Output\InsertParenthesesVisitorTests.cs" />
diff --git a/ILSpy/AssemblyList.cs b/ICSharpCode.ILSpyX/AssemblyList.cs
similarity index 82%
rename from ILSpy/AssemblyList.cs
rename to ICSharpCode.ILSpyX/AssemblyList.cs
index 46a9b9561..e24cb737b 100644
--- a/ILSpy/AssemblyList.cs
+++ b/ICSharpCode.ILSpyX/AssemblyList.cs
@@ -27,21 +27,24 @@ using System.IO;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
-using System.Windows.Threading;
 using System.Xml.Linq;
 
-namespace ICSharpCode.ILSpy
+using ICSharpCode.ILSpyX.Extensions;
+
+namespace ICSharpCode.ILSpyX
 {
 	/// <summary>
 	/// A list of assemblies.
 	/// </summary>
 	public sealed class AssemblyList
 	{
+		readonly Thread ownerThread;
+		readonly SynchronizationContext? synchronizationContext;
+		readonly AssemblyListManager manager;
 		readonly string listName;
 
 		/// <summary>Dirty flag, used to mark modifications so that the list is saved later</summary>
 		bool dirty;
-
 		readonly object lockObj = new object();
 
 		/// <summary>
@@ -62,17 +65,27 @@ namespace ICSharpCode.ILSpy
 		/// </summary>
 		readonly Dictionary<string, LoadedAssembly> byFilename = new Dictionary<string, LoadedAssembly>(StringComparer.OrdinalIgnoreCase);
 
-		public AssemblyList(string listName)
+		/// <summary>
+		/// Exists for testing only.
+		/// </summary>
+		internal AssemblyList()
+		{
+		}
+
+		internal AssemblyList(AssemblyListManager manager, string listName)
 		{
+			this.manager = manager ?? throw new ArgumentNullException(nameof(manager));
 			this.listName = listName;
+			ownerThread = Thread.CurrentThread;
+			synchronizationContext = SynchronizationContext.Current;
 			assemblies.CollectionChanged += Assemblies_CollectionChanged;
 		}
 
 		/// <summary>
 		/// Loads an assembly list from XML.
 		/// </summary>
-		public AssemblyList(XElement listElement)
-			: this((string?)listElement.Attribute("name") ?? AssemblyListManager.DefaultListName)
+		internal AssemblyList(AssemblyListManager manager, XElement listElement)
+			: this(manager, (string?)listElement.Attribute("name") ?? AssemblyListManager.DefaultListName)
 		{
 			foreach (var asm in listElement.Elements("Assembly"))
 			{
@@ -85,7 +98,7 @@ namespace ICSharpCode.ILSpy
 		/// Creates a copy of an assembly list.
 		/// </summary>
 		public AssemblyList(AssemblyList list, string newName)
-			: this(newName)
+			: this(list.manager, newName)
 		{
 			lock (lockObj)
 			{
@@ -99,15 +112,18 @@ namespace ICSharpCode.ILSpy
 
 		public event NotifyCollectionChangedEventHandler CollectionChanged {
 			add {
-				App.Current.Dispatcher.VerifyAccess();
+				VerifyAccess();
 				this.assemblies.CollectionChanged += value;
 			}
 			remove {
-				App.Current.Dispatcher.VerifyAccess();
+				VerifyAccess();
 				this.assemblies.CollectionChanged -= value;
 			}
 		}
 
+		public bool ApplyWinRTProjections { get; set; }
+		public bool UseDebugSymbols { get; set; }
+
 		/// <summary>
 		/// Gets the loaded assemblies. This method is thread-safe.
 		/// </summary>
@@ -165,7 +181,7 @@ namespace ICSharpCode.ILSpy
 
 		internal void Move(LoadedAssembly[] assembliesToMove, int index)
 		{
-			App.Current.Dispatcher.VerifyAccess();
+			VerifyAccess();
 			lock (lockObj)
 			{
 				foreach (LoadedAssembly asm in assembliesToMove)
@@ -214,16 +230,14 @@ namespace ICSharpCode.ILSpy
 			if (!dirty)
 			{
 				dirty = true;
-				App.Current.Dispatcher.BeginInvoke(
-					DispatcherPriority.Background,
-					new Action(
-						delegate {
-							if (dirty)
-							{
-								dirty = false;
-								AssemblyListManager.SaveList(this);
-							}
-						})
+				BeginInvoke(
+					delegate {
+						if (dirty)
+						{
+							dirty = false;
+							this.manager.SaveList(this);
+						}
+					}
 				);
 			}
 		}
@@ -260,7 +274,7 @@ namespace ICSharpCode.ILSpy
 		{
 			file = Path.GetFullPath(file);
 			return OpenAssembly(file, () => {
-				var newAsm = new LoadedAssembly(this, file);
+				var newAsm = new LoadedAssembly(this, file, applyWinRTProjections: ApplyWinRTProjections, useDebugSymbols: UseDebugSymbols);
 				newAsm.IsAutoLoaded = isAutoLoaded;
 				return newAsm;
 			});
@@ -273,7 +287,8 @@ namespace ICSharpCode.ILSpy
 		{
 			file = Path.GetFullPath(file);
 			return OpenAssembly(file, () => {
-				var newAsm = new LoadedAssembly(this, file, stream: Task.FromResult(stream));
+				var newAsm = new LoadedAssembly(this, file, stream: Task.FromResult(stream),
+					applyWinRTProjections: ApplyWinRTProjections, useDebugSymbols: UseDebugSymbols);
 				newAsm.IsAutoLoaded = isAutoLoaded;
 				return newAsm;
 			});
@@ -281,8 +296,7 @@ namespace ICSharpCode.ILSpy
 
 		LoadedAssembly OpenAssembly(string file, Func<LoadedAssembly> load)
 		{
-			bool isUIThread = App.Current.Dispatcher.Thread == Thread.CurrentThread;
-
+			bool isUIThread = ownerThread == Thread.CurrentThread;
 			LoadedAssembly? asm;
 			lock (lockObj)
 			{
@@ -299,12 +313,12 @@ namespace ICSharpCode.ILSpy
 			}
 			if (!isUIThread)
 			{
-				App.Current.Dispatcher.BeginInvoke((Action)delegate () {
+				BeginInvoke(delegate () {
 					lock (lockObj)
 					{
 						assemblies.Add(asm);
 					}
-				}, DispatcherPriority.Normal);
+				});
 			}
 			return asm;
 		}
@@ -315,7 +329,7 @@ namespace ICSharpCode.ILSpy
 		/// </summary>
 		public LoadedAssembly? HotReplaceAssembly(string file, Stream stream)
 		{
-			App.Current.Dispatcher.VerifyAccess();
+			VerifyAccess();
 			file = Path.GetFullPath(file);
 			lock (lockObj)
 			{
@@ -325,7 +339,8 @@ namespace ICSharpCode.ILSpy
 				if (index < 0)
 					return null;
 
-				var newAsm = new LoadedAssembly(this, file, stream: Task.FromResult<Stream?>(stream));
+				var newAsm = new LoadedAssembly(this, file, stream: Task.FromResult<Stream?>(stream),
+					applyWinRTProjections: ApplyWinRTProjections, useDebugSymbols: UseDebugSymbols);
 				newAsm.IsAutoLoaded = target.IsAutoLoaded;
 
 				Debug.Assert(newAsm.FileName == file);
@@ -337,7 +352,7 @@ namespace ICSharpCode.ILSpy
 
 		public LoadedAssembly? ReloadAssembly(string file)
 		{
-			App.Current.Dispatcher.VerifyAccess();
+			VerifyAccess();
 			file = Path.GetFullPath(file);
 
 			var target = this.assemblies.FirstOrDefault(asm => file.Equals(asm.FileName, StringComparison.OrdinalIgnoreCase));
@@ -349,11 +364,12 @@ namespace ICSharpCode.ILSpy
 
 		public LoadedAssembly? ReloadAssembly(LoadedAssembly target)
 		{
-			App.Current.Dispatcher.VerifyAccess();
+			VerifyAccess();
 			var index = this.assemblies.IndexOf(target);
 			if (index < 0)
 				return null;
-			var newAsm = new LoadedAssembly(this, target.FileName, pdbFileName: target.PdbFileName);
+			var newAsm = new LoadedAssembly(this, target.FileName, pdbFileName: target.PdbFileName,
+				applyWinRTProjections: ApplyWinRTProjections, useDebugSymbols: UseDebugSymbols);
 			newAsm.IsAutoLoaded = target.IsAutoLoaded;
 			lock (lockObj)
 			{
@@ -365,27 +381,12 @@ namespace ICSharpCode.ILSpy
 
 		public void Unload(LoadedAssembly assembly)
 		{
-			App.Current.Dispatcher.VerifyAccess();
+			VerifyAccess();
 			lock (lockObj)
 			{
 				assemblies.Remove(assembly);
 				byFilename.Remove(assembly.FileName);
 			}
-			RequestGC();
-		}
-
-		static bool gcRequested;
-
-		static void RequestGC()
-		{
-			if (gcRequested)
-				return;
-			gcRequested = true;
-			App.Current.Dispatcher.BeginInvoke(DispatcherPriority.ContextIdle, new Action(
-				delegate {
-					gcRequested = false;
-					GC.Collect();
-				}));
 		}
 
 		public void Sort(IComparer<LoadedAssembly> comparer)
@@ -395,7 +396,7 @@ namespace ICSharpCode.ILSpy
 
 		public void Sort(int index, int count, IComparer<LoadedAssembly> comparer)
 		{
-			App.Current.Dispatcher.VerifyAccess();
+			VerifyAccess();
 			lock (lockObj)
 			{
 				List<LoadedAssembly> list = new List<LoadedAssembly>(assemblies);
@@ -404,5 +405,23 @@ namespace ICSharpCode.ILSpy
 				assemblies.AddRange(list);
 			}
 		}
+
+		private void BeginInvoke(Action action)
+		{
+			if (synchronizationContext == null)
+			{
+				action();
+			}
+			else
+			{
+				synchronizationContext.Post(new SendOrPostCallback(_ => action()), null);
+			}
+		}
+
+		private void VerifyAccess()
+		{
+			if (this.ownerThread != Thread.CurrentThread)
+				throw new InvalidOperationException("This method must always be called on the thread that owns the assembly list: " + ownerThread.ManagedThreadId + " " + ownerThread.Name);
+		}
 	}
 }
diff --git a/ICSharpCode.ILSpyX/AssemblyListManager.cs b/ICSharpCode.ILSpyX/AssemblyListManager.cs
new file mode 100644
index 000000000..90cd51503
--- /dev/null
+++ b/ICSharpCode.ILSpyX/AssemblyListManager.cs
@@ -0,0 +1,324 @@
+// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this
+// software and associated documentation files (the "Software"), to deal in the Software
+// without restriction, including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
+// to whom the Software is furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in all copies or
+// substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+using System;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Linq;
+using System.Xml.Linq;
+
+using ICSharpCode.Decompiler.Metadata;
+
+namespace ICSharpCode.ILSpyX
+{
+	public interface ISettingsProvider
+	{
+		XElement this[XName section] { get; }
+
+		void Update(Action<XElement> action);
+		ISettingsProvider Load();
+	}
+
+	/// <summary>
+	/// Manages the available assembly lists.
+	/// 
+	/// Contains the list of list names; and provides methods for loading/saving and creating/deleting lists.
+	/// </summary>
+	public sealed class AssemblyListManager
+	{
+		public const string DotNet4List = ".NET 4 (WPF)";
+		public const string DotNet35List = ".NET 3.5";
+		public const string ASPDotNetMVC3List = "ASP.NET (MVC3)";
+
+		private ISettingsProvider settingsProvider;
+
+		public AssemblyListManager(ISettingsProvider settingsProvider)
+		{
+			this.settingsProvider = settingsProvider;
+			XElement doc = this.settingsProvider["AssemblyLists"];
+			foreach (var list in doc.Elements("List"))
+			{
+				AssemblyLists.Add((string)list.Attribute("name"));
+			}
+		}
+
+		public bool ApplyWinRTProjections { get; set; }
+		public bool UseDebugSymbols { get; set; }
+
+		public ObservableCollection<string> AssemblyLists { get; } = new ObservableCollection<string>();
+
+		/// <summary>
+		/// Loads an assembly list from the ILSpySettings.
+		/// If no list with the specified name is found, the default list is loaded instead.
+		/// </summary>
+		public AssemblyList LoadList(string listName)
+		{
+			this.settingsProvider = this.settingsProvider.Load();
+			AssemblyList list = DoLoadList(listName);
+			if (!AssemblyLists.Contains(list.ListName))
+				AssemblyLists.Add(list.ListName);
+			return list;
+		}
+
+		AssemblyList DoLoadList(string listName)
+		{
+			XElement doc = this.settingsProvider["AssemblyLists"];
+			if (listName != null)
+			{
+				foreach (var list in doc.Elements("List"))
+				{
+					if ((string)list.Attribute("name") == listName)
+					{
+						return new AssemblyList(this, list) {
+							UseDebugSymbols = UseDebugSymbols,
+							ApplyWinRTProjections = ApplyWinRTProjections
+						};
+					}
+				}
+			}
+			return new AssemblyList(this, listName ?? DefaultListName) {
+				UseDebugSymbols = UseDebugSymbols,
+				ApplyWinRTProjections = ApplyWinRTProjections
+			};
+		}
+
+		public bool CloneList(string selectedAssemblyList, string newListName)
+		{
+			var list = DoLoadList(selectedAssemblyList);
+			var newList = new AssemblyList(list, newListName) {
+				UseDebugSymbols = UseDebugSymbols,
+				ApplyWinRTProjections = ApplyWinRTProjections
+			};
+			return AddListIfNotExists(newList);
+		}
+
+		public bool RenameList(string selectedAssemblyList, string newListName)
+		{
+			var list = DoLoadList(selectedAssemblyList);
+			var newList = new AssemblyList(list, newListName) {
+				UseDebugSymbols = UseDebugSymbols,
+				ApplyWinRTProjections = ApplyWinRTProjections
+			};
+			return DeleteList(selectedAssemblyList) && AddListIfNotExists(newList);
+		}
+
+		public const string DefaultListName = "(Default)";
+
+		/// <summary>
+		/// Saves the specified assembly list into the config file.
+		/// </summary>
+		public void SaveList(AssemblyList list)
+		{
+			this.settingsProvider.Update(
+				delegate (XElement root) {
+					XElement doc = root.Element("AssemblyLists");
+					if (doc == null)
+					{
+						doc = new XElement("AssemblyLists");
+						root.Add(doc);
+					}
+					XElement listElement = doc.Elements("List").FirstOrDefault(e => (string)e.Attribute("name") == list.ListName);
+					if (listElement != null)
+						listElement.ReplaceWith(list.SaveAsXml());
+					else
+						doc.Add(list.SaveAsXml());
+				});
+		}
+
+		public bool AddListIfNotExists(AssemblyList list)
+		{
+			if (!AssemblyLists.Contains(list.ListName))
+			{
+				AssemblyLists.Add(list.ListName);
+				SaveList(list);
+				return true;
+			}
+			return false;
+		}
+
+		public bool DeleteList(string Name)
+		{
+			if (AssemblyLists.Remove(Name))
+			{
+				this.settingsProvider.Update(
+					delegate (XElement root) {
+						XElement doc = root.Element("AssemblyLists");
+						if (doc == null)
+						{
+							return;
+						}
+						XElement listElement = doc.Elements("List").FirstOrDefault(e => (string)e.Attribute("name") == Name);
+						if (listElement != null)
+							listElement.Remove();
+					});
+				return true;
+			}
+			return false;
+		}
+
+		public void ClearAll()
+		{
+			AssemblyLists.Clear();
+			this.settingsProvider.Update(
+				delegate (XElement root) {
+					XElement doc = root.Element("AssemblyLists");
+					if (doc == null)
+					{
+						return;
+					}
+					doc.Remove();
+				});
+		}
+
+		public void CreateDefaultAssemblyLists()
+		{
+			if (AssemblyLists.Count > 0)
+				return;
+
+			if (!AssemblyLists.Contains(DotNet4List))
+			{
+				AssemblyList dotnet4 = CreateDefaultList(DotNet4List);
+				if (dotnet4.Count > 0)
+				{
+					AddListIfNotExists(dotnet4);
+				}
+			}
+
+			if (!AssemblyLists.Contains(DotNet35List))
+			{
+				AssemblyList dotnet35 = CreateDefaultList(DotNet35List);
+				if (dotnet35.Count > 0)
+				{
+					AddListIfNotExists(dotnet35);
+				}
+			}
+
+			if (!AssemblyLists.Contains(ASPDotNetMVC3List))
+			{
+				AssemblyList mvc = CreateDefaultList(ASPDotNetMVC3List);
+				if (mvc.Count > 0)
+				{
+					AddListIfNotExists(mvc);
+				}
+			}
+		}
+
+		public AssemblyList CreateList(string name)
+		{
+			return new AssemblyList(this, name);
+		}
+
+		public AssemblyList CreateDefaultList(string name, string? path = null, string? newName = null)
+		{
+			var list = new AssemblyList(this, newName ?? name);
+			switch (name)
+			{
+				case DotNet4List:
+					AddToListFromGAC("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.Data.DataSetExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.Xaml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
+					AddToListFromGAC("PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
+					AddToListFromGAC("PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
+					AddToListFromGAC("WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
+					break;
+				case DotNet35List:
+					AddToListFromGAC("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
+					AddToListFromGAC("PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
+					AddToListFromGAC("WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
+					break;
+				case ASPDotNetMVC3List:
+					AddToListFromGAC("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.ComponentModel.DataAnnotations, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
+					AddToListFromGAC("System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
+					AddToListFromGAC("System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.Data.DataSetExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
+					AddToListFromGAC("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
+					AddToListFromGAC("System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
+					AddToListFromGAC("System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
+					AddToListFromGAC("System.Web.ApplicationServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
+					AddToListFromGAC("System.Web.DynamicData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
+					AddToListFromGAC("System.Web.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
+					AddToListFromGAC("System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
+					AddToListFromGAC("System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
+					AddToListFromGAC("System.Web.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
+					AddToListFromGAC("System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
+					AddToListFromGAC("System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
+					AddToListFromGAC("System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+					AddToListFromGAC("Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
+					break;
+				case object _ when path != null:
+					foreach (var file in Directory.GetFiles(path, "*.dll"))
+					{
+						var dllname = Path.GetFileName(file);
+						if (DoIncludeFile(dllname))
+							AddToListFromDirectory(file);
+					}
+					break;
+			}
+			return list;
+
+			void AddToListFromGAC(string fullName)
+			{
+				AssemblyNameReference reference = AssemblyNameReference.Parse(fullName);
+				string? file = UniversalAssemblyResolver.GetAssemblyInGac(reference);
+				if (file != null)
+					list.OpenAssembly(file);
+			}
+
+			void AddToListFromDirectory(string file)
+			{
+				if (File.Exists(file))
+					list.OpenAssembly(file);
+			}
+
+			bool DoIncludeFile(string fileName)
+			{
+				if (fileName == "Microsoft.DiaSymReader.Native.amd64.dll")
+					return false;
+				if (fileName.EndsWith("_cor3.dll", StringComparison.OrdinalIgnoreCase))
+					return false;
+				if (char.IsUpper(fileName[0]))
+					return true;
+				if (fileName == "netstandard.dll")
+					return true;
+				if (fileName == "mscorlib.dll")
+					return true;
+				return false;
+			}
+		}
+	}
+}
diff --git a/ILSpy/AssemblyListSnapshot.cs b/ICSharpCode.ILSpyX/AssemblyListSnapshot.cs
similarity index 98%
rename from ILSpy/AssemblyListSnapshot.cs
rename to ICSharpCode.ILSpyX/AssemblyListSnapshot.cs
index 64c98acf5..7f6821eda 100644
--- a/ILSpy/AssemblyListSnapshot.cs
+++ b/ICSharpCode.ILSpyX/AssemblyListSnapshot.cs
@@ -26,8 +26,9 @@ using System.Threading.Tasks;
 
 using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.Decompiler.Util;
+using ICSharpCode.ILSpyX.Extensions;
 
-namespace ICSharpCode.ILSpy
+namespace ICSharpCode.ILSpyX
 {
 	class AssemblyListSnapshot
 	{
diff --git a/ICSharpCode.ILSpyX/Extensions/CollectionExtensions.cs b/ICSharpCode.ILSpyX/Extensions/CollectionExtensions.cs
new file mode 100644
index 000000000..772c46476
--- /dev/null
+++ b/ICSharpCode.ILSpyX/Extensions/CollectionExtensions.cs
@@ -0,0 +1,122 @@
+// Copyright (c) 2022 Siegfried Pammer
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this
+// software and associated documentation files (the "Software"), to deal in the Software
+// without restriction, including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
+// to whom the Software is furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in all copies or
+// substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+using ICSharpCode.Decompiler.Util;
+
+namespace ICSharpCode.ILSpyX.Extensions
+{
+	public static class CollectionExtensions
+	{
+		public static void AddRange<T>(this ICollection<T> list, IEnumerable<T> items)
+		{
+			foreach (T item in items)
+				if (!list.Contains(item))
+					list.Add(item);
+		}
+
+		public static T? PeekOrDefault<T>(this Stack<T> stack)
+		{
+			if (stack.Count == 0)
+				return default(T);
+			return stack.Peek();
+		}
+
+		public static int BinarySearch<T>(this IList<T> list, T item, int start, int count, IComparer<T> comparer)
+		{
+			if (list == null)
+				throw new ArgumentNullException(nameof(list));
+			if (start < 0 || start >= list.Count)
+				throw new ArgumentOutOfRangeException(nameof(start), start, "Value must be between 0 and " + (list.Count - 1));
+			if (count < 0 || count > list.Count - start)
+				throw new ArgumentOutOfRangeException(nameof(count), count, "Value must be between 0 and " + (list.Count - start));
+			int end = start + count - 1;
+			while (start <= end)
+			{
+				int pivot = (start + end) / 2;
+				int result = comparer.Compare(item, list[pivot]);
+				if (result == 0)
+					return pivot;
+				if (result < 0)
+					end = pivot - 1;
+				else
+					start = pivot + 1;
+			}
+			return ~start;
+		}
+
+		public static int BinarySearch<T, TKey>(this IList<T> instance, TKey itemKey, Func<T, TKey> keySelector)
+			where TKey : IComparable<TKey>, IComparable
+		{
+			if (instance == null)
+				throw new ArgumentNullException(nameof(instance));
+			if (keySelector == null)
+				throw new ArgumentNullException(nameof(keySelector));
+
+			int start = 0;
+			int end = instance.Count - 1;
+
+			while (start <= end)
+			{
+				int m = (start + end) / 2;
+				TKey key = keySelector(instance[m]);
+				int result = key.CompareTo(itemKey);
+				if (result == 0)
+					return m;
+				if (result < 0)
+					start = m + 1;
+				else
+					end = m - 1;
+			}
+			return ~start;
+		}
+
+		public static void InsertSorted<T>(this IList<T> list, T item, IComparer<T> comparer)
+		{
+			if (list == null)
+				throw new ArgumentNullException(nameof(list));
+			if (comparer == null)
+				throw new ArgumentNullException(nameof(comparer));
+
+			if (list.Count == 0)
+			{
+				list.Add(item);
+			}
+			else
+			{
+				int index = list.BinarySearch(item, 0, list.Count, comparer);
+				list.Insert(index < 0 ? ~index : index, item);
+			}
+		}
+
+		internal static void Deconstruct<TKey, TValue>(this KeyValuePair<TKey, TValue> pair, out TKey key, out TValue value)
+		{
+			key = pair.Key;
+			value = pair.Value;
+		}
+
+		internal static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T>? inst) => inst ?? Enumerable.Empty<T>();
+		internal static IEnumerable EmptyIfNull(this IEnumerable? inst) => inst ?? Enumerable.Empty<object>();
+		internal static IList<T> EmptyIfNull<T>(this IList<T>? inst) => inst ?? EmptyList<T>.Instance;
+		internal static IList EmptyIfNull(this IList? inst) => inst ?? Array.Empty<object>();
+	}
+}
diff --git a/ICSharpCode.ILSpyX/ICSharpCode.ILSpyX.csproj b/ICSharpCode.ILSpyX/ICSharpCode.ILSpyX.csproj
new file mode 100644
index 000000000..05386069a
--- /dev/null
+++ b/ICSharpCode.ILSpyX/ICSharpCode.ILSpyX.csproj
@@ -0,0 +1,41 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net6.0</TargetFramework>
+    <Nullable>enable</Nullable>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    
+    <NeutralLanguage>en-US</NeutralLanguage>
+    <GenerateAssemblyVersionAttribute>False</GenerateAssemblyVersionAttribute>
+    <GenerateAssemblyFileVersionAttribute>False</GenerateAssemblyFileVersionAttribute>
+    <GenerateAssemblyInformationalVersionAttribute>False</GenerateAssemblyInformationalVersionAttribute>
+  </PropertyGroup>
+  
+  <Import Project="..\packages.props" />
+  
+  <ItemGroup>
+    <Compile Remove="Properties\AssemblyInfo.template.cs" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="System.IO.Compression" Version="4.3.0" />
+    <PackageReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataVersion)" />
+    <PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="$(SystemCompilerServicesUnsafeVersion)" />
+    <PackageReference Include="System.Composition" Version="$(SystemCompositionVersion)" />
+    <PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
+    <PackageReference Include="Mono.Cecil" Version="$(MonoCecilVersion)" />
+    <PackageReference Include="K4os.Compression.LZ4" Version="1.2.16" />
+    <PackageReference Include="System.Buffers" Version="4.5.1" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj" />
+  </ItemGroup>
+  
+  <Target Name="ILSpyUpdateAssemblyInfo" BeforeTargets="BeforeBuild">
+    <ReadLinesFromFile ContinueOnError="true" File="..\VERSION">
+      <Output TaskParameter="Lines" PropertyName="PackageVersion" />
+    </ReadLinesFromFile>
+  </Target>
+
+</Project>
diff --git a/ILSpy/LoadedAssembly.cs b/ICSharpCode.ILSpyX/LoadedAssembly.cs
similarity index 92%
rename from ILSpy/LoadedAssembly.cs
rename to ICSharpCode.ILSpyX/LoadedAssembly.cs
index 66e9c5b5f..66c992ff0 100644
--- a/ILSpy/LoadedAssembly.cs
+++ b/ICSharpCode.ILSpyX/LoadedAssembly.cs
@@ -18,10 +18,8 @@
 
 using System;
 using System.Buffers;
-using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
-using System.Linq;
 using System.Reflection.Metadata;
 using System.Reflection.PortableExecutable;
 using System.Runtime.CompilerServices;
@@ -30,17 +28,16 @@ using System.Threading.Tasks;
 
 using ICSharpCode.Decompiler.DebugInfo;
 using ICSharpCode.Decompiler.Metadata;
-using ICSharpCode.Decompiler.PdbProvider;
 using ICSharpCode.Decompiler.TypeSystem;
 using ICSharpCode.Decompiler.TypeSystem.Implementation;
 using ICSharpCode.Decompiler.Util;
-using ICSharpCode.ILSpy.Options;
+using ICSharpCode.ILSpyX.PdbProvider;
 
 using K4os.Compression.LZ4;
 
 #nullable enable
 
-namespace ICSharpCode.ILSpy
+namespace ICSharpCode.ILSpyX
 {
 	/// <summary>
 	/// Represents a file loaded into ILSpy.
@@ -86,23 +83,31 @@ namespace ICSharpCode.ILSpy
 		readonly string fileName;
 		readonly string shortName;
 		readonly IAssemblyResolver? providedAssemblyResolver;
+		readonly bool applyWinRTProjections;
+		readonly bool useDebugSymbols;
 
 		public LoadedAssembly? ParentBundle { get; }
 
 		public LoadedAssembly(AssemblyList assemblyList, string fileName,
-			Task<Stream?>? stream = null, IAssemblyResolver? assemblyResolver = null, string? pdbFileName = null)
+			Task<Stream?>? stream = null, IAssemblyResolver? assemblyResolver = null, string? pdbFileName = null,
+			bool applyWinRTProjections = false, bool useDebugSymbols = false)
 		{
 			this.assemblyList = assemblyList ?? throw new ArgumentNullException(nameof(assemblyList));
 			this.fileName = fileName ?? throw new ArgumentNullException(nameof(fileName));
 			this.PdbFileName = pdbFileName;
 			this.providedAssemblyResolver = assemblyResolver;
+			this.applyWinRTProjections = applyWinRTProjections;
+			this.useDebugSymbols = useDebugSymbols;
 
 			this.loadingTask = Task.Run(() => LoadAsync(stream)); // requires that this.fileName is set
 			this.shortName = Path.GetFileNameWithoutExtension(fileName);
 		}
 
-		public LoadedAssembly(LoadedAssembly bundle, string fileName, Task<Stream?>? stream, IAssemblyResolver? assemblyResolver = null)
-			: this(bundle.assemblyList, fileName, stream, assemblyResolver)
+		public LoadedAssembly(LoadedAssembly bundle, string fileName, Task<Stream?>? stream,
+			IAssemblyResolver? assemblyResolver = null,
+			bool applyWinRTProjections = false, bool useDebugSymbols = false)
+			: this(bundle.assemblyList, fileName, stream, assemblyResolver, null,
+				  applyWinRTProjections, useDebugSymbols)
 		{
 			this.ParentBundle = bundle;
 		}
@@ -326,7 +331,7 @@ namespace ICSharpCode.ILSpy
 					stream = memoryStream;
 				}
 				var streamOptions = stream is MemoryStream ? PEStreamOptions.PrefetchEntireImage : PEStreamOptions.Default;
-				return LoadAssembly(stream, streamOptions);
+				return LoadAssembly(stream, streamOptions, applyWinRTProjections);
 			}
 			// Read the module from disk
 			Exception loadAssemblyException;
@@ -334,7 +339,7 @@ namespace ICSharpCode.ILSpy
 			{
 				using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
 				{
-					return LoadAssembly(fileStream, PEStreamOptions.PrefetchEntireImage);
+					return LoadAssembly(fileStream, PEStreamOptions.PrefetchEntireImage, applyWinRTProjections);
 				}
 			}
 			catch (PEFileNotSupportedException ex)
@@ -374,17 +379,11 @@ namespace ICSharpCode.ILSpy
 			}
 		}
 
-		LoadResult LoadAssembly(Stream stream, PEStreamOptions streamOptions)
+		LoadResult LoadAssembly(Stream stream, PEStreamOptions streamOptions, bool applyWinRTProjections)
 		{
-			MetadataReaderOptions options;
-			if (DecompilerSettingsPanel.CurrentDecompilerSettings.ApplyWindowsRuntimeProjections)
-			{
-				options = MetadataReaderOptions.ApplyWindowsRuntimeProjections;
-			}
-			else
-			{
-				options = MetadataReaderOptions.None;
-			}
+			MetadataReaderOptions options = applyWinRTProjections
+				? MetadataReaderOptions.ApplyWindowsRuntimeProjections
+				: MetadataReaderOptions.None;
 
 			PEFile module = new PEFile(fileName, stream, streamOptions, metadataOptions: options);
 
@@ -421,7 +420,7 @@ namespace ICSharpCode.ILSpy
 					// Load module from decompressed data buffer
 					using (var uncompressedStream = new MemoryStream(dst, writable: false))
 					{
-						return LoadAssembly(uncompressedStream, PEStreamOptions.PrefetchEntireImage);
+						return LoadAssembly(uncompressedStream, PEStreamOptions.PrefetchEntireImage, applyWinRTProjections);
 					}
 				}
 				finally
@@ -434,11 +433,11 @@ namespace ICSharpCode.ILSpy
 
 		IDebugInfoProvider? LoadDebugInfo(PEFile module)
 		{
-			if (DecompilerSettingsPanel.CurrentDecompilerSettings.UseDebugSymbols)
+			if (useDebugSymbols)
 			{
 				try
 				{
-					return DebugInfoUtils.FromFile(module, PdbFileName)
+					return (PdbFileName != null ? DebugInfoUtils.FromFile(module, PdbFileName) : null)
 						?? DebugInfoUtils.LoadSymbols(module);
 				}
 				catch (IOException)
@@ -467,6 +466,7 @@ namespace ICSharpCode.ILSpy
 		{
 			readonly LoadedAssembly parent;
 			readonly bool loadOnDemand;
+			readonly bool applyWinRTProjections;
 
 			readonly IAssemblyResolver? providedAssemblyResolver;
 			readonly AssemblyList assemblyList;
@@ -474,10 +474,12 @@ namespace ICSharpCode.ILSpy
 			readonly Task<string> tfmTask;
 			readonly ReferenceLoadInfo referenceLoadInfo;
 
-			public MyAssemblyResolver(LoadedAssembly parent, AssemblyListSnapshot assemblyListSnapshot, bool loadOnDemand)
+			public MyAssemblyResolver(LoadedAssembly parent, AssemblyListSnapshot assemblyListSnapshot,
+				bool loadOnDemand, bool applyWinRTProjections)
 			{
 				this.parent = parent;
 				this.loadOnDemand = loadOnDemand;
+				this.applyWinRTProjections = applyWinRTProjections;
 
 				this.providedAssemblyResolver = parent.providedAssemblyResolver;
 				this.assemblyList = parent.assemblyList;
@@ -529,7 +531,7 @@ namespace ICSharpCode.ILSpy
 					return module;
 				}
 
-				string? file = parent.GetUniversalResolver().FindAssemblyFile(reference);
+				string? file = parent.GetUniversalResolver(applyWinRTProjections).FindAssemblyFile(reference);
 
 				if (file != null)
 				{
@@ -622,23 +624,24 @@ namespace ICSharpCode.ILSpy
 			}
 		}
 
-		public IAssemblyResolver GetAssemblyResolver(bool loadOnDemand = true)
+		public IAssemblyResolver GetAssemblyResolver(bool loadOnDemand = true, bool applyWinRTProjections = false)
 		{
-			return new MyAssemblyResolver(this, AssemblyList.GetSnapshot(), loadOnDemand);
+			return new MyAssemblyResolver(this, AssemblyList.GetSnapshot(), loadOnDemand, applyWinRTProjections);
 		}
 
-		internal IAssemblyResolver GetAssemblyResolver(AssemblyListSnapshot snapshot, bool loadOnDemand = true)
+		internal IAssemblyResolver GetAssemblyResolver(AssemblyListSnapshot snapshot,
+			bool loadOnDemand = true, bool applyWinRTProjections = false)
 		{
-			return new MyAssemblyResolver(this, snapshot, loadOnDemand);
+			return new MyAssemblyResolver(this, snapshot, loadOnDemand, applyWinRTProjections);
 		}
 
-		private UniversalAssemblyResolver GetUniversalResolver()
+		private UniversalAssemblyResolver GetUniversalResolver(bool applyWinRTProjections)
 		{
 			return LazyInitializer.EnsureInitialized(ref this.universalResolver, () => {
 				var targetFramework = this.GetTargetFrameworkIdAsync().Result;
 				var runtimePack = this.GetRuntimePackAsync().Result;
 
-				var readerOptions = DecompilerSettingsPanel.CurrentDecompilerSettings.ApplyWindowsRuntimeProjections
+				var readerOptions = applyWinRTProjections
 					? MetadataReaderOptions.ApplyWindowsRuntimeProjections
 					: MetadataReaderOptions.None;
 
@@ -649,9 +652,9 @@ namespace ICSharpCode.ILSpy
 			})!;
 		}
 
-		public AssemblyReferenceClassifier GetAssemblyReferenceClassifier()
+		public AssemblyReferenceClassifier GetAssemblyReferenceClassifier(bool applyWinRTProjections)
 		{
-			return GetUniversalResolver();
+			return GetUniversalResolver(applyWinRTProjections);
 		}
 
 		/// <summary>
diff --git a/ILSpy/LoadedAssemblyExtensions.cs b/ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs
similarity index 84%
rename from ILSpy/LoadedAssemblyExtensions.cs
rename to ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs
index 05d210145..724310e07 100644
--- a/ILSpy/LoadedAssemblyExtensions.cs
+++ b/ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs
@@ -5,7 +5,7 @@ using ICSharpCode.Decompiler.DebugInfo;
 using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.Decompiler.TypeSystem;
 
-namespace ICSharpCode.ILSpy
+namespace ICSharpCode.ILSpyX
 {
 	public static class LoadedAssemblyExtensions
 	{
@@ -36,21 +36,16 @@ namespace ICSharpCode.ILSpy
 			return GetLoadedAssembly(file).GetAssemblyResolver(snapshot, loadOnDemand);
 		}
 
-		public static IDebugInfoProvider GetDebugInfoOrNull(this PEFile file)
+		public static IDebugInfoProvider? GetDebugInfoOrNull(this PEFile file)
 		{
 			return GetLoadedAssembly(file).GetDebugInfoOrNull();
 		}
 
-		public static ICompilation GetTypeSystemOrNull(this PEFile file)
+		public static ICompilation? GetTypeSystemOrNull(this PEFile file)
 		{
 			return GetLoadedAssembly(file).GetTypeSystemOrNull();
 		}
 
-		public static ICompilation GetTypeSystemWithCurrentOptionsOrNull(this PEFile file)
-		{
-			return GetLoadedAssembly(file).GetTypeSystemOrNull(DecompilerTypeSystem.GetOptions(new DecompilationOptions().DecompilerSettings));
-		}
-
 		public static LoadedAssembly GetLoadedAssembly(this PEFile file)
 		{
 			if (file == null)
diff --git a/ILSpy/LoadedPackage.cs b/ICSharpCode.ILSpyX/LoadedPackage.cs
similarity index 99%
rename from ILSpy/LoadedPackage.cs
rename to ICSharpCode.ILSpyX/LoadedPackage.cs
index 2acf98e62..ffe789cdb 100644
--- a/ILSpy/LoadedPackage.cs
+++ b/ICSharpCode.ILSpyX/LoadedPackage.cs
@@ -31,7 +31,7 @@ using System.Threading.Tasks;
 using ICSharpCode.Decompiler;
 using ICSharpCode.Decompiler.Metadata;
 
-namespace ICSharpCode.ILSpy
+namespace ICSharpCode.ILSpyX
 {
 	/// <summary>
 	/// NuGet package or .NET bundle:
diff --git a/ILSpy/DebugInfo/DebugInfoUtils.cs b/ICSharpCode.ILSpyX/PdbProvider/DebugInfoUtils.cs
similarity index 98%
rename from ILSpy/DebugInfo/DebugInfoUtils.cs
rename to ICSharpCode.ILSpyX/PdbProvider/DebugInfoUtils.cs
index cd3f9b596..16cbe284d 100644
--- a/ILSpy/DebugInfo/DebugInfoUtils.cs
+++ b/ICSharpCode.ILSpyX/PdbProvider/DebugInfoUtils.cs
@@ -26,9 +26,9 @@ using System.Runtime.InteropServices;
 using ICSharpCode.Decompiler.DebugInfo;
 using ICSharpCode.Decompiler.Metadata;
 
-namespace ICSharpCode.Decompiler.PdbProvider
+namespace ICSharpCode.ILSpyX.PdbProvider
 {
-	static class DebugInfoUtils
+	public static class DebugInfoUtils
 	{
 		public static IDebugInfoProvider LoadSymbols(PEFile module)
 		{
diff --git a/ICSharpCode.Decompiler.PdbProvider.Cecil/MonoCecilDebugInfoProvider.cs b/ICSharpCode.ILSpyX/PdbProvider/MonoCecilDebugInfoProvider.cs
similarity index 99%
rename from ICSharpCode.Decompiler.PdbProvider.Cecil/MonoCecilDebugInfoProvider.cs
rename to ICSharpCode.ILSpyX/PdbProvider/MonoCecilDebugInfoProvider.cs
index 0ca165e06..8d2f9e272 100644
--- a/ICSharpCode.Decompiler.PdbProvider.Cecil/MonoCecilDebugInfoProvider.cs
+++ b/ICSharpCode.ILSpyX/PdbProvider/MonoCecilDebugInfoProvider.cs
@@ -31,7 +31,7 @@ using Mono.Cecil.Pdb;
 
 using SRM = System.Reflection.Metadata;
 
-namespace ICSharpCode.Decompiler.PdbProvider
+namespace ICSharpCode.ILSpyX.PdbProvider
 {
 	public class MonoCecilDebugInfoProvider : IDebugInfoProvider
 	{
diff --git a/ILSpy/DebugInfo/PortableDebugInfoProvider.cs b/ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs
similarity index 95%
rename from ILSpy/DebugInfo/PortableDebugInfoProvider.cs
rename to ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs
index f4c04cd3b..b04198c80 100644
--- a/ILSpy/DebugInfo/PortableDebugInfoProvider.cs
+++ b/ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs
@@ -23,7 +23,7 @@ using System.Reflection.Metadata;
 
 using ICSharpCode.Decompiler.DebugInfo;
 
-namespace ICSharpCode.Decompiler.PdbProvider
+namespace ICSharpCode.ILSpyX.PdbProvider
 {
 	class PortableDebugInfoProvider : IDebugInfoProvider
 	{
@@ -80,11 +80,11 @@ namespace ICSharpCode.Decompiler.PdbProvider
 
 		public string SourceFileName => pdbFileName ?? moduleFileName;
 
-		public IList<DebugInfo.SequencePoint> GetSequencePoints(MethodDefinitionHandle method)
+		public IList<Decompiler.DebugInfo.SequencePoint> GetSequencePoints(MethodDefinitionHandle method)
 		{
 			var metadata = GetMetadataReader();
 			var debugInfo = metadata.GetMethodDebugInformation(method);
-			var sequencePoints = new List<DebugInfo.SequencePoint>();
+			var sequencePoints = new List<Decompiler.DebugInfo.SequencePoint>();
 			if (metadata == null)
 				return sequencePoints;
 
diff --git a/ICSharpCode.ILSpyX/Properties/AssemblyInfo.cs b/ICSharpCode.ILSpyX/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..25750d5ce
--- /dev/null
+++ b/ICSharpCode.ILSpyX/Properties/AssemblyInfo.cs
@@ -0,0 +1,29 @@
+#region Using directives
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
+
+#endregion
+
+// This sets the default COM visibility of types in the assembly to invisible.
+// If you need to expose a type to COM, use [ComVisible(true)] on that type.
+[assembly: ComVisible(false)]
+
+[assembly: AssemblyVersion(DecompilerVersionInfo.Major + "." + DecompilerVersionInfo.Minor + "." + DecompilerVersionInfo.Build + "." + DecompilerVersionInfo.Revision)]
+[assembly: AssemblyInformationalVersion(DecompilerVersionInfo.FullVersionWithShortCommitHash)]
+
+[assembly: SupportedOSPlatform("Windows7.0")]
+[assembly: TargetPlatform("Windows10.0")]
+
+[assembly: SuppressMessage("Microsoft.Usage", "CA2243:AttributeStringLiteralsShouldParseCorrectly",
+	Justification = "AssemblyInformationalVersion does not need to be a parsable version")]
+
+[assembly: InternalsVisibleTo("ILSpy, PublicKey=00240000048000009400000006020000002400005253413100040000010001004dcf3979c4e902efa4dd2163a039701ed5822e6f1134d77737296abbb97bf0803083cfb2117b4f5446a217782f5c7c634f9fe1fc60b4c11d62c5b3d33545036706296d31903ddcf750875db38a8ac379512f51620bb948c94d0831125fbc5fe63707cbb93f48c1459c4d1749eb7ac5e681a2f0d6d7c60fa527a3c0b8f92b02bf")]
+[assembly: InternalsVisibleTo("ILSpy.Tests")]
+
+
diff --git a/ILSpy.AddIn.slnf b/ILSpy.AddIn.slnf
index 21f14e948..8dbeea0a1 100644
--- a/ILSpy.AddIn.slnf
+++ b/ILSpy.AddIn.slnf
@@ -2,9 +2,9 @@
   "solution": {
     "path": "ILSpy.sln",
     "projects": [
-      "ICSharpCode.Decompiler.PdbProvider.Cecil\\ICSharpCode.Decompiler.PdbProvider.Cecil.csproj",
       "ICSharpCode.Decompiler.Tests\\ICSharpCode.Decompiler.Tests.csproj",
       "ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj",
+      "ICSharpCode.ILSpyX\\ICSharpCode.ILSpyX.csproj",
       "ILSpy.AddIn.Shared\\ILSpy.AddIn.Shared.shproj",
       "ILSpy.AddIn.VS2022\\ILSpy.AddIn.VS2022.csproj",
       "ILSpy.AddIn\\ILSpy.AddIn.csproj",
diff --git a/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs b/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs
index f2c0b375c..c5f086342 100644
--- a/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs
+++ b/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs
@@ -23,6 +23,7 @@ using System.IO;
 using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.ILSpy;
 using ICSharpCode.ILSpy.TreeNodes;
+using ICSharpCode.ILSpyX;
 
 namespace ILSpy.BamlDecompiler
 {
diff --git a/ILSpy.Installer.slnf b/ILSpy.Installer.slnf
index a45d85373..bff5364a2 100644
--- a/ILSpy.Installer.slnf
+++ b/ILSpy.Installer.slnf
@@ -5,6 +5,7 @@
 			"ICSharpCode.Decompiler.PdbProvider.Cecil\\ICSharpCode.Decompiler.PdbProvider.Cecil.csproj",
 			"ICSharpCode.Decompiler.Tests\\ICSharpCode.Decompiler.Tests.csproj",
 			"ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj",
+			"ICSharpCode.ILSpyX\\ICSharpCode.ILSpyX.csproj",
 			"ILSpy.BamlDecompiler.Tests\\ILSpy.BamlDecompiler.Tests.csproj",
 			"ILSpy.BamlDecompiler\\ILSpy.BamlDecompiler.csproj",
 			"ILSpy.ReadyToRun\\ILSpy.ReadyToRun.csproj",
diff --git a/ILSpy.ReadyToRun/ReadyToRunLanguage.cs b/ILSpy.ReadyToRun/ReadyToRunLanguage.cs
index 037cb7903..d8db74e98 100644
--- a/ILSpy.ReadyToRun/ReadyToRunLanguage.cs
+++ b/ILSpy.ReadyToRun/ReadyToRunLanguage.cs
@@ -33,6 +33,7 @@ using ICSharpCode.Decompiler.Disassembler;
 using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.Decompiler.Solution;
 using ICSharpCode.Decompiler.TypeSystem;
+using ICSharpCode.ILSpyX;
 
 using ILCompiler.Reflection.ReadyToRun;
 
diff --git a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs
index 415d3f729..fed74fb2c 100644
--- a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs
+++ b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs
@@ -22,7 +22,6 @@ using System.Xml.Linq;
 
 using ICSharpCode.ILSpy.Options;
 
-using ILSpy.ReadyToRun;
 namespace ICSharpCode.ILSpy.ReadyToRun
 {
 	[ExportOptionPage(Title = nameof(global::ILSpy.ReadyToRun.Properties.Resources.ReadyToRun), Order = 40)]
diff --git a/ILSpy.ReadyToRun/ReadyToRunOptions.cs b/ILSpy.ReadyToRun/ReadyToRunOptions.cs
index 3fbd6df6c..8f8d5d75e 100644
--- a/ILSpy.ReadyToRun/ReadyToRunOptions.cs
+++ b/ILSpy.ReadyToRun/ReadyToRunOptions.cs
@@ -18,6 +18,8 @@
 
 using System.Xml.Linq;
 
+using ICSharpCode.ILSpyX;
+
 namespace ICSharpCode.ILSpy.ReadyToRun
 {
 	internal class ReadyToRunOptions
diff --git a/ILSpy.Tests/Analyzers/MethodUsesAnalyzerTests.cs b/ILSpy.Tests/Analyzers/MethodUsesAnalyzerTests.cs
index e502891ac..0f9f46cbb 100644
--- a/ILSpy.Tests/Analyzers/MethodUsesAnalyzerTests.cs
+++ b/ILSpy.Tests/Analyzers/MethodUsesAnalyzerTests.cs
@@ -8,6 +8,7 @@ using System.Windows;
 using ICSharpCode.Decompiler.TypeSystem;
 using ICSharpCode.ILSpy.Analyzers;
 using ICSharpCode.ILSpy.Analyzers.Builtin;
+using ICSharpCode.ILSpyX;
 
 using NUnit.Framework;
 
@@ -25,9 +26,7 @@ namespace ICSharpCode.ILSpy.Tests.Analyzers
 		[OneTimeSetUp]
 		public void Setup()
 		{
-			Stub.SetupApplication();
-			Options.DecompilerSettingsPanel.TestSetup(new Decompiler.DecompilerSettings());
-			assemblyList = new AssemblyList("Test");
+			assemblyList = new AssemblyList();
 			testAssembly = assemblyList.OpenAssembly(typeof(MethodUsesAnalyzerTests).Assembly.Location);
 			assemblyList.OpenAssembly(typeof(void).Assembly.Location);
 			testAssemblyTypeSystem = testAssembly.GetTypeSystemOrNull();
diff --git a/ILSpy.Tests/Analyzers/TypeUsedByAnalyzerTests.cs b/ILSpy.Tests/Analyzers/TypeUsedByAnalyzerTests.cs
index 6a57daa8c..76af5ca9c 100644
--- a/ILSpy.Tests/Analyzers/TypeUsedByAnalyzerTests.cs
+++ b/ILSpy.Tests/Analyzers/TypeUsedByAnalyzerTests.cs
@@ -23,17 +23,18 @@ using System.Text;
 using System.Threading.Tasks;
 using System.Windows;
 
+using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.Decompiler.TypeSystem;
 using ICSharpCode.Decompiler.TypeSystem.Implementation;
 using ICSharpCode.ILSpy.Analyzers;
 using ICSharpCode.ILSpy.Analyzers.Builtin;
+using ICSharpCode.ILSpyX;
 
 using NUnit.Framework;
 
 namespace ICSharpCode.ILSpy.Tests.Analyzers
 {
 	[TestFixture, Parallelizable(ParallelScope.All)]
-	[Ignore("Only one test case can be executed, the test setup is really hacky and the whole ILSpy UI should be refactored and made mockable/testable, remove singletons, dependencies on Application.Current.Dispatcher, etc.")]
 	public class TypeUsedByAnalyzerTests
 	{
 		AssemblyList assemblyList;
@@ -44,11 +45,9 @@ namespace ICSharpCode.ILSpy.Tests.Analyzers
 		[OneTimeSetUp]
 		public void Setup()
 		{
-			Stub.SetupApplication();
-			Options.DecompilerSettingsPanel.TestSetup(new Decompiler.DecompilerSettings());
-			assemblyList = new AssemblyList("Test");
+			assemblyList = new AssemblyList();
 			testAssembly = assemblyList.OpenAssembly(typeof(MethodUsesAnalyzerTests).Assembly.Location);
-			testAssemblyTypeSystem = new SimpleCompilation(testAssembly.GetPEFileOrNull(), assemblyList.OpenAssembly(typeof(void).Assembly.Location).GetPEFileOrNull());
+			testAssemblyTypeSystem = new DecompilerTypeSystem(testAssembly.GetPEFileOrNull(), testAssembly.GetAssemblyResolver());
 			language = new CSharpLanguage();
 		}
 
diff --git a/ILSpy.Tests/ILSpy.Tests.csproj b/ILSpy.Tests/ILSpy.Tests.csproj
index 3e136338b..345189f44 100644
--- a/ILSpy.Tests/ILSpy.Tests.csproj
+++ b/ILSpy.Tests/ILSpy.Tests.csproj
@@ -38,7 +38,6 @@
     <Compile Include="Analyzers\MethodUsesAnalyzerTests.cs" />
     <Compile Include="Analyzers\TestCases\MainAssembly.cs" />
     <Compile Include="Analyzers\TypeUsedByAnalyzerTests.cs" />
-    <Compile Include="Stub.cs" />
   </ItemGroup>
 
   <Import Project="..\packages.props" />
diff --git a/ILSpy.Tests/Stub.cs b/ILSpy.Tests/Stub.cs
deleted file mode 100644
index 6763528d4..000000000
--- a/ILSpy.Tests/Stub.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2020 Siegfried Pammer
-// 
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this
-// software and associated documentation files (the "Software"), to deal in the Software
-// without restriction, including without limitation the rights to use, copy, modify, merge,
-// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
-// to whom the Software is furnished to do so, subject to the following conditions:
-// 
-// The above copyright notice and this permission notice shall be included in all copies or
-// substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
-// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-using System.Windows;
-
-namespace ICSharpCode.ILSpy.Tests
-{
-	public static class Stub
-	{
-		static readonly object sync = new object();
-
-		internal static void SetupApplication()
-		{
-			lock (sync)
-			{
-				if (Application.Current == null)
-					new Application();
-			}
-		}
-	}
-}
diff --git a/ILSpy.Wpf.slnf b/ILSpy.Wpf.slnf
index 259436d4c..e27dd18c4 100644
--- a/ILSpy.Wpf.slnf
+++ b/ILSpy.Wpf.slnf
@@ -5,6 +5,7 @@
 			"ICSharpCode.Decompiler.PdbProvider.Cecil\\ICSharpCode.Decompiler.PdbProvider.Cecil.csproj",
 			"ICSharpCode.Decompiler.Tests\\ICSharpCode.Decompiler.Tests.csproj",
 			"ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj",
+			"ICSharpCode.ILSpyX\\ICSharpCode.ILSpyX.csproj",
 			"ILSpy.BamlDecompiler.Tests\\ILSpy.BamlDecompiler.Tests.csproj",
 			"ILSpy.BamlDecompiler\\ILSpy.BamlDecompiler.csproj",
 			"ILSpy.ReadyToRun\\ILSpy.ReadyToRun.csproj",
diff --git a/ILSpy.XPlat.slnf b/ILSpy.XPlat.slnf
index 02445a148..c7272c267 100644
--- a/ILSpy.XPlat.slnf
+++ b/ILSpy.XPlat.slnf
@@ -5,7 +5,8 @@
 			"ICSharpCode.Decompiler.Console\\ICSharpCode.Decompiler.Console.csproj",
 			"ICSharpCode.Decompiler.PowerShell\\ICSharpCode.Decompiler.PowerShell.csproj",
 			"ICSharpCode.Decompiler.Tests\\ICSharpCode.Decompiler.Tests.csproj",
-			"ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj"
+			"ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj",
+			"ICSharpCode.ILSpyX\\ICSharpCode.ILSpyX.csproj"
 		]
 	}
 }
\ No newline at end of file
diff --git a/ILSpy.sln b/ILSpy.sln
index bbb51a9b5..ff994e7b8 100644
--- a/ILSpy.sln
+++ b/ILSpy.sln
@@ -37,8 +37,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILSpy.AddIn", "ILSpy.AddIn\
 		{1E85EFF9-E370-4683-83E4-8A3D063FF791} = {1E85EFF9-E370-4683-83E4-8A3D063FF791}
 	EndProjectSection
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ICSharpCode.Decompiler.PdbProvider.Cecil", "ICSharpCode.Decompiler.PdbProvider.Cecil\ICSharpCode.Decompiler.PdbProvider.Cecil.csproj", "{B85A155A-9DD6-43BC-A624-2D8EC773D71F}"
-EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILSpy.Tests", "ILSpy.Tests\ILSpy.Tests.csproj", "{B51C6636-B8D1-4200-9869-08F2689DE6C2}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILSpy.ReadyToRun", "ILSpy.ReadyToRun\ILSpy.ReadyToRun.csproj", "{0313F581-C63B-43BB-AA9B-07615DABD8A3}"
@@ -65,6 +63,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILSpy.Installer", "ILSpy.In
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ICSharpCode.Decompiler.TestRunner", "ICSharpCode.Decompiler.TestRunner\ICSharpCode.Decompiler.TestRunner.csproj", "{4FBB470F-69EB-4C8B-8961-8B4DF4EBB999}"
 EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ICSharpCode.ILSpyX", "ICSharpCode.ILSpyX\ICSharpCode.ILSpyX.csproj", "{F8EFCF9D-B9A3-4BA0-A1B2-B026A71DAC22}"
+EndProject
 Global
 	GlobalSection(SharedMSBuildProjectFiles) = preSolution
 		ILSpy.AddIn.Shared\ILSpy.AddIn.Shared.projitems*{09a03980-d14a-4705-a38c-741ad7166dee}*SharedItemsImports = 5
@@ -108,10 +108,6 @@ Global
 		{9D7BE6C0-B7B3-4A50-A54E-18A2D84A3384}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{9D7BE6C0-B7B3-4A50-A54E-18A2D84A3384}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{9D7BE6C0-B7B3-4A50-A54E-18A2D84A3384}.Release|Any CPU.Build.0 = Release|Any CPU
-		{B85A155A-9DD6-43BC-A624-2D8EC773D71F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{B85A155A-9DD6-43BC-A624-2D8EC773D71F}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{B85A155A-9DD6-43BC-A624-2D8EC773D71F}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{B85A155A-9DD6-43BC-A624-2D8EC773D71F}.Release|Any CPU.Build.0 = Release|Any CPU
 		{B51C6636-B8D1-4200-9869-08F2689DE6C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{B51C6636-B8D1-4200-9869-08F2689DE6C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{B51C6636-B8D1-4200-9869-08F2689DE6C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -140,6 +136,10 @@ Global
 		{4FBB470F-69EB-4C8B-8961-8B4DF4EBB999}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{4FBB470F-69EB-4C8B-8961-8B4DF4EBB999}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{4FBB470F-69EB-4C8B-8961-8B4DF4EBB999}.Release|Any CPU.Build.0 = Release|Any CPU
+		{F8EFCF9D-B9A3-4BA0-A1B2-B026A71DAC22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F8EFCF9D-B9A3-4BA0-A1B2-B026A71DAC22}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F8EFCF9D-B9A3-4BA0-A1B2-B026A71DAC22}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F8EFCF9D-B9A3-4BA0-A1B2-B026A71DAC22}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/ILSpy/Analyzers/AnalyzerContext.cs b/ILSpy/Analyzers/AnalyzerContext.cs
index 47a7b517b..2e3657103 100644
--- a/ILSpy/Analyzers/AnalyzerContext.cs
+++ b/ILSpy/Analyzers/AnalyzerContext.cs
@@ -23,6 +23,7 @@ using System.Threading;
 
 using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.Decompiler.TypeSystem;
+using ICSharpCode.ILSpyX;
 
 namespace ICSharpCode.ILSpy.Analyzers
 {
diff --git a/ILSpy/Analyzers/AnalyzerEntityTreeNode.cs b/ILSpy/Analyzers/AnalyzerEntityTreeNode.cs
index ee1fc4ee9..782821c47 100644
--- a/ILSpy/Analyzers/AnalyzerEntityTreeNode.cs
+++ b/ILSpy/Analyzers/AnalyzerEntityTreeNode.cs
@@ -21,6 +21,7 @@ using System.Windows;
 
 using ICSharpCode.Decompiler.TypeSystem;
 using ICSharpCode.ILSpy.TreeNodes;
+using ICSharpCode.ILSpyX;
 using ICSharpCode.TreeView;
 
 namespace ICSharpCode.ILSpy.Analyzers
diff --git a/ILSpy/Analyzers/AnalyzerScope.cs b/ILSpy/Analyzers/AnalyzerScope.cs
index 6b5735be8..6377549b2 100644
--- a/ILSpy/Analyzers/AnalyzerScope.cs
+++ b/ILSpy/Analyzers/AnalyzerScope.cs
@@ -24,6 +24,7 @@ using System.Threading;
 using ICSharpCode.Decompiler;
 using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.Decompiler.Util;
+using ICSharpCode.ILSpyX;
 
 namespace ICSharpCode.ILSpy.Analyzers
 {
diff --git a/ILSpy/Analyzers/AnalyzerSearchTreeNode.cs b/ILSpy/Analyzers/AnalyzerSearchTreeNode.cs
index f0965c3bf..6b908d1ff 100644
--- a/ILSpy/Analyzers/AnalyzerSearchTreeNode.cs
+++ b/ILSpy/Analyzers/AnalyzerSearchTreeNode.cs
@@ -24,6 +24,7 @@ using System.Threading;
 using ICSharpCode.Decompiler.TypeSystem;
 using ICSharpCode.ILSpy.Analyzers.TreeNodes;
 using ICSharpCode.ILSpy.TreeNodes;
+using ICSharpCode.ILSpyX;
 
 namespace ICSharpCode.ILSpy.Analyzers
 {
diff --git a/ILSpy/Analyzers/AnalyzerTreeNode.cs b/ILSpy/Analyzers/AnalyzerTreeNode.cs
index 96a1a1a5e..5f9b39650 100644
--- a/ILSpy/Analyzers/AnalyzerTreeNode.cs
+++ b/ILSpy/Analyzers/AnalyzerTreeNode.cs
@@ -20,6 +20,7 @@ using System.Collections.Generic;
 using System.Collections.Specialized;
 using System.Linq;
 
+using ICSharpCode.ILSpyX;
 using ICSharpCode.TreeView;
 
 namespace ICSharpCode.ILSpy.Analyzers
diff --git a/ILSpy/Analyzers/AnalyzerTreeView.cs b/ILSpy/Analyzers/AnalyzerTreeView.cs
index 261e52b18..500f40f79 100644
--- a/ILSpy/Analyzers/AnalyzerTreeView.cs
+++ b/ILSpy/Analyzers/AnalyzerTreeView.cs
@@ -26,6 +26,7 @@ using ICSharpCode.Decompiler.TypeSystem;
 using ICSharpCode.ILSpy.Analyzers.TreeNodes;
 using ICSharpCode.ILSpy.Docking;
 using ICSharpCode.ILSpy.ViewModels;
+using ICSharpCode.ILSpyX;
 using ICSharpCode.TreeView;
 
 namespace ICSharpCode.ILSpy.Analyzers
diff --git a/ILSpy/AssemblyListManager.cs b/ILSpy/AssemblyListManager.cs
deleted file mode 100644
index 8000f3b51..000000000
--- a/ILSpy/AssemblyListManager.cs
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
-// 
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this
-// software and associated documentation files (the "Software"), to deal in the Software
-// without restriction, including without limitation the rights to use, copy, modify, merge,
-// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
-// to whom the Software is furnished to do so, subject to the following conditions:
-// 
-// The above copyright notice and this permission notice shall be included in all copies or
-// substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
-// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Xml.Linq;
-
-using ICSharpCode.ILSpy.ViewModels;
-
-namespace ICSharpCode.ILSpy
-{
-	/// <summary>
-	/// Manages the available assembly lists.
-	/// 
-	/// Contains the list of list names; and provides methods for loading/saving and creating/deleting lists.
-	/// </summary>
-	sealed class AssemblyListManager
-	{
-		ILSpySettings spySettings;
-
-		public AssemblyListManager(ILSpySettings spySettings)
-		{
-			this.spySettings = spySettings;
-			XElement doc = spySettings["AssemblyLists"];
-			foreach (var list in doc.Elements("List"))
-			{
-				AssemblyLists.Add((string)list.Attribute("name"));
-			}
-		}
-
-		public ObservableCollection<string> AssemblyLists { get; } = new ObservableCollection<string>();
-
-		/// <summary>
-		/// Loads an assembly list from the ILSpySettings.
-		/// If no list with the specified name is found, the default list is loaded instead.
-		/// </summary>
-		public AssemblyList LoadList(ILSpySettings settings, string listName)
-		{
-			this.spySettings = settings;
-			AssemblyList list = DoLoadList(spySettings, listName);
-			if (!AssemblyLists.Contains(list.ListName))
-				AssemblyLists.Add(list.ListName);
-			return list;
-		}
-
-		AssemblyList DoLoadList(ILSpySettings spySettings, string listName)
-		{
-			XElement doc = spySettings["AssemblyLists"];
-			if (listName != null)
-			{
-				foreach (var list in doc.Elements("List"))
-				{
-					if ((string)list.Attribute("name") == listName)
-					{
-						return new AssemblyList(list);
-					}
-				}
-			}
-			return new AssemblyList(listName ?? DefaultListName);
-		}
-
-		public bool CloneList(string selectedAssemblyList, string newListName)
-		{
-			var list = DoLoadList(spySettings, selectedAssemblyList);
-			var newList = new AssemblyList(list, newListName);
-			return CreateList(newList);
-		}
-
-		public bool RenameList(string selectedAssemblyList, string newListName)
-		{
-			var list = DoLoadList(spySettings, selectedAssemblyList);
-			var newList = new AssemblyList(list, newListName);
-			return DeleteList(selectedAssemblyList) && CreateList(newList);
-		}
-
-		public const string DefaultListName = "(Default)";
-
-		/// <summary>
-		/// Saves the specifies assembly list into the config file.
-		/// </summary>
-		public static void SaveList(AssemblyList list)
-		{
-			ILSpySettings.Update(
-				delegate (XElement root) {
-					XElement doc = root.Element("AssemblyLists");
-					if (doc == null)
-					{
-						doc = new XElement("AssemblyLists");
-						root.Add(doc);
-					}
-					XElement listElement = doc.Elements("List").FirstOrDefault(e => (string)e.Attribute("name") == list.ListName);
-					if (listElement != null)
-						listElement.ReplaceWith(list.SaveAsXml());
-					else
-						doc.Add(list.SaveAsXml());
-				});
-		}
-
-		public bool CreateList(AssemblyList list)
-		{
-			if (!AssemblyLists.Contains(list.ListName))
-			{
-				AssemblyLists.Add(list.ListName);
-				SaveList(list);
-				return true;
-			}
-			return false;
-		}
-
-		public bool DeleteList(string Name)
-		{
-			if (AssemblyLists.Remove(Name))
-			{
-				ILSpySettings.Update(
-					delegate (XElement root) {
-						XElement doc = root.Element("AssemblyLists");
-						if (doc == null)
-						{
-							return;
-						}
-						XElement listElement = doc.Elements("List").FirstOrDefault(e => (string)e.Attribute("name") == Name);
-						if (listElement != null)
-							listElement.Remove();
-					});
-				return true;
-			}
-			return false;
-		}
-
-		public void ClearAll()
-		{
-			AssemblyLists.Clear();
-			ILSpySettings.Update(
-				delegate (XElement root) {
-					XElement doc = root.Element("AssemblyLists");
-					if (doc == null)
-					{
-						return;
-					}
-					doc.Remove();
-				});
-		}
-
-		public void CreateDefaultAssemblyLists()
-		{
-			if (AssemblyLists.Count > 0)
-				return;
-
-			if (!AssemblyLists.Contains(ManageAssemblyListsViewModel.DotNet4List))
-			{
-				AssemblyList dotnet4 = ManageAssemblyListsViewModel.CreateDefaultList(ManageAssemblyListsViewModel.DotNet4List);
-				if (dotnet4.Count > 0)
-				{
-					CreateList(dotnet4);
-				}
-			}
-
-			if (!AssemblyLists.Contains(ManageAssemblyListsViewModel.DotNet35List))
-			{
-				AssemblyList dotnet35 = ManageAssemblyListsViewModel.CreateDefaultList(ManageAssemblyListsViewModel.DotNet35List);
-				if (dotnet35.Count > 0)
-				{
-					CreateList(dotnet35);
-				}
-			}
-
-			if (!AssemblyLists.Contains(ManageAssemblyListsViewModel.ASPDotNetMVC3List))
-			{
-				AssemblyList mvc = ManageAssemblyListsViewModel.CreateDefaultList(ManageAssemblyListsViewModel.ASPDotNetMVC3List);
-				if (mvc.Count > 0)
-				{
-					CreateList(mvc);
-				}
-			}
-		}
-	}
-}
diff --git a/ILSpy/Commands/DecompileAllCommand.cs b/ILSpy/Commands/DecompileAllCommand.cs
index ca6f926c5..bda0d7a93 100644
--- a/ILSpy/Commands/DecompileAllCommand.cs
+++ b/ILSpy/Commands/DecompileAllCommand.cs
@@ -27,6 +27,7 @@ using System.Threading.Tasks;
 using ICSharpCode.Decompiler;
 using ICSharpCode.ILSpy.Properties;
 using ICSharpCode.ILSpy.TextView;
+using ICSharpCode.ILSpyX;
 
 namespace ICSharpCode.ILSpy
 {
diff --git a/ILSpy/Commands/DisassembleAllCommand.cs b/ILSpy/Commands/DisassembleAllCommand.cs
index 849dd15d7..a127c5203 100644
--- a/ILSpy/Commands/DisassembleAllCommand.cs
+++ b/ILSpy/Commands/DisassembleAllCommand.cs
@@ -25,6 +25,7 @@ using System.Threading.Tasks;
 
 using ICSharpCode.ILSpy.Properties;
 using ICSharpCode.ILSpy.TextView;
+using ICSharpCode.ILSpyX;
 
 namespace ICSharpCode.ILSpy
 {
diff --git a/ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs b/ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs
index 79974c89b..57076e517 100644
--- a/ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs
+++ b/ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs
@@ -27,6 +27,7 @@ using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
 using ICSharpCode.ILSpy.Properties;
 using ICSharpCode.ILSpy.TextView;
 using ICSharpCode.ILSpy.TreeNodes;
+using ICSharpCode.ILSpyX;
 
 using Microsoft.Win32;
 
diff --git a/ILSpy/Commands/GeneratePdbContextMenuEntry.cs b/ILSpy/Commands/GeneratePdbContextMenuEntry.cs
index 473360ff5..351e96e10 100644
--- a/ILSpy/Commands/GeneratePdbContextMenuEntry.cs
+++ b/ILSpy/Commands/GeneratePdbContextMenuEntry.cs
@@ -30,6 +30,7 @@ using ICSharpCode.Decompiler.DebugInfo;
 using ICSharpCode.ILSpy.Properties;
 using ICSharpCode.ILSpy.TextView;
 using ICSharpCode.ILSpy.TreeNodes;
+using ICSharpCode.ILSpyX;
 
 using Microsoft.Win32;
 
diff --git a/ILSpy/Commands/SaveCodeContextMenuEntry.cs b/ILSpy/Commands/SaveCodeContextMenuEntry.cs
index 0a849f134..a16316fac 100644
--- a/ILSpy/Commands/SaveCodeContextMenuEntry.cs
+++ b/ILSpy/Commands/SaveCodeContextMenuEntry.cs
@@ -22,6 +22,7 @@ using System.IO;
 using System.Linq;
 using System.Windows;
 
+using ICSharpCode.ILSpy.Options;
 using ICSharpCode.ILSpy.Properties;
 using ICSharpCode.ILSpy.TreeNodes;
 using ICSharpCode.ILSpy.ViewModels;
diff --git a/ILSpy/Commands/SortAssemblyListCommand.cs b/ILSpy/Commands/SortAssemblyListCommand.cs
index a57999a71..29cd8ae05 100644
--- a/ILSpy/Commands/SortAssemblyListCommand.cs
+++ b/ILSpy/Commands/SortAssemblyListCommand.cs
@@ -20,6 +20,7 @@ using System;
 using System.Collections.Generic;
 
 using ICSharpCode.ILSpy.Properties;
+using ICSharpCode.ILSpyX;
 using ICSharpCode.TreeView;
 
 namespace ICSharpCode.ILSpy
diff --git a/ILSpy/EntityReference.cs b/ILSpy/EntityReference.cs
index 1ff1ce7e7..86ebd55a2 100644
--- a/ILSpy/EntityReference.cs
+++ b/ILSpy/EntityReference.cs
@@ -21,6 +21,7 @@ using System.Diagnostics;
 using System.Reflection.Metadata;
 
 using ICSharpCode.Decompiler.Metadata;
+using ICSharpCode.ILSpyX;
 
 namespace ICSharpCode.ILSpy
 {
diff --git a/ILSpy/ExtensionMethods.cs b/ILSpy/ExtensionMethods.cs
index de2bd4189..732dc7b4e 100644
--- a/ILSpy/ExtensionMethods.cs
+++ b/ILSpy/ExtensionMethods.cs
@@ -26,8 +26,11 @@ using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Media;
 
+using ICSharpCode.Decompiler.Metadata;
+using ICSharpCode.Decompiler.TypeSystem;
 using ICSharpCode.Decompiler.Util;
 using ICSharpCode.ILSpy.Options;
+using ICSharpCode.ILSpyX;
 
 namespace ICSharpCode.ILSpy
 {
@@ -36,134 +39,17 @@ namespace ICSharpCode.ILSpy
 	/// </summary>
 	public static class ExtensionMethods
 	{
-		public static void AddRange<T>(this ICollection<T> list, IEnumerable<T> items)
+		public static string ToSuffixString(this System.Reflection.Metadata.EntityHandle handle, bool showMetadataTokens, bool useBase10)
 		{
-			foreach (T item in items)
-				if (!list.Contains(item))
-					list.Add(item);
-		}
-
-		public static T? PeekOrDefault<T>(this Stack<T> stack)
-		{
-			if (stack.Count == 0)
-				return default(T);
-			return stack.Peek();
-		}
-
-		public static int BinarySearch<T>(this IList<T> list, T item, int start, int count, IComparer<T> comparer)
-		{
-			if (list == null)
-				throw new ArgumentNullException(nameof(list));
-			if (start < 0 || start >= list.Count)
-				throw new ArgumentOutOfRangeException(nameof(start), start, "Value must be between 0 and " + (list.Count - 1));
-			if (count < 0 || count > list.Count - start)
-				throw new ArgumentOutOfRangeException(nameof(count), count, "Value must be between 0 and " + (list.Count - start));
-			int end = start + count - 1;
-			while (start <= end)
-			{
-				int pivot = (start + end) / 2;
-				int result = comparer.Compare(item, list[pivot]);
-				if (result == 0)
-					return pivot;
-				if (result < 0)
-					end = pivot - 1;
-				else
-					start = pivot + 1;
-			}
-			return ~start;
-		}
-
-		public static int BinarySearch<T, TKey>(this IList<T> instance, TKey itemKey, Func<T, TKey> keySelector)
-			where TKey : IComparable<TKey>, IComparable
-		{
-			if (instance == null)
-				throw new ArgumentNullException(nameof(instance));
-			if (keySelector == null)
-				throw new ArgumentNullException(nameof(keySelector));
-
-			int start = 0;
-			int end = instance.Count - 1;
-
-			while (start <= end)
-			{
-				int m = (start + end) / 2;
-				TKey key = keySelector(instance[m]);
-				int result = key.CompareTo(itemKey);
-				if (result == 0)
-					return m;
-				if (result < 0)
-					start = m + 1;
-				else
-					end = m - 1;
-			}
-			return ~start;
-		}
-
-		public static void InsertSorted<T>(this IList<T> list, T item, IComparer<T> comparer)
-		{
-			if (list == null)
-				throw new ArgumentNullException(nameof(list));
-			if (comparer == null)
-				throw new ArgumentNullException(nameof(comparer));
-
-			if (list.Count == 0)
-			{
-				list.Add(item);
-			}
-			else
-			{
-				int index = list.BinarySearch(item, 0, list.Count, comparer);
-				list.Insert(index < 0 ? ~index : index, item);
-			}
-		}
-
-		internal static void Deconstruct<TKey, TValue>(this KeyValuePair<TKey, TValue> pair, out TKey key, out TValue value)
-		{
-			key = pair.Key;
-			value = pair.Value;
-		}
-
-		internal static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T>? inst) => inst ?? Enumerable.Empty<T>();
-		internal static IEnumerable EmptyIfNull(this IEnumerable? inst) => inst ?? Enumerable.Empty<object>();
-		internal static IList<T> EmptyIfNull<T>(this IList<T>? inst) => inst ?? EmptyList<T>.Instance;
-		internal static IList EmptyIfNull(this IList? inst) => inst ?? Array.Empty<object>();
-
-		public static string ToSuffixString(this System.Reflection.Metadata.EntityHandle handle)
-		{
-			if (!DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokens)
+			if (!showMetadataTokens)
 				return string.Empty;
 
 			int token = System.Reflection.Metadata.Ecma335.MetadataTokens.GetToken(handle);
-			if (DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokensInBase10)
+			if (useBase10)
 				return " @" + token;
 			return " @" + token.ToString("x8");
 		}
 
-		public static string ToSuffixString(this System.Reflection.Metadata.MethodDefinitionHandle handle)
-		{
-			return ToSuffixString((System.Reflection.Metadata.EntityHandle)handle);
-		}
-
-		public static string ToSuffixString(this System.Reflection.Metadata.PropertyDefinitionHandle handle)
-		{
-			return ToSuffixString((System.Reflection.Metadata.EntityHandle)handle);
-		}
-
-		public static string ToSuffixString(this System.Reflection.Metadata.EventDefinitionHandle handle)
-		{
-			return ToSuffixString((System.Reflection.Metadata.EntityHandle)handle);
-		}
-
-		public static string ToSuffixString(this System.Reflection.Metadata.FieldDefinitionHandle handle)
-		{
-			return ToSuffixString((System.Reflection.Metadata.EntityHandle)handle);
-		}
-
-		public static string ToSuffixString(this System.Reflection.Metadata.TypeDefinitionHandle handle)
-		{
-			return ToSuffixString((System.Reflection.Metadata.EntityHandle)handle);
-		}
-
 		/// <summary>
 		/// Takes at most <paramref name="length" /> first characters from string, and appends '...' if string is longer.
 		/// String can be null.
@@ -190,6 +76,11 @@ namespace ICSharpCode.ILSpy
 			return result;
 		}
 
+		public static ICompilation? GetTypeSystemWithCurrentOptionsOrNull(this PEFile file)
+		{
+			return LoadedAssemblyExtensions.GetLoadedAssembly(file).GetTypeSystemOrNull(DecompilerTypeSystem.GetOptions(new DecompilationOptions().DecompilerSettings));
+		}
+
 		#region DPI independence
 		public static Rect TransformToDevice(this Rect rect, Visual visual)
 		{
diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj
index 9f2cd7532..87224fc0e 100644
--- a/ILSpy/ILSpy.csproj
+++ b/ILSpy/ILSpy.csproj
@@ -56,7 +56,6 @@
   </ItemGroup>
 
   <ItemGroup>
-    <Compile Include="..\ICSharpCode.Decompiler.PdbProvider.Cecil\MonoCecilDebugInfoProvider.cs" Link="DebugInfo\MonoCecilDebugInfoProvider.cs" />
     <EmbeddedResource Include="..\doc\ILSpyAboutPage.txt" />
     <EmbeddedResource Include="..\doc\ILSpyAboutPage_zh_Hans.txt" />
     <EmbeddedResource Include="..\doc\third-party-notices.txt" />
@@ -94,6 +93,7 @@
   </ItemGroup>
 
   <ItemGroup>
+    <ProjectReference Include="..\ICSharpCode.ILSpyX\ICSharpCode.ILSpyX.csproj" />
     <ProjectReference Include="..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj" />
     <ProjectReference Include="..\SharpTreeView\ICSharpCode.TreeView.csproj" />
   </ItemGroup>
diff --git a/ILSpy/ILSpySettings.cs b/ILSpy/ILSpySettings.cs
index 4da939c4b..77eb58bc9 100644
--- a/ILSpy/ILSpySettings.cs
+++ b/ILSpy/ILSpySettings.cs
@@ -22,12 +22,14 @@ using System.Threading;
 using System.Xml;
 using System.Xml.Linq;
 
+using ICSharpCode.ILSpyX;
+
 namespace ICSharpCode.ILSpy
 {
 	/// <summary>
 	/// Manages IL Spy settings.
 	/// </summary>
-	public class ILSpySettings
+	public class ILSpySettings : ISettingsProvider
 	{
 		readonly XElement root;
 
@@ -124,6 +126,11 @@ namespace ICSharpCode.ILSpy
 			}
 		}
 
+		void ISettingsProvider.Update(Action<XElement> action)
+		{
+			Update(action);
+		}
+
 		static string GetConfigFile()
 		{
 			if (App.CommandLineArguments.ConfigFile != null)
@@ -134,6 +141,11 @@ namespace ICSharpCode.ILSpy
 			return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ICSharpCode\\ILSpy.xml");
 		}
 
+		ISettingsProvider ISettingsProvider.Load()
+		{
+			return Load();
+		}
+
 		const string ConfigFileMutex = "01A91708-49D1-410D-B8EB-4DE2662B3971";
 
 		/// <summary>
diff --git a/ILSpy/Languages/CSharpHighlightingTokenWriter.cs b/ILSpy/Languages/CSharpHighlightingTokenWriter.cs
index 475cac06a..ab437bfa4 100644
--- a/ILSpy/Languages/CSharpHighlightingTokenWriter.cs
+++ b/ILSpy/Languages/CSharpHighlightingTokenWriter.cs
@@ -24,6 +24,7 @@ using ICSharpCode.Decompiler.CSharp;
 using ICSharpCode.Decompiler.CSharp.OutputVisitor;
 using ICSharpCode.Decompiler.CSharp.Syntax;
 using ICSharpCode.Decompiler.TypeSystem;
+using ICSharpCode.ILSpyX.Extensions;
 
 namespace ICSharpCode.ILSpy
 {
diff --git a/ILSpy/Languages/CSharpILMixedLanguage.cs b/ILSpy/Languages/CSharpILMixedLanguage.cs
index 2fa6a32f8..2de42e3aa 100644
--- a/ILSpy/Languages/CSharpILMixedLanguage.cs
+++ b/ILSpy/Languages/CSharpILMixedLanguage.cs
@@ -36,6 +36,8 @@ using ICSharpCode.Decompiler.Disassembler;
 using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.Decompiler.TypeSystem;
 using ICSharpCode.Decompiler.Util;
+using ICSharpCode.ILSpyX;
+using ICSharpCode.ILSpyX.Extensions;
 
 namespace ICSharpCode.ILSpy
 {
diff --git a/ILSpy/Languages/CSharpLanguage.cs b/ILSpy/Languages/CSharpLanguage.cs
index 6d0e2d378..5bb903410 100644
--- a/ILSpy/Languages/CSharpLanguage.cs
+++ b/ILSpy/Languages/CSharpLanguage.cs
@@ -42,8 +42,10 @@ using ICSharpCode.Decompiler.Output;
 using ICSharpCode.Decompiler.Solution;
 using ICSharpCode.Decompiler.TypeSystem;
 using ICSharpCode.Decompiler.Util;
+using ICSharpCode.ILSpy.Options;
 using ICSharpCode.ILSpy.TextView;
 using ICSharpCode.ILSpy.TreeNodes;
+using ICSharpCode.ILSpyX;
 
 namespace ICSharpCode.ILSpy
 {
@@ -496,7 +498,7 @@ namespace ICSharpCode.ILSpy
 			readonly DecompilationOptions options;
 
 			public ILSpyWholeProjectDecompiler(LoadedAssembly assembly, DecompilationOptions options)
-				: base(options.DecompilerSettings, assembly.GetAssemblyResolver(), assembly.GetAssemblyReferenceClassifier(), assembly.GetDebugInfoOrNull())
+				: base(options.DecompilerSettings, assembly.GetAssemblyResolver(), assembly.GetAssemblyReferenceClassifier(options.DecompilerSettings.ApplyWindowsRuntimeProjections), assembly.GetDebugInfoOrNull())
 			{
 				this.assembly = assembly;
 				this.options = options;
diff --git a/ILSpy/Languages/ILAstLanguage.cs b/ILSpy/Languages/ILAstLanguage.cs
index 7d4156168..918558451 100644
--- a/ILSpy/Languages/ILAstLanguage.cs
+++ b/ILSpy/Languages/ILAstLanguage.cs
@@ -29,6 +29,7 @@ using ICSharpCode.Decompiler.IL.Transforms;
 using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.Decompiler.TypeSystem;
 using ICSharpCode.ILSpy.ViewModels;
+using ICSharpCode.ILSpyX;
 
 using static System.Reflection.Metadata.PEReaderExtensions;
 
diff --git a/ILSpy/Languages/ILLanguage.cs b/ILSpy/Languages/ILLanguage.cs
index d31068de4..a57e0266e 100644
--- a/ILSpy/Languages/ILLanguage.cs
+++ b/ILSpy/Languages/ILLanguage.cs
@@ -30,6 +30,7 @@ using ICSharpCode.Decompiler.Solution;
 using ICSharpCode.Decompiler.TypeSystem;
 using ICSharpCode.Decompiler.Util;
 using ICSharpCode.ILSpy.TextView;
+using ICSharpCode.ILSpyX;
 
 namespace ICSharpCode.ILSpy
 {
diff --git a/ILSpy/Languages/IResourceFileHandler.cs b/ILSpy/Languages/IResourceFileHandler.cs
index 3ea4fb6bc..43270bec4 100644
--- a/ILSpy/Languages/IResourceFileHandler.cs
+++ b/ILSpy/Languages/IResourceFileHandler.cs
@@ -18,6 +18,8 @@
 
 using System.IO;
 
+using ICSharpCode.ILSpyX;
+
 namespace ICSharpCode.ILSpy
 {
 	public interface IResourceFileHandler
diff --git a/ILSpy/Languages/Language.cs b/ILSpy/Languages/Language.cs
index d9fa79827..0b7cc48e8 100644
--- a/ILSpy/Languages/Language.cs
+++ b/ILSpy/Languages/Language.cs
@@ -29,6 +29,7 @@ using ICSharpCode.Decompiler.Solution;
 using ICSharpCode.Decompiler.TypeSystem;
 using ICSharpCode.Decompiler.TypeSystem.Implementation;
 using ICSharpCode.Decompiler.Util;
+using ICSharpCode.ILSpyX;
 
 using SRM = System.Reflection.Metadata;
 
diff --git a/ILSpy/MainWindow.xaml.cs b/ILSpy/MainWindow.xaml.cs
index 1fb4a38c7..725464427 100644
--- a/ILSpy/MainWindow.xaml.cs
+++ b/ILSpy/MainWindow.xaml.cs
@@ -49,6 +49,7 @@ using ICSharpCode.ILSpy.TextView;
 using ICSharpCode.ILSpy.Themes;
 using ICSharpCode.ILSpy.TreeNodes;
 using ICSharpCode.ILSpy.ViewModels;
+using ICSharpCode.ILSpyX;
 using ICSharpCode.TreeView;
 
 using Microsoft.Win32;
@@ -850,12 +851,12 @@ namespace ICSharpCode.ILSpy
 			{
 				// Load AssemblyList only in Loaded event so that WPF is initialized before we start the CPU-heavy stuff.
 				// This makes the UI come up a bit faster.
-				this.assemblyList = AssemblyListManager.LoadList(spySettings, sessionSettings.ActiveAssemblyList);
+				this.assemblyList = AssemblyListManager.LoadList(sessionSettings.ActiveAssemblyList);
 			}
 			else
 			{
-				this.assemblyList = new AssemblyList(AssemblyListManager.DefaultListName);
 				AssemblyListManager.ClearAll();
+				this.assemblyList = AssemblyListManager.CreateList(AssemblyListManager.DefaultListName);
 			}
 
 			HandleCommandLineArguments(App.CommandLineArguments);
@@ -983,7 +984,7 @@ namespace ICSharpCode.ILSpy
 
 		public void ShowAssemblyList(string name)
 		{
-			AssemblyList list = this.AssemblyListManager.LoadList(ILSpySettings.Load(), name);
+			AssemblyList list = this.AssemblyListManager.LoadList(name);
 			//Only load a new list when it is a different one
 			if (list.ListName != CurrentAssemblyList.ListName)
 			{
@@ -1409,7 +1410,7 @@ namespace ICSharpCode.ILSpy
 			{
 				refreshInProgress = true;
 				var path = GetPathForNode(AssemblyTreeView.SelectedItem as SharpTreeNode);
-				ShowAssemblyList(AssemblyListManager.LoadList(ILSpySettings.Load(), assemblyList.ListName));
+				ShowAssemblyList(AssemblyListManager.LoadList(assemblyList.ListName));
 				SelectNode(FindNodeByPath(path, true), false, false);
 			}
 			finally
diff --git a/ILSpy/MainWindowViewModel.cs b/ILSpy/MainWindowViewModel.cs
index 6568e18db..16b2cc0fd 100644
--- a/ILSpy/MainWindowViewModel.cs
+++ b/ILSpy/MainWindowViewModel.cs
@@ -17,7 +17,7 @@
 // DEALINGS IN THE SOFTWARE.
 
 using ICSharpCode.ILSpy.Docking;
-using ICSharpCode.ILSpy.ViewModels;
+using ICSharpCode.ILSpyX;
 
 namespace ICSharpCode.ILSpy
 {
diff --git a/ILSpy/Metadata/CoffHeaderTreeNode.cs b/ILSpy/Metadata/CoffHeaderTreeNode.cs
index 7764ce903..8e7c3fe57 100644
--- a/ILSpy/Metadata/CoffHeaderTreeNode.cs
+++ b/ILSpy/Metadata/CoffHeaderTreeNode.cs
@@ -26,6 +26,7 @@ using ICSharpCode.Decompiler;
 using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.ILSpy.TreeNodes;
 using ICSharpCode.ILSpy.ViewModels;
+using ICSharpCode.ILSpyX.Extensions;
 
 namespace ICSharpCode.ILSpy.Metadata
 {
diff --git a/ILSpy/Metadata/OptionalHeaderTreeNode.cs b/ILSpy/Metadata/OptionalHeaderTreeNode.cs
index 76a46bcbf..cbd67a292 100644
--- a/ILSpy/Metadata/OptionalHeaderTreeNode.cs
+++ b/ILSpy/Metadata/OptionalHeaderTreeNode.cs
@@ -24,8 +24,8 @@ using System.Windows.Data;
 
 using ICSharpCode.Decompiler;
 using ICSharpCode.Decompiler.Metadata;
-using ICSharpCode.ILSpy.TextView;
 using ICSharpCode.ILSpy.TreeNodes;
+using ICSharpCode.ILSpyX.Extensions;
 
 namespace ICSharpCode.ILSpy.Metadata
 {
diff --git a/ILSpy/Options/DecompilerSettingsPanel.xaml.cs b/ILSpy/Options/DecompilerSettingsPanel.xaml.cs
index d2d9402dc..41bfb1b5f 100644
--- a/ILSpy/Options/DecompilerSettingsPanel.xaml.cs
+++ b/ILSpy/Options/DecompilerSettingsPanel.xaml.cs
@@ -19,15 +19,11 @@
 using System.ComponentModel;
 using System.Linq;
 using System.Reflection;
-using System.Runtime.CompilerServices;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Data;
 using System.Xml.Linq;
 
-using ICSharpCode.ILSpy.Properties;
-using ICSharpCode.ILSpy.TreeNodes;
-
 namespace ICSharpCode.ILSpy.Options
 {
 	/// <summary>
@@ -43,11 +39,6 @@ namespace ICSharpCode.ILSpy.Options
 
 		static Decompiler.DecompilerSettings currentDecompilerSettings;
 
-		internal static void TestSetup(Decompiler.DecompilerSettings settings)
-		{
-			currentDecompilerSettings = settings;
-		}
-
 		public static Decompiler.DecompilerSettings CurrentDecompilerSettings {
 			get {
 				return currentDecompilerSettings ?? (currentDecompilerSettings = LoadDecompilerSettings(ILSpySettings.Load()));
@@ -71,13 +62,13 @@ namespace ICSharpCode.ILSpy.Options
 
 		public void Load(ILSpySettings settings)
 		{
-			this.DataContext = new DecompilerSettings(LoadDecompilerSettings(settings));
+			this.DataContext = new DecompilerSettingsViewModel(LoadDecompilerSettings(settings));
 		}
 
 		public void Save(XElement root)
 		{
 			XElement section = new XElement("DecompilerSettings");
-			var newSettings = ((DecompilerSettings)this.DataContext).ToDecompilerSettings();
+			var newSettings = ((DecompilerSettingsViewModel)this.DataContext).ToDecompilerSettings();
 			var properties = typeof(Decompiler.DecompilerSettings).GetProperties()
 				.Where(p => p.GetCustomAttribute<BrowsableAttribute>()?.Browsable != false);
 			foreach (var p in properties)
@@ -145,81 +136,7 @@ namespace ICSharpCode.ILSpy.Options
 		public void LoadDefaults()
 		{
 			currentDecompilerSettings = new Decompiler.DecompilerSettings();
-			this.DataContext = new DecompilerSettings(currentDecompilerSettings);
-		}
-	}
-
-	public class DecompilerSettings : INotifyPropertyChanged
-	{
-		public CSharpDecompilerSetting[] Settings { get; set; }
-
-		public DecompilerSettings(Decompiler.DecompilerSettings settings)
-		{
-			Settings = typeof(Decompiler.DecompilerSettings).GetProperties()
-				.Where(p => p.GetCustomAttribute<BrowsableAttribute>()?.Browsable != false)
-				.Select(p => new CSharpDecompilerSetting(p) { IsEnabled = (bool)p.GetValue(settings) })
-				.OrderBy(item => item.Category, NaturalStringComparer.Instance)
-				.ThenBy(item => item.Description)
-				.ToArray();
-		}
-
-		public event PropertyChangedEventHandler PropertyChanged;
-
-		protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
-		{
-			PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
-		}
-
-		public Decompiler.DecompilerSettings ToDecompilerSettings()
-		{
-			var settings = new Decompiler.DecompilerSettings();
-			foreach (var item in Settings)
-			{
-				item.Property.SetValue(settings, item.IsEnabled);
-			}
-			return settings;
-		}
-	}
-
-	public class CSharpDecompilerSetting : INotifyPropertyChanged
-	{
-		bool isEnabled;
-
-		public CSharpDecompilerSetting(PropertyInfo p)
-		{
-			this.Property = p;
-			this.Category = GetResourceString(p.GetCustomAttribute<CategoryAttribute>()?.Category ?? Resources.Other);
-			this.Description = GetResourceString(p.GetCustomAttribute<DescriptionAttribute>()?.Description ?? p.Name);
-		}
-
-		public PropertyInfo Property { get; }
-
-		public bool IsEnabled {
-			get => isEnabled;
-			set {
-				if (value != isEnabled)
-				{
-					isEnabled = value;
-					OnPropertyChanged();
-				}
-			}
-		}
-
-		public string Description { get; set; }
-
-		public string Category { get; set; }
-
-		public event PropertyChangedEventHandler PropertyChanged;
-
-		protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
-		{
-			PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
-		}
-
-		static string GetResourceString(string key)
-		{
-			var str = !string.IsNullOrEmpty(key) ? Resources.ResourceManager.GetString(key) : null;
-			return string.IsNullOrEmpty(key) || string.IsNullOrEmpty(str) ? key : str;
+			this.DataContext = new DecompilerSettingsViewModel(currentDecompilerSettings);
 		}
 	}
 }
diff --git a/ILSpy/Options/DecompilerSettingsViewModel.cs b/ILSpy/Options/DecompilerSettingsViewModel.cs
new file mode 100644
index 000000000..b7ce36fbe
--- /dev/null
+++ b/ILSpy/Options/DecompilerSettingsViewModel.cs
@@ -0,0 +1,101 @@
+// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this
+// software and associated documentation files (the "Software"), to deal in the Software
+// without restriction, including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
+// to whom the Software is furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in all copies or
+// substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+using ICSharpCode.ILSpy.Properties;
+using ICSharpCode.ILSpy.TreeNodes;
+
+namespace ICSharpCode.ILSpy.Options
+{
+	public class DecompilerSettingsViewModel : INotifyPropertyChanged
+	{
+		public CSharpDecompilerSetting[] Settings { get; set; }
+
+		public DecompilerSettingsViewModel(Decompiler.DecompilerSettings settings)
+		{
+			Settings = typeof(Decompiler.DecompilerSettings).GetProperties()
+				.Where(p => p.GetCustomAttribute<BrowsableAttribute>()?.Browsable != false)
+				.Select(p => new CSharpDecompilerSetting(p) { IsEnabled = (bool)p.GetValue(settings) })
+				.OrderBy(item => item.Category, NaturalStringComparer.Instance)
+				.ThenBy(item => item.Description)
+				.ToArray();
+		}
+
+		public event PropertyChangedEventHandler PropertyChanged;
+
+		protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
+		{
+			PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+		}
+
+		public Decompiler.DecompilerSettings ToDecompilerSettings()
+		{
+			var settings = new Decompiler.DecompilerSettings();
+			foreach (var item in Settings)
+			{
+				item.Property.SetValue(settings, item.IsEnabled);
+			}
+			return settings;
+		}
+	}
+	public class CSharpDecompilerSetting : INotifyPropertyChanged
+	{
+		bool isEnabled;
+
+		public CSharpDecompilerSetting(PropertyInfo p)
+		{
+			this.Property = p;
+			this.Category = GetResourceString(p.GetCustomAttribute<CategoryAttribute>()?.Category ?? Resources.Other);
+			this.Description = GetResourceString(p.GetCustomAttribute<DescriptionAttribute>()?.Description ?? p.Name);
+		}
+
+		public PropertyInfo Property { get; }
+
+		public bool IsEnabled {
+			get => isEnabled;
+			set {
+				if (value != isEnabled)
+				{
+					isEnabled = value;
+					OnPropertyChanged();
+				}
+			}
+		}
+
+		public string Description { get; set; }
+
+		public string Category { get; set; }
+
+		public event PropertyChangedEventHandler PropertyChanged;
+
+		protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
+		{
+			PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+		}
+
+		static string GetResourceString(string key)
+		{
+			var str = !string.IsNullOrEmpty(key) ? Resources.ResourceManager.GetString(key) : null;
+			return string.IsNullOrEmpty(key) || string.IsNullOrEmpty(str) ? key : str;
+		}
+	}
+}
diff --git a/ILSpy/Search/SearchPane.cs b/ILSpy/Search/SearchPane.cs
index 3fb677d35..7f81b1972 100644
--- a/ILSpy/Search/SearchPane.cs
+++ b/ILSpy/Search/SearchPane.cs
@@ -37,6 +37,8 @@ using ICSharpCode.ILSpy.Docking;
 using ICSharpCode.ILSpy.Options;
 using ICSharpCode.ILSpy.Search;
 using ICSharpCode.ILSpy.ViewModels;
+using ICSharpCode.ILSpyX;
+using ICSharpCode.ILSpyX.Extensions;
 
 namespace ICSharpCode.ILSpy
 {
diff --git a/ILSpy/SolutionWriter.cs b/ILSpy/SolutionWriter.cs
index a02cfe87b..b8a2700ef 100644
--- a/ILSpy/SolutionWriter.cs
+++ b/ILSpy/SolutionWriter.cs
@@ -29,6 +29,7 @@ using ICSharpCode.Decompiler;
 using ICSharpCode.Decompiler.Solution;
 using ICSharpCode.Decompiler.Util;
 using ICSharpCode.ILSpy.TextView;
+using ICSharpCode.ILSpyX;
 
 namespace ICSharpCode.ILSpy
 {
diff --git a/ILSpy/TextView/DecompilerTextView.cs b/ILSpy/TextView/DecompilerTextView.cs
index 2c17dd3df..0ebaf6219 100644
--- a/ILSpy/TextView/DecompilerTextView.cs
+++ b/ILSpy/TextView/DecompilerTextView.cs
@@ -56,6 +56,7 @@ using ICSharpCode.ILSpy.Options;
 using ICSharpCode.ILSpy.Themes;
 using ICSharpCode.ILSpy.TreeNodes;
 using ICSharpCode.ILSpy.ViewModels;
+using ICSharpCode.ILSpyX;
 
 using Microsoft.Win32;
 
diff --git a/ILSpy/TreeNodes/AssemblyListTreeNode.cs b/ILSpy/TreeNodes/AssemblyListTreeNode.cs
index 2341e15bc..4d29f8fe8 100644
--- a/ILSpy/TreeNodes/AssemblyListTreeNode.cs
+++ b/ILSpy/TreeNodes/AssemblyListTreeNode.cs
@@ -25,6 +25,7 @@ using ICSharpCode.Decompiler;
 using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.Decompiler.TypeSystem;
 using ICSharpCode.Decompiler.Util;
+using ICSharpCode.ILSpyX;
 using ICSharpCode.TreeView;
 
 namespace ICSharpCode.ILSpy.TreeNodes
diff --git a/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs b/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs
index 01a0961d6..815983efb 100644
--- a/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs
+++ b/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs
@@ -42,7 +42,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
 		public IAssemblyReference AssemblyNameReference => r;
 
 		public override object Text {
-			get { return r.Name + ((System.Reflection.Metadata.EntityHandle)r.Handle).ToSuffixString(); }
+			get { return r.Name + GetSuffixString(r.Handle); }
 		}
 
 		public override object Icon => Images.Assembly;
diff --git a/ILSpy/TreeNodes/AssemblyTreeNode.cs b/ILSpy/TreeNodes/AssemblyTreeNode.cs
index 59ea8b066..6efe0b143 100644
--- a/ILSpy/TreeNodes/AssemblyTreeNode.cs
+++ b/ILSpy/TreeNodes/AssemblyTreeNode.cs
@@ -31,6 +31,8 @@ using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.Decompiler.TypeSystem;
 using ICSharpCode.ILSpy.Properties;
 using ICSharpCode.ILSpy.ViewModels;
+using ICSharpCode.ILSpyX;
+using ICSharpCode.ILSpyX.PdbProvider;
 using ICSharpCode.TreeView;
 
 using Microsoft.Win32;
@@ -204,7 +206,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
 			var assembly = (MetadataModule)typeSystem.MainModule;
 			this.Children.Add(new Metadata.MetadataTreeNode(module, this));
 			Decompiler.DebugInfo.IDebugInfoProvider debugInfo = LoadedAssembly.GetDebugInfoOrNull();
-			if (debugInfo is Decompiler.PdbProvider.PortableDebugInfoProvider ppdb
+			if (debugInfo is PortableDebugInfoProvider ppdb
 				&& ppdb.GetMetadataReader() is System.Reflection.Metadata.MetadataReader reader)
 			{
 				this.Children.Add(new Metadata.DebugMetadataTreeNode(module, ppdb.IsEmbedded, reader, this));
diff --git a/ILSpy/TreeNodes/BaseTypesTreeNode.cs b/ILSpy/TreeNodes/BaseTypesTreeNode.cs
index f90147935..d2d79650c 100644
--- a/ILSpy/TreeNodes/BaseTypesTreeNode.cs
+++ b/ILSpy/TreeNodes/BaseTypesTreeNode.cs
@@ -24,6 +24,7 @@ using System.Windows.Threading;
 using ICSharpCode.Decompiler;
 using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.Decompiler.TypeSystem;
+using ICSharpCode.ILSpyX;
 using ICSharpCode.TreeView;
 
 namespace ICSharpCode.ILSpy.TreeNodes
diff --git a/ILSpy/TreeNodes/DerivedTypesEntryNode.cs b/ILSpy/TreeNodes/DerivedTypesEntryNode.cs
index 48199ecd0..fa4fa0c9a 100644
--- a/ILSpy/TreeNodes/DerivedTypesEntryNode.cs
+++ b/ILSpy/TreeNodes/DerivedTypesEntryNode.cs
@@ -21,6 +21,7 @@ using System.Linq;
 using System.Threading;
 
 using ICSharpCode.Decompiler;
+using ICSharpCode.ILSpyX;
 
 namespace ICSharpCode.ILSpy.TreeNodes
 {
@@ -43,7 +44,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
 		public override bool ShowExpander => !type.IsSealed && base.ShowExpander;
 
 		public override object Text {
-			get { return Language.TypeToString(type, includeNamespace: true) + type.MetadataToken.ToSuffixString(); }
+			get { return Language.TypeToString(type, includeNamespace: true) + GetSuffixString(type.MetadataToken); }
 		}
 
 		public override object Icon => TypeTreeNode.GetIcon(type);
diff --git a/ILSpy/TreeNodes/DerivedTypesTreeNode.cs b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs
index 3221af947..46dcbf6d7 100644
--- a/ILSpy/TreeNodes/DerivedTypesTreeNode.cs
+++ b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs
@@ -21,9 +21,9 @@ using System.Linq;
 using System.Threading;
 
 using ICSharpCode.Decompiler;
-using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.Decompiler.TypeSystem;
 using ICSharpCode.ILSpy.Properties;
+using ICSharpCode.ILSpyX;
 
 using SRM = System.Reflection.Metadata;
 
diff --git a/ILSpy/TreeNodes/EventTreeNode.cs b/ILSpy/TreeNodes/EventTreeNode.cs
index b9cce0968..9362fac6e 100644
--- a/ILSpy/TreeNodes/EventTreeNode.cs
+++ b/ILSpy/TreeNodes/EventTreeNode.cs
@@ -46,7 +46,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
 
 		public IEvent EventDefinition { get; }
 
-		public override object Text => GetText(GetEventDefinition(), this.Language) + EventDefinition.MetadataToken.ToSuffixString();
+		public override object Text => GetText(GetEventDefinition(), this.Language) + GetSuffixString(EventDefinition);
 
 		private IEvent GetEventDefinition()
 		{
diff --git a/ILSpy/TreeNodes/FieldTreeNode.cs b/ILSpy/TreeNodes/FieldTreeNode.cs
index fab2c6ae4..3a11cbefb 100644
--- a/ILSpy/TreeNodes/FieldTreeNode.cs
+++ b/ILSpy/TreeNodes/FieldTreeNode.cs
@@ -38,7 +38,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
 			this.FieldDefinition = field ?? throw new ArgumentNullException(nameof(field));
 		}
 
-		public override object Text => GetText(GetFieldDefinition(), Language) + FieldDefinition.MetadataToken.ToSuffixString();
+		public override object Text => GetText(GetFieldDefinition(), Language) + GetSuffixString(FieldDefinition);
 
 		private IField GetFieldDefinition()
 		{
diff --git a/ILSpy/TreeNodes/ILSpyTreeNode.cs b/ILSpy/TreeNodes/ILSpyTreeNode.cs
index 6796e48a3..d4672fd6b 100644
--- a/ILSpy/TreeNodes/ILSpyTreeNode.cs
+++ b/ILSpy/TreeNodes/ILSpyTreeNode.cs
@@ -20,10 +20,14 @@ using System;
 using System.Collections.Specialized;
 using System.ComponentModel;
 using System.Linq;
+using System.Reflection.Metadata;
+using System.Reflection.Metadata.Ecma335;
 using System.Windows;
 using System.Windows.Threading;
 
 using ICSharpCode.Decompiler;
+using ICSharpCode.Decompiler.TypeSystem;
+using ICSharpCode.ILSpy.Options;
 using ICSharpCode.TreeView;
 
 namespace ICSharpCode.ILSpy.TreeNodes
@@ -178,6 +182,19 @@ namespace ICSharpCode.ILSpy.TreeNodes
 			}
 		}
 
+		protected string GetSuffixString(IMember member) => GetSuffixString(member.MetadataToken);
+
+		protected string GetSuffixString(EntityHandle handle)
+		{
+			if (!DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokens)
+				return string.Empty;
+
+			int token = MetadataTokens.GetToken(handle);
+			if (DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokensInBase10)
+				return " @" + token;
+			return " @" + token.ToString("x8");
+		}
+
 		public virtual bool IsPublicAPI {
 			get { return true; }
 		}
diff --git a/ILSpy/TreeNodes/MethodTreeNode.cs b/ILSpy/TreeNodes/MethodTreeNode.cs
index 408e5a36e..28e4cfa30 100644
--- a/ILSpy/TreeNodes/MethodTreeNode.cs
+++ b/ILSpy/TreeNodes/MethodTreeNode.cs
@@ -38,7 +38,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
 			this.MethodDefinition = method ?? throw new ArgumentNullException(nameof(method));
 		}
 
-		public override object Text => GetText(GetMethodDefinition(), Language) + MethodDefinition.MetadataToken.ToSuffixString();
+		public override object Text => GetText(GetMethodDefinition(), Language) + GetSuffixString(MethodDefinition);
 
 		private IMethod GetMethodDefinition()
 		{
diff --git a/ILSpy/TreeNodes/ModuleReferenceTreeNode.cs b/ILSpy/TreeNodes/ModuleReferenceTreeNode.cs
index 6216a3704..1161d2e56 100644
--- a/ILSpy/TreeNodes/ModuleReferenceTreeNode.cs
+++ b/ILSpy/TreeNodes/ModuleReferenceTreeNode.cs
@@ -61,7 +61,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
 		}
 
 		public override object Text {
-			get { return moduleName + ((EntityHandle)handle).ToSuffixString(); }
+			get { return moduleName + GetSuffixString(handle); }
 		}
 
 		public override object Icon => Images.Library;
diff --git a/ILSpy/TreeNodes/PackageFolderTreeNode.cs b/ILSpy/TreeNodes/PackageFolderTreeNode.cs
index 58f4f3801..6a631966d 100644
--- a/ILSpy/TreeNodes/PackageFolderTreeNode.cs
+++ b/ILSpy/TreeNodes/PackageFolderTreeNode.cs
@@ -21,6 +21,7 @@ using System.Collections.Generic;
 using System.Linq;
 
 using ICSharpCode.Decompiler;
+using ICSharpCode.ILSpyX;
 using ICSharpCode.TreeView;
 
 namespace ICSharpCode.ILSpy.TreeNodes
diff --git a/ILSpy/TreeNodes/PropertyTreeNode.cs b/ILSpy/TreeNodes/PropertyTreeNode.cs
index e8e2e149d..694a31c4c 100644
--- a/ILSpy/TreeNodes/PropertyTreeNode.cs
+++ b/ILSpy/TreeNodes/PropertyTreeNode.cs
@@ -48,7 +48,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
 
 		public IProperty PropertyDefinition { get; }
 
-		public override object Text => GetText(GetPropertyDefinition(), Language) + PropertyDefinition.MetadataToken.ToSuffixString();
+		public override object Text => GetText(GetPropertyDefinition(), Language) + GetSuffixString(PropertyDefinition);
 
 		private IProperty GetPropertyDefinition()
 		{
diff --git a/ILSpy/TreeNodes/ThreadingSupport.cs b/ILSpy/TreeNodes/ThreadingSupport.cs
index 0e5fbf4e0..4e8861c21 100644
--- a/ILSpy/TreeNodes/ThreadingSupport.cs
+++ b/ILSpy/TreeNodes/ThreadingSupport.cs
@@ -27,7 +27,6 @@ using System.Windows;
 using System.Windows.Threading;
 
 using ICSharpCode.Decompiler;
-using ICSharpCode.ILSpy.Analyzers;
 using ICSharpCode.ILSpy.Properties;
 using ICSharpCode.TreeView;
 
diff --git a/ILSpy/TreeNodes/TypeTreeNode.cs b/ILSpy/TreeNodes/TypeTreeNode.cs
index 3cb5ca3a4..c0edd649e 100644
--- a/ILSpy/TreeNodes/TypeTreeNode.cs
+++ b/ILSpy/TreeNodes/TypeTreeNode.cs
@@ -18,7 +18,6 @@
 
 using System;
 using System.Linq;
-using System.Reflection;
 using System.Windows.Media;
 
 using ICSharpCode.Decompiler;
@@ -28,6 +27,7 @@ using SRM = System.Reflection.Metadata;
 namespace ICSharpCode.ILSpy.TreeNodes
 {
 	using ICSharpCode.Decompiler.TypeSystem;
+
 	public sealed class TypeTreeNode : ILSpyTreeNode, IMemberTreeNode
 	{
 		public TypeTreeNode(ITypeDefinition typeDefinition, AssemblyTreeNode parentAssemblyNode)
@@ -42,7 +42,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
 		public AssemblyTreeNode ParentAssemblyNode { get; }
 
 		public override object Text => this.Language.TypeToString(GetTypeDefinition(), includeNamespace: false)
-			+ TypeDefinition.MetadataToken.ToSuffixString();
+			+ GetSuffixString(TypeDefinition.MetadataToken);
 
 		private ITypeDefinition GetTypeDefinition()
 		{
diff --git a/ILSpy/ViewModels/ManageAssemblyListsViewModel.cs b/ILSpy/ViewModels/ManageAssemblyListsViewModel.cs
index e1db19ac1..5327afc0b 100644
--- a/ILSpy/ViewModels/ManageAssemblyListsViewModel.cs
+++ b/ILSpy/ViewModels/ManageAssemblyListsViewModel.cs
@@ -27,15 +27,12 @@ using System.Windows.Input;
 using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.ILSpy.Commands;
 using ICSharpCode.ILSpy.Properties;
+using ICSharpCode.ILSpyX;
 
 namespace ICSharpCode.ILSpy.ViewModels
 {
 	public class ManageAssemblyListsViewModel : ViewModelBase
 	{
-		public const string DotNet4List = ".NET 4 (WPF)";
-		public const string DotNet35List = ".NET 3.5";
-		public const string ASPDotNetMVC3List = "ASP.NET (MVC3)";
-
 		private readonly AssemblyListManager manager;
 		private readonly Window parent;
 
@@ -57,9 +54,9 @@ namespace ICSharpCode.ILSpy.ViewModels
 
 		IEnumerable<PreconfiguredAssemblyList> ResolvePreconfiguredAssemblyLists()
 		{
-			yield return new PreconfiguredAssemblyList(DotNet4List);
-			yield return new PreconfiguredAssemblyList(DotNet35List);
-			yield return new PreconfiguredAssemblyList(ASPDotNetMVC3List);
+			yield return new PreconfiguredAssemblyList(AssemblyListManager.DotNet4List);
+			yield return new PreconfiguredAssemblyList(AssemblyListManager.DotNet35List);
+			yield return new PreconfiguredAssemblyList(AssemblyListManager.ASPDotNetMVC3List);
 
 			var basePath = DotNetCorePathFinder.FindDotNetExeDirectory();
 			if (basePath == null)
@@ -140,7 +137,7 @@ namespace ICSharpCode.ILSpy.ViewModels
 			};
 			if (dlg.ShowDialog() == true)
 			{
-				manager.CreateList(new AssemblyList(dlg.ListName));
+				manager.CreateList(dlg.ListName);
 			}
 		}
 
@@ -241,104 +238,6 @@ namespace ICSharpCode.ILSpy.ViewModels
 			}
 		}
 
-		internal static AssemblyList CreateDefaultList(string name, string path = null, string newName = null)
-		{
-			var list = new AssemblyList(newName ?? name);
-			switch (name)
-			{
-				case DotNet4List:
-					AddToListFromGAC("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.Data.DataSetExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.Xaml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
-					AddToListFromGAC("PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
-					AddToListFromGAC("PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
-					AddToListFromGAC("WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
-					break;
-				case DotNet35List:
-					AddToListFromGAC("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
-					AddToListFromGAC("PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
-					AddToListFromGAC("WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
-					break;
-				case ASPDotNetMVC3List:
-					AddToListFromGAC("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.ComponentModel.DataAnnotations, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
-					AddToListFromGAC("System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
-					AddToListFromGAC("System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.Data.DataSetExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
-					AddToListFromGAC("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
-					AddToListFromGAC("System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
-					AddToListFromGAC("System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
-					AddToListFromGAC("System.Web.ApplicationServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
-					AddToListFromGAC("System.Web.DynamicData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
-					AddToListFromGAC("System.Web.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
-					AddToListFromGAC("System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
-					AddToListFromGAC("System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
-					AddToListFromGAC("System.Web.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
-					AddToListFromGAC("System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
-					AddToListFromGAC("System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
-					AddToListFromGAC("System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
-					AddToListFromGAC("Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
-					break;
-				case object _ when path != null:
-					foreach (var file in Directory.GetFiles(path, "*.dll"))
-					{
-						var dllname = Path.GetFileName(file);
-						if (DoIncludeFile(dllname))
-							AddToListFromDirectory(file);
-					}
-					break;
-			}
-			return list;
-
-			void AddToListFromGAC(string fullName)
-			{
-				AssemblyNameReference reference = AssemblyNameReference.Parse(fullName);
-				string file = UniversalAssemblyResolver.GetAssemblyInGac(reference);
-				if (file != null)
-					list.OpenAssembly(file);
-			}
-
-			void AddToListFromDirectory(string file)
-			{
-				if (File.Exists(file))
-					list.OpenAssembly(file);
-			}
-
-			bool DoIncludeFile(string fileName)
-			{
-				if (fileName == "Microsoft.DiaSymReader.Native.amd64.dll")
-					return false;
-				if (fileName.EndsWith("_cor3.dll", StringComparison.OrdinalIgnoreCase))
-					return false;
-				if (char.IsUpper(fileName[0]))
-					return true;
-				if (fileName == "netstandard.dll")
-					return true;
-				if (fileName == "mscorlib.dll")
-					return true;
-				return false;
-			}
-		}
-
 		private void ExecuteCreatePreconfiguredAssemblyList(PreconfiguredAssemblyList config)
 		{
 			CreateListDialog dlg = new CreateListDialog(Resources.AddPreconfiguredList);
@@ -357,10 +256,10 @@ namespace ICSharpCode.ILSpy.ViewModels
 			};
 			if (dlg.ShowDialog() == true)
 			{
-				var list = CreateDefaultList(config.Name, config.Path, dlg.ListName);
+				var list = manager.CreateDefaultList(config.Name, config.Path, dlg.ListName);
 				if (list.Count > 0)
 				{
-					manager.CreateList(list);
+					manager.AddListIfNotExists(list);
 				}
 			}
 		}
diff --git a/ILSpy/Views/DebugSteps.xaml.cs b/ILSpy/Views/DebugSteps.xaml.cs
index 46eb588ca..dce20bafb 100644
--- a/ILSpy/Views/DebugSteps.xaml.cs
+++ b/ILSpy/Views/DebugSteps.xaml.cs
@@ -7,6 +7,7 @@ using System.Windows.Input;
 using ICSharpCode.Decompiler.IL;
 using ICSharpCode.Decompiler.IL.Transforms;
 using ICSharpCode.ILSpy.Docking;
+using ICSharpCode.ILSpy.Options;
 using ICSharpCode.ILSpy.ViewModels;
 
 namespace ICSharpCode.ILSpy
diff --git a/ILSpy/Views/OpenFromGacDialog.xaml.cs b/ILSpy/Views/OpenFromGacDialog.xaml.cs
index 22a1a00aa..5189be034 100644
--- a/ILSpy/Views/OpenFromGacDialog.xaml.cs
+++ b/ILSpy/Views/OpenFromGacDialog.xaml.cs
@@ -29,6 +29,7 @@ using System.Windows.Threading;
 
 using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.ILSpy.Controls;
+using ICSharpCode.ILSpyX.Extensions;
 
 namespace ICSharpCode.ILSpy
 {