diff --git a/Filtration.Interface/Filtration.Interface.csproj b/Filtration.Interface/Filtration.Interface.csproj
index bc71f57..d383624 100644
--- a/Filtration.Interface/Filtration.Interface.csproj
+++ b/Filtration.Interface/Filtration.Interface.csproj
@@ -31,9 +31,24 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="GalaSoft.MvvmLight, Version=5.3.0.19026, Culture=neutral, PublicKeyToken=e7570ab207bcb616, processorArchitecture=MSIL">
+      <HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.dll</HintPath>
+    </Reference>
+    <Reference Include="GalaSoft.MvvmLight.Extras, Version=5.3.0.19032, Culture=neutral, PublicKeyToken=669f0b5e8f868abf, processorArchitecture=MSIL">
+      <HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.Extras.dll</HintPath>
+    </Reference>
+    <Reference Include="GalaSoft.MvvmLight.Platform, Version=5.3.0.19032, Culture=neutral, PublicKeyToken=5f873c45e98af8a1, processorArchitecture=MSIL">
+      <HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.Platform.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Practices.ServiceLocation, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll</HintPath>
+    </Reference>
     <Reference Include="PresentationCore" />
     <Reference Include="System" />
     <Reference Include="System.Core" />
+    <Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\System.Windows.Interactivity.dll</HintPath>
+    </Reference>
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
     <Reference Include="Microsoft.CSharp" />
@@ -46,6 +61,9 @@
     <Compile Include="IEditableDocument.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
diff --git a/Filtration.Interface/IDocument.cs b/Filtration.Interface/IDocument.cs
index 8f86095..c32a38b 100644
--- a/Filtration.Interface/IDocument.cs
+++ b/Filtration.Interface/IDocument.cs
@@ -1,4 +1,6 @@
 using System.Threading.Tasks;
+using System.Windows.Input;
+using GalaSoft.MvvmLight.CommandWpf;
 
 namespace Filtration.Interface
 {
@@ -7,5 +9,6 @@ namespace Filtration.Interface
         bool IsScript { get; }
         bool IsTheme { get; }
         Task Close();
+        RelayCommand CloseCommand { get; }
     }
 }
diff --git a/Filtration.Interface/packages.config b/Filtration.Interface/packages.config
new file mode 100644
index 0000000..946df8d
--- /dev/null
+++ b/Filtration.Interface/packages.config
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="CommonServiceLocator" version="1.3" targetFramework="net461" />
+  <package id="MvvmLightLibs" version="5.3.0.0" targetFramework="net461" />
+</packages>
\ No newline at end of file
diff --git a/Filtration.sln b/Filtration.sln
index e7dc0d1..c72486f 100644
--- a/Filtration.sln
+++ b/Filtration.sln
@@ -45,6 +45,10 @@ Global
 		Release|ARM = Release|ARM
 		Release|x64 = Release|x64
 		Release|x86 = Release|x86
+		SquirrelReleasify|Any CPU = SquirrelReleasify|Any CPU
+		SquirrelReleasify|ARM = SquirrelReleasify|ARM
+		SquirrelReleasify|x64 = SquirrelReleasify|x64
+		SquirrelReleasify|x86 = SquirrelReleasify|x86
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 		{55E0A34C-E039-43D7-A024-A4045401CDDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -63,6 +67,14 @@ Global
 		{55E0A34C-E039-43D7-A024-A4045401CDDA}.Release|x64.Build.0 = Release|Any CPU
 		{55E0A34C-E039-43D7-A024-A4045401CDDA}.Release|x86.ActiveCfg = Release|Any CPU
 		{55E0A34C-E039-43D7-A024-A4045401CDDA}.Release|x86.Build.0 = Release|Any CPU
+		{55E0A34C-E039-43D7-A024-A4045401CDDA}.SquirrelReleasify|Any CPU.ActiveCfg = Releasify|Any CPU
+		{55E0A34C-E039-43D7-A024-A4045401CDDA}.SquirrelReleasify|Any CPU.Build.0 = Releasify|Any CPU
+		{55E0A34C-E039-43D7-A024-A4045401CDDA}.SquirrelReleasify|ARM.ActiveCfg = Release|Any CPU
+		{55E0A34C-E039-43D7-A024-A4045401CDDA}.SquirrelReleasify|ARM.Build.0 = Release|Any CPU
+		{55E0A34C-E039-43D7-A024-A4045401CDDA}.SquirrelReleasify|x64.ActiveCfg = Release|Any CPU
+		{55E0A34C-E039-43D7-A024-A4045401CDDA}.SquirrelReleasify|x64.Build.0 = Release|Any CPU
+		{55E0A34C-E039-43D7-A024-A4045401CDDA}.SquirrelReleasify|x86.ActiveCfg = Release|Any CPU
+		{55E0A34C-E039-43D7-A024-A4045401CDDA}.SquirrelReleasify|x86.Build.0 = Release|Any CPU
 		{E0693972-72C5-4E05-A9C5-A5943E4015C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{E0693972-72C5-4E05-A9C5-A5943E4015C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{E0693972-72C5-4E05-A9C5-A5943E4015C6}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -79,6 +91,14 @@ Global
 		{E0693972-72C5-4E05-A9C5-A5943E4015C6}.Release|x64.Build.0 = Release|Any CPU
 		{E0693972-72C5-4E05-A9C5-A5943E4015C6}.Release|x86.ActiveCfg = Release|Any CPU
 		{E0693972-72C5-4E05-A9C5-A5943E4015C6}.Release|x86.Build.0 = Release|Any CPU
+		{E0693972-72C5-4E05-A9C5-A5943E4015C6}.SquirrelReleasify|Any CPU.ActiveCfg = Release|Any CPU
+		{E0693972-72C5-4E05-A9C5-A5943E4015C6}.SquirrelReleasify|Any CPU.Build.0 = Release|Any CPU
+		{E0693972-72C5-4E05-A9C5-A5943E4015C6}.SquirrelReleasify|ARM.ActiveCfg = Release|Any CPU
+		{E0693972-72C5-4E05-A9C5-A5943E4015C6}.SquirrelReleasify|ARM.Build.0 = Release|Any CPU
+		{E0693972-72C5-4E05-A9C5-A5943E4015C6}.SquirrelReleasify|x64.ActiveCfg = Release|Any CPU
+		{E0693972-72C5-4E05-A9C5-A5943E4015C6}.SquirrelReleasify|x64.Build.0 = Release|Any CPU
+		{E0693972-72C5-4E05-A9C5-A5943E4015C6}.SquirrelReleasify|x86.ActiveCfg = Release|Any CPU
+		{E0693972-72C5-4E05-A9C5-A5943E4015C6}.SquirrelReleasify|x86.Build.0 = Release|Any CPU
 		{4AAC3BEB-1DC1-483E-9D11-0E9334E80227}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{4AAC3BEB-1DC1-483E-9D11-0E9334E80227}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{4AAC3BEB-1DC1-483E-9D11-0E9334E80227}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -95,6 +115,14 @@ Global
 		{4AAC3BEB-1DC1-483E-9D11-0E9334E80227}.Release|x64.Build.0 = Release|Any CPU
 		{4AAC3BEB-1DC1-483E-9D11-0E9334E80227}.Release|x86.ActiveCfg = Release|Any CPU
 		{4AAC3BEB-1DC1-483E-9D11-0E9334E80227}.Release|x86.Build.0 = Release|Any CPU
+		{4AAC3BEB-1DC1-483E-9D11-0E9334E80227}.SquirrelReleasify|Any CPU.ActiveCfg = Release|Any CPU
+		{4AAC3BEB-1DC1-483E-9D11-0E9334E80227}.SquirrelReleasify|Any CPU.Build.0 = Release|Any CPU
+		{4AAC3BEB-1DC1-483E-9D11-0E9334E80227}.SquirrelReleasify|ARM.ActiveCfg = Release|Any CPU
+		{4AAC3BEB-1DC1-483E-9D11-0E9334E80227}.SquirrelReleasify|ARM.Build.0 = Release|Any CPU
+		{4AAC3BEB-1DC1-483E-9D11-0E9334E80227}.SquirrelReleasify|x64.ActiveCfg = Release|Any CPU
+		{4AAC3BEB-1DC1-483E-9D11-0E9334E80227}.SquirrelReleasify|x64.Build.0 = Release|Any CPU
+		{4AAC3BEB-1DC1-483E-9D11-0E9334E80227}.SquirrelReleasify|x86.ActiveCfg = Release|Any CPU
+		{4AAC3BEB-1DC1-483E-9D11-0E9334E80227}.SquirrelReleasify|x86.Build.0 = Release|Any CPU
 		{537BE676-2FF6-4995-B05B-9CFACE852EC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{537BE676-2FF6-4995-B05B-9CFACE852EC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{537BE676-2FF6-4995-B05B-9CFACE852EC9}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -111,6 +139,14 @@ Global
 		{537BE676-2FF6-4995-B05B-9CFACE852EC9}.Release|x64.Build.0 = Release|Any CPU
 		{537BE676-2FF6-4995-B05B-9CFACE852EC9}.Release|x86.ActiveCfg = Release|Any CPU
 		{537BE676-2FF6-4995-B05B-9CFACE852EC9}.Release|x86.Build.0 = Release|Any CPU
+		{537BE676-2FF6-4995-B05B-9CFACE852EC9}.SquirrelReleasify|Any CPU.ActiveCfg = Release|Any CPU
+		{537BE676-2FF6-4995-B05B-9CFACE852EC9}.SquirrelReleasify|Any CPU.Build.0 = Release|Any CPU
+		{537BE676-2FF6-4995-B05B-9CFACE852EC9}.SquirrelReleasify|ARM.ActiveCfg = Release|Any CPU
+		{537BE676-2FF6-4995-B05B-9CFACE852EC9}.SquirrelReleasify|ARM.Build.0 = Release|Any CPU
+		{537BE676-2FF6-4995-B05B-9CFACE852EC9}.SquirrelReleasify|x64.ActiveCfg = Release|Any CPU
+		{537BE676-2FF6-4995-B05B-9CFACE852EC9}.SquirrelReleasify|x64.Build.0 = Release|Any CPU
+		{537BE676-2FF6-4995-B05B-9CFACE852EC9}.SquirrelReleasify|x86.ActiveCfg = Release|Any CPU
+		{537BE676-2FF6-4995-B05B-9CFACE852EC9}.SquirrelReleasify|x86.Build.0 = Release|Any CPU
 		{41B8F5C2-65AA-42F0-A20B-6F95B13A9F48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{41B8F5C2-65AA-42F0-A20B-6F95B13A9F48}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{41B8F5C2-65AA-42F0-A20B-6F95B13A9F48}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -127,6 +163,14 @@ Global
 		{41B8F5C2-65AA-42F0-A20B-6F95B13A9F48}.Release|x64.Build.0 = Release|Any CPU
 		{41B8F5C2-65AA-42F0-A20B-6F95B13A9F48}.Release|x86.ActiveCfg = Release|Any CPU
 		{41B8F5C2-65AA-42F0-A20B-6F95B13A9F48}.Release|x86.Build.0 = Release|Any CPU
+		{41B8F5C2-65AA-42F0-A20B-6F95B13A9F48}.SquirrelReleasify|Any CPU.ActiveCfg = Release|Any CPU
+		{41B8F5C2-65AA-42F0-A20B-6F95B13A9F48}.SquirrelReleasify|Any CPU.Build.0 = Release|Any CPU
+		{41B8F5C2-65AA-42F0-A20B-6F95B13A9F48}.SquirrelReleasify|ARM.ActiveCfg = Release|Any CPU
+		{41B8F5C2-65AA-42F0-A20B-6F95B13A9F48}.SquirrelReleasify|ARM.Build.0 = Release|Any CPU
+		{41B8F5C2-65AA-42F0-A20B-6F95B13A9F48}.SquirrelReleasify|x64.ActiveCfg = Release|Any CPU
+		{41B8F5C2-65AA-42F0-A20B-6F95B13A9F48}.SquirrelReleasify|x64.Build.0 = Release|Any CPU
+		{41B8F5C2-65AA-42F0-A20B-6F95B13A9F48}.SquirrelReleasify|x86.ActiveCfg = Release|Any CPU
+		{41B8F5C2-65AA-42F0-A20B-6F95B13A9F48}.SquirrelReleasify|x86.Build.0 = Release|Any CPU
 		{450AC313-BF25-4BFD-A066-9F39F026FDCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{450AC313-BF25-4BFD-A066-9F39F026FDCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{450AC313-BF25-4BFD-A066-9F39F026FDCF}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -143,6 +187,14 @@ Global
 		{450AC313-BF25-4BFD-A066-9F39F026FDCF}.Release|x64.Build.0 = Release|Any CPU
 		{450AC313-BF25-4BFD-A066-9F39F026FDCF}.Release|x86.ActiveCfg = Release|Any CPU
 		{450AC313-BF25-4BFD-A066-9F39F026FDCF}.Release|x86.Build.0 = Release|Any CPU
+		{450AC313-BF25-4BFD-A066-9F39F026FDCF}.SquirrelReleasify|Any CPU.ActiveCfg = Release|Any CPU
+		{450AC313-BF25-4BFD-A066-9F39F026FDCF}.SquirrelReleasify|Any CPU.Build.0 = Release|Any CPU
+		{450AC313-BF25-4BFD-A066-9F39F026FDCF}.SquirrelReleasify|ARM.ActiveCfg = Release|Any CPU
+		{450AC313-BF25-4BFD-A066-9F39F026FDCF}.SquirrelReleasify|ARM.Build.0 = Release|Any CPU
+		{450AC313-BF25-4BFD-A066-9F39F026FDCF}.SquirrelReleasify|x64.ActiveCfg = Release|Any CPU
+		{450AC313-BF25-4BFD-A066-9F39F026FDCF}.SquirrelReleasify|x64.Build.0 = Release|Any CPU
+		{450AC313-BF25-4BFD-A066-9F39F026FDCF}.SquirrelReleasify|x86.ActiveCfg = Release|Any CPU
+		{450AC313-BF25-4BFD-A066-9F39F026FDCF}.SquirrelReleasify|x86.Build.0 = Release|Any CPU
 		{0F333344-7695-47B2-B0E6-172E4DE74819}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{0F333344-7695-47B2-B0E6-172E4DE74819}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{0F333344-7695-47B2-B0E6-172E4DE74819}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -159,6 +211,14 @@ Global
 		{0F333344-7695-47B2-B0E6-172E4DE74819}.Release|x64.Build.0 = Release|Any CPU
 		{0F333344-7695-47B2-B0E6-172E4DE74819}.Release|x86.ActiveCfg = Release|Any CPU
 		{0F333344-7695-47B2-B0E6-172E4DE74819}.Release|x86.Build.0 = Release|Any CPU
+		{0F333344-7695-47B2-B0E6-172E4DE74819}.SquirrelReleasify|Any CPU.ActiveCfg = Release|Any CPU
+		{0F333344-7695-47B2-B0E6-172E4DE74819}.SquirrelReleasify|Any CPU.Build.0 = Release|Any CPU
+		{0F333344-7695-47B2-B0E6-172E4DE74819}.SquirrelReleasify|ARM.ActiveCfg = Release|Any CPU
+		{0F333344-7695-47B2-B0E6-172E4DE74819}.SquirrelReleasify|ARM.Build.0 = Release|Any CPU
+		{0F333344-7695-47B2-B0E6-172E4DE74819}.SquirrelReleasify|x64.ActiveCfg = Release|Any CPU
+		{0F333344-7695-47B2-B0E6-172E4DE74819}.SquirrelReleasify|x64.Build.0 = Release|Any CPU
+		{0F333344-7695-47B2-B0E6-172E4DE74819}.SquirrelReleasify|x86.ActiveCfg = Release|Any CPU
+		{0F333344-7695-47B2-B0E6-172E4DE74819}.SquirrelReleasify|x86.Build.0 = Release|Any CPU
 		{8CB44F28-2956-4C2A-9314-72727262EDD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{8CB44F28-2956-4C2A-9314-72727262EDD4}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{8CB44F28-2956-4C2A-9314-72727262EDD4}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -175,6 +235,14 @@ Global
 		{8CB44F28-2956-4C2A-9314-72727262EDD4}.Release|x64.Build.0 = Release|Any CPU
 		{8CB44F28-2956-4C2A-9314-72727262EDD4}.Release|x86.ActiveCfg = Release|Any CPU
 		{8CB44F28-2956-4C2A-9314-72727262EDD4}.Release|x86.Build.0 = Release|Any CPU
+		{8CB44F28-2956-4C2A-9314-72727262EDD4}.SquirrelReleasify|Any CPU.ActiveCfg = Release|Any CPU
+		{8CB44F28-2956-4C2A-9314-72727262EDD4}.SquirrelReleasify|Any CPU.Build.0 = Release|Any CPU
+		{8CB44F28-2956-4C2A-9314-72727262EDD4}.SquirrelReleasify|ARM.ActiveCfg = Release|Any CPU
+		{8CB44F28-2956-4C2A-9314-72727262EDD4}.SquirrelReleasify|ARM.Build.0 = Release|Any CPU
+		{8CB44F28-2956-4C2A-9314-72727262EDD4}.SquirrelReleasify|x64.ActiveCfg = Release|Any CPU
+		{8CB44F28-2956-4C2A-9314-72727262EDD4}.SquirrelReleasify|x64.Build.0 = Release|Any CPU
+		{8CB44F28-2956-4C2A-9314-72727262EDD4}.SquirrelReleasify|x86.ActiveCfg = Release|Any CPU
+		{8CB44F28-2956-4C2A-9314-72727262EDD4}.SquirrelReleasify|x86.Build.0 = Release|Any CPU
 		{1E42A658-45C4-4DD9-83C5-2A10728DBDFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{1E42A658-45C4-4DD9-83C5-2A10728DBDFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{1E42A658-45C4-4DD9-83C5-2A10728DBDFA}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -191,6 +259,14 @@ Global
 		{1E42A658-45C4-4DD9-83C5-2A10728DBDFA}.Release|x64.Build.0 = Release|Any CPU
 		{1E42A658-45C4-4DD9-83C5-2A10728DBDFA}.Release|x86.ActiveCfg = Release|Any CPU
 		{1E42A658-45C4-4DD9-83C5-2A10728DBDFA}.Release|x86.Build.0 = Release|Any CPU
+		{1E42A658-45C4-4DD9-83C5-2A10728DBDFA}.SquirrelReleasify|Any CPU.ActiveCfg = Release|Any CPU
+		{1E42A658-45C4-4DD9-83C5-2A10728DBDFA}.SquirrelReleasify|Any CPU.Build.0 = Release|Any CPU
+		{1E42A658-45C4-4DD9-83C5-2A10728DBDFA}.SquirrelReleasify|ARM.ActiveCfg = Release|Any CPU
+		{1E42A658-45C4-4DD9-83C5-2A10728DBDFA}.SquirrelReleasify|ARM.Build.0 = Release|Any CPU
+		{1E42A658-45C4-4DD9-83C5-2A10728DBDFA}.SquirrelReleasify|x64.ActiveCfg = Release|Any CPU
+		{1E42A658-45C4-4DD9-83C5-2A10728DBDFA}.SquirrelReleasify|x64.Build.0 = Release|Any CPU
+		{1E42A658-45C4-4DD9-83C5-2A10728DBDFA}.SquirrelReleasify|x86.ActiveCfg = Release|Any CPU
+		{1E42A658-45C4-4DD9-83C5-2A10728DBDFA}.SquirrelReleasify|x86.Build.0 = Release|Any CPU
 		{3AB98B6E-05DB-44FA-9DAD-584AA88F0739}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{3AB98B6E-05DB-44FA-9DAD-584AA88F0739}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{3AB98B6E-05DB-44FA-9DAD-584AA88F0739}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -207,6 +283,14 @@ Global
 		{3AB98B6E-05DB-44FA-9DAD-584AA88F0739}.Release|x64.Build.0 = Release|Any CPU
 		{3AB98B6E-05DB-44FA-9DAD-584AA88F0739}.Release|x86.ActiveCfg = Release|Any CPU
 		{3AB98B6E-05DB-44FA-9DAD-584AA88F0739}.Release|x86.Build.0 = Release|Any CPU
+		{3AB98B6E-05DB-44FA-9DAD-584AA88F0739}.SquirrelReleasify|Any CPU.ActiveCfg = Release|Any CPU
+		{3AB98B6E-05DB-44FA-9DAD-584AA88F0739}.SquirrelReleasify|Any CPU.Build.0 = Release|Any CPU
+		{3AB98B6E-05DB-44FA-9DAD-584AA88F0739}.SquirrelReleasify|ARM.ActiveCfg = Release|Any CPU
+		{3AB98B6E-05DB-44FA-9DAD-584AA88F0739}.SquirrelReleasify|ARM.Build.0 = Release|Any CPU
+		{3AB98B6E-05DB-44FA-9DAD-584AA88F0739}.SquirrelReleasify|x64.ActiveCfg = Release|Any CPU
+		{3AB98B6E-05DB-44FA-9DAD-584AA88F0739}.SquirrelReleasify|x64.Build.0 = Release|Any CPU
+		{3AB98B6E-05DB-44FA-9DAD-584AA88F0739}.SquirrelReleasify|x86.ActiveCfg = Release|Any CPU
+		{3AB98B6E-05DB-44FA-9DAD-584AA88F0739}.SquirrelReleasify|x86.Build.0 = Release|Any CPU
 		{58CD3B9C-EBBA-4527-A81C-78B7EA9CA298}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{58CD3B9C-EBBA-4527-A81C-78B7EA9CA298}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{58CD3B9C-EBBA-4527-A81C-78B7EA9CA298}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -223,6 +307,14 @@ Global
 		{58CD3B9C-EBBA-4527-A81C-78B7EA9CA298}.Release|x64.Build.0 = Release|Any CPU
 		{58CD3B9C-EBBA-4527-A81C-78B7EA9CA298}.Release|x86.ActiveCfg = Release|Any CPU
 		{58CD3B9C-EBBA-4527-A81C-78B7EA9CA298}.Release|x86.Build.0 = Release|Any CPU
+		{58CD3B9C-EBBA-4527-A81C-78B7EA9CA298}.SquirrelReleasify|Any CPU.ActiveCfg = Release|Any CPU
+		{58CD3B9C-EBBA-4527-A81C-78B7EA9CA298}.SquirrelReleasify|Any CPU.Build.0 = Release|Any CPU
+		{58CD3B9C-EBBA-4527-A81C-78B7EA9CA298}.SquirrelReleasify|ARM.ActiveCfg = Release|Any CPU
+		{58CD3B9C-EBBA-4527-A81C-78B7EA9CA298}.SquirrelReleasify|ARM.Build.0 = Release|Any CPU
+		{58CD3B9C-EBBA-4527-A81C-78B7EA9CA298}.SquirrelReleasify|x64.ActiveCfg = Release|Any CPU
+		{58CD3B9C-EBBA-4527-A81C-78B7EA9CA298}.SquirrelReleasify|x64.Build.0 = Release|Any CPU
+		{58CD3B9C-EBBA-4527-A81C-78B7EA9CA298}.SquirrelReleasify|x86.ActiveCfg = Release|Any CPU
+		{58CD3B9C-EBBA-4527-A81C-78B7EA9CA298}.SquirrelReleasify|x86.Build.0 = Release|Any CPU
 		{10A7C2BC-EC6F-4A38-BDDA-E35935004C02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{10A7C2BC-EC6F-4A38-BDDA-E35935004C02}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{10A7C2BC-EC6F-4A38-BDDA-E35935004C02}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -239,6 +331,14 @@ Global
 		{10A7C2BC-EC6F-4A38-BDDA-E35935004C02}.Release|x64.Build.0 = Release|Any CPU
 		{10A7C2BC-EC6F-4A38-BDDA-E35935004C02}.Release|x86.ActiveCfg = Release|Any CPU
 		{10A7C2BC-EC6F-4A38-BDDA-E35935004C02}.Release|x86.Build.0 = Release|Any CPU
+		{10A7C2BC-EC6F-4A38-BDDA-E35935004C02}.SquirrelReleasify|Any CPU.ActiveCfg = Release|Any CPU
+		{10A7C2BC-EC6F-4A38-BDDA-E35935004C02}.SquirrelReleasify|Any CPU.Build.0 = Release|Any CPU
+		{10A7C2BC-EC6F-4A38-BDDA-E35935004C02}.SquirrelReleasify|ARM.ActiveCfg = Release|Any CPU
+		{10A7C2BC-EC6F-4A38-BDDA-E35935004C02}.SquirrelReleasify|ARM.Build.0 = Release|Any CPU
+		{10A7C2BC-EC6F-4A38-BDDA-E35935004C02}.SquirrelReleasify|x64.ActiveCfg = Release|Any CPU
+		{10A7C2BC-EC6F-4A38-BDDA-E35935004C02}.SquirrelReleasify|x64.Build.0 = Release|Any CPU
+		{10A7C2BC-EC6F-4A38-BDDA-E35935004C02}.SquirrelReleasify|x86.ActiveCfg = Release|Any CPU
+		{10A7C2BC-EC6F-4A38-BDDA-E35935004C02}.SquirrelReleasify|x86.Build.0 = Release|Any CPU
 		{46383F20-02DF-48B4-B092-9088FA4ACD5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{46383F20-02DF-48B4-B092-9088FA4ACD5A}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{46383F20-02DF-48B4-B092-9088FA4ACD5A}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -255,6 +355,14 @@ Global
 		{46383F20-02DF-48B4-B092-9088FA4ACD5A}.Release|x64.Build.0 = Release|Any CPU
 		{46383F20-02DF-48B4-B092-9088FA4ACD5A}.Release|x86.ActiveCfg = Release|Any CPU
 		{46383F20-02DF-48B4-B092-9088FA4ACD5A}.Release|x86.Build.0 = Release|Any CPU
+		{46383F20-02DF-48B4-B092-9088FA4ACD5A}.SquirrelReleasify|Any CPU.ActiveCfg = Release|Any CPU
+		{46383F20-02DF-48B4-B092-9088FA4ACD5A}.SquirrelReleasify|Any CPU.Build.0 = Release|Any CPU
+		{46383F20-02DF-48B4-B092-9088FA4ACD5A}.SquirrelReleasify|ARM.ActiveCfg = Release|Any CPU
+		{46383F20-02DF-48B4-B092-9088FA4ACD5A}.SquirrelReleasify|ARM.Build.0 = Release|Any CPU
+		{46383F20-02DF-48B4-B092-9088FA4ACD5A}.SquirrelReleasify|x64.ActiveCfg = Release|Any CPU
+		{46383F20-02DF-48B4-B092-9088FA4ACD5A}.SquirrelReleasify|x64.Build.0 = Release|Any CPU
+		{46383F20-02DF-48B4-B092-9088FA4ACD5A}.SquirrelReleasify|x86.ActiveCfg = Release|Any CPU
+		{46383F20-02DF-48B4-B092-9088FA4ACD5A}.SquirrelReleasify|x86.Build.0 = Release|Any CPU
 		{1F30CF6D-A5BF-4777-B8BA-E34F439FE8E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{1F30CF6D-A5BF-4777-B8BA-E34F439FE8E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{1F30CF6D-A5BF-4777-B8BA-E34F439FE8E5}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -271,6 +379,14 @@ Global
 		{1F30CF6D-A5BF-4777-B8BA-E34F439FE8E5}.Release|x64.Build.0 = Release|Any CPU
 		{1F30CF6D-A5BF-4777-B8BA-E34F439FE8E5}.Release|x86.ActiveCfg = Release|Any CPU
 		{1F30CF6D-A5BF-4777-B8BA-E34F439FE8E5}.Release|x86.Build.0 = Release|Any CPU
+		{1F30CF6D-A5BF-4777-B8BA-E34F439FE8E5}.SquirrelReleasify|Any CPU.ActiveCfg = Release|Any CPU
+		{1F30CF6D-A5BF-4777-B8BA-E34F439FE8E5}.SquirrelReleasify|Any CPU.Build.0 = Release|Any CPU
+		{1F30CF6D-A5BF-4777-B8BA-E34F439FE8E5}.SquirrelReleasify|ARM.ActiveCfg = Release|Any CPU
+		{1F30CF6D-A5BF-4777-B8BA-E34F439FE8E5}.SquirrelReleasify|ARM.Build.0 = Release|Any CPU
+		{1F30CF6D-A5BF-4777-B8BA-E34F439FE8E5}.SquirrelReleasify|x64.ActiveCfg = Release|Any CPU
+		{1F30CF6D-A5BF-4777-B8BA-E34F439FE8E5}.SquirrelReleasify|x64.Build.0 = Release|Any CPU
+		{1F30CF6D-A5BF-4777-B8BA-E34F439FE8E5}.SquirrelReleasify|x86.ActiveCfg = Release|Any CPU
+		{1F30CF6D-A5BF-4777-B8BA-E34F439FE8E5}.SquirrelReleasify|x86.Build.0 = Release|Any CPU
 		{855B38CC-EEF2-471D-BBBC-EB3E2FF3D387}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{855B38CC-EEF2-471D-BBBC-EB3E2FF3D387}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{855B38CC-EEF2-471D-BBBC-EB3E2FF3D387}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -287,6 +403,14 @@ Global
 		{855B38CC-EEF2-471D-BBBC-EB3E2FF3D387}.Release|x64.Build.0 = Release|Any CPU
 		{855B38CC-EEF2-471D-BBBC-EB3E2FF3D387}.Release|x86.ActiveCfg = Release|Any CPU
 		{855B38CC-EEF2-471D-BBBC-EB3E2FF3D387}.Release|x86.Build.0 = Release|Any CPU
+		{855B38CC-EEF2-471D-BBBC-EB3E2FF3D387}.SquirrelReleasify|Any CPU.ActiveCfg = Release|Any CPU
+		{855B38CC-EEF2-471D-BBBC-EB3E2FF3D387}.SquirrelReleasify|Any CPU.Build.0 = Release|Any CPU
+		{855B38CC-EEF2-471D-BBBC-EB3E2FF3D387}.SquirrelReleasify|ARM.ActiveCfg = Release|Any CPU
+		{855B38CC-EEF2-471D-BBBC-EB3E2FF3D387}.SquirrelReleasify|ARM.Build.0 = Release|Any CPU
+		{855B38CC-EEF2-471D-BBBC-EB3E2FF3D387}.SquirrelReleasify|x64.ActiveCfg = Release|Any CPU
+		{855B38CC-EEF2-471D-BBBC-EB3E2FF3D387}.SquirrelReleasify|x64.Build.0 = Release|Any CPU
+		{855B38CC-EEF2-471D-BBBC-EB3E2FF3D387}.SquirrelReleasify|x86.ActiveCfg = Release|Any CPU
+		{855B38CC-EEF2-471D-BBBC-EB3E2FF3D387}.SquirrelReleasify|x86.Build.0 = Release|Any CPU
 		{7A5720DE-A41B-47EA-AAAB-7C5608FF0C1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{7A5720DE-A41B-47EA-AAAB-7C5608FF0C1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{7A5720DE-A41B-47EA-AAAB-7C5608FF0C1F}.Debug|ARM.ActiveCfg = Debug|Any CPU
@@ -303,8 +427,19 @@ Global
 		{7A5720DE-A41B-47EA-AAAB-7C5608FF0C1F}.Release|x64.Build.0 = Release|Any CPU
 		{7A5720DE-A41B-47EA-AAAB-7C5608FF0C1F}.Release|x86.ActiveCfg = Release|Any CPU
 		{7A5720DE-A41B-47EA-AAAB-7C5608FF0C1F}.Release|x86.Build.0 = Release|Any CPU
+		{7A5720DE-A41B-47EA-AAAB-7C5608FF0C1F}.SquirrelReleasify|Any CPU.ActiveCfg = Release|Any CPU
+		{7A5720DE-A41B-47EA-AAAB-7C5608FF0C1F}.SquirrelReleasify|Any CPU.Build.0 = Release|Any CPU
+		{7A5720DE-A41B-47EA-AAAB-7C5608FF0C1F}.SquirrelReleasify|ARM.ActiveCfg = Release|Any CPU
+		{7A5720DE-A41B-47EA-AAAB-7C5608FF0C1F}.SquirrelReleasify|ARM.Build.0 = Release|Any CPU
+		{7A5720DE-A41B-47EA-AAAB-7C5608FF0C1F}.SquirrelReleasify|x64.ActiveCfg = Release|Any CPU
+		{7A5720DE-A41B-47EA-AAAB-7C5608FF0C1F}.SquirrelReleasify|x64.Build.0 = Release|Any CPU
+		{7A5720DE-A41B-47EA-AAAB-7C5608FF0C1F}.SquirrelReleasify|x86.ActiveCfg = Release|Any CPU
+		{7A5720DE-A41B-47EA-AAAB-7C5608FF0C1F}.SquirrelReleasify|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {8A170BBA-F99C-4192-9467-A5669B1DE126}
+	EndGlobalSection
 EndGlobal
diff --git a/Filtration.sln.DotSettings b/Filtration.sln.DotSettings
index c6806ba..de2c6b9 100644
--- a/Filtration.sln.DotSettings
+++ b/Filtration.sln.DotSettings
@@ -2,4 +2,5 @@
 	<s:Boolean x:Key="/Default/CodeInspection/CodeAnnotations/NamespacesWithAnnotations/=Filtration_002EAnnotations/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/CodeInspection/CodeAnnotations/NamespacesWithAnnotations/=Filtration_002EObjectModel_002EAnnotations/@EntryIndexedValue">True</s:Boolean>
 	<s:String x:Key="/Default/FilterSettingsManager/AttributeFilterXml/@EntryValue">&lt;data /&gt;</s:String>
-	<s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue">&lt;data&gt;&lt;IncludeFilters /&gt;&lt;ExcludeFilters&gt;&lt;Filter ModuleMask="Filtration.ItemFilterPreview.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;Filter ModuleMask="Filtration.ObjectModel.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;Filter ModuleMask="Filtration.ThemeEditor.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;Filter ModuleMask="Filtration.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;/ExcludeFilters&gt;&lt;/data&gt;</s:String></wpf:ResourceDictionary>
\ No newline at end of file
+	<s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue">&lt;data&gt;&lt;IncludeFilters /&gt;&lt;ExcludeFilters&gt;&lt;Filter ModuleMask="Filtration.ItemFilterPreview.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;Filter ModuleMask="Filtration.ObjectModel.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;Filter ModuleMask="Filtration.ThemeEditor.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;Filter ModuleMask="Filtration.Tests" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;/ExcludeFilters&gt;&lt;/data&gt;</s:String>
+	<s:Boolean x:Key="/Default/UserDictionary/Words/=Prerelease/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
\ No newline at end of file
diff --git a/Filtration/App.config b/Filtration/App.config
index ebcbc98..4281109 100644
--- a/Filtration/App.config
+++ b/Filtration/App.config
@@ -31,6 +31,33 @@
             <setting name="StaticDataLastUpdated" serializeAs="String">
                 <value>2016-01-01</value>
             </setting>
+            <setting name="DownloadPrereleaseUpdates" serializeAs="String">
+                <value>False</value>
+            </setting>
+            <setting name="ShowSectionBrowser" serializeAs="String">
+                <value>True</value>
+            </setting>
+            <setting name="ShowBlockGroupBrowser" serializeAs="String">
+                <value>True</value>
+            </setting>
+            <setting name="ShowBlockOutputPreview" serializeAs="String">
+                <value>True</value>
+            </setting>
+            <setting name="ShowAdvanced" serializeAs="String">
+                <value>False</value>
+            </setting>
+            <setting name="WindowState" serializeAs="String">
+                <value>Normal</value>
+            </setting>
+            <setting name="WindowWidth" serializeAs="String">
+                <value>1200</value>
+            </setting>
+            <setting name="WindowHeight" serializeAs="String">
+                <value>800</value>
+            </setting>
+            <setting name="LastActiveDocument" serializeAs="String">
+                <value />
+            </setting>
         </Filtration.Properties.Settings>
     </userSettings>
   <runtime>
diff --git a/Filtration/App.xaml.cs b/Filtration/App.xaml.cs
index 624f22e..692aa95 100644
--- a/Filtration/App.xaml.cs
+++ b/Filtration/App.xaml.cs
@@ -1,32 +1,23 @@
-using System;
-using System.Linq;
+using System.Linq;
 using System.Windows;
-using System.Windows.Threading;
 using AutoMapper;
 using Castle.Facilities.TypedFactory;
 using Castle.MicroKernel.ModelBuilder.Inspectors;
 using Castle.Windsor;
 using Castle.Windsor.Installer;
-using Filtration.ObjectModel;
 using Filtration.ObjectModel.ThemeEditor;
 using Filtration.Properties;
 using Filtration.Services;
 using Filtration.ThemeEditor.ViewModels;
-using Filtration.ViewModels;
-using Filtration.Views;
-using NLog;
 
 namespace Filtration
 {
     public partial class App
     {
         private IWindsorContainer _container;
-        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
 
-        private void Application_Startup(object sender, StartupEventArgs e)
+        private async void Application_Startup(object sender, StartupEventArgs e)
         {
-            DispatcherUnhandledException += OnDispatcherUnhandledException;
-
             _container = new WindsorContainer();
 
             // Disable property injection
@@ -56,26 +47,9 @@ namespace Filtration
             });
 
             Mapper.AssertConfigurationIsValid();
-
-            var mainWindow = _container.Resolve<IMainWindow>();
-            mainWindow.Show();
-
-            var updateCheckService = _container.Resolve<IUpdateCheckService>();
-            updateCheckService.CheckForUpdates();
-        }
-
-        private static void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
-        {
-            Logger.Fatal(e.Exception);
-            var exception = e.Exception.Message + Environment.NewLine + e.Exception.StackTrace;
-            var innerException = e.Exception.InnerException != null
-                ? e.Exception.InnerException.Message + Environment.NewLine +
-                  e.Exception.InnerException.StackTrace
-                : string.Empty;
-
-            MessageBox.Show(
-                exception + Environment.NewLine + innerException,
-                "Unhandled Exception", MessageBoxButton.OK, MessageBoxImage.Error);
+            
+            var bootstrapper = _container.Resolve<IBootstrapper>();
+            await bootstrapper.GoAsync();
         }
 
         protected override void OnExit(ExitEventArgs e)
diff --git a/Filtration/Filtration.csproj b/Filtration/Filtration.csproj
index f2d679c..c87a98b 100644
--- a/Filtration/Filtration.csproj
+++ b/Filtration/Filtration.csproj
@@ -15,21 +15,6 @@
     <WarningLevel>4</WarningLevel>
     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
     <TargetFrameworkProfile />
-    <PublishUrl>publish\</PublishUrl>
-    <Install>true</Install>
-    <InstallFrom>Disk</InstallFrom>
-    <UpdateEnabled>false</UpdateEnabled>
-    <UpdateMode>Foreground</UpdateMode>
-    <UpdateInterval>7</UpdateInterval>
-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
-    <UpdatePeriodically>false</UpdatePeriodically>
-    <UpdateRequired>false</UpdateRequired>
-    <MapFileExtensions>true</MapFileExtensions>
-    <ApplicationRevision>0</ApplicationRevision>
-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
-    <UseApplicationTrust>false</UseApplicationTrust>
-    <BootstrapperEnabled>true</BootstrapperEnabled>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -56,6 +41,16 @@
   <PropertyGroup>
     <ApplicationIcon>Resources\filtration.ico</ApplicationIcon>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Releasify|AnyCPU'">
+    <OutputPath>bin\Releasify\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
   <ItemGroup>
     <Reference Include="AutoMapper, Version=6.0.2.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
       <HintPath>..\packages\AutoMapper.6.0.2\lib\net45\AutoMapper.dll</HintPath>
@@ -70,6 +65,15 @@
     <Reference Include="ControlzEx, Version=2.2.0.4, Culture=neutral, PublicKeyToken=f08b075e934b7045, processorArchitecture=MSIL">
       <HintPath>..\packages\ControlzEx.2.2.0.4\lib\net45\ControlzEx.dll</HintPath>
     </Reference>
+    <Reference Include="DeltaCompressionDotNet, Version=1.1.0.0, Culture=neutral, PublicKeyToken=1d14d6e5194e7f4a, processorArchitecture=MSIL">
+      <HintPath>..\packages\DeltaCompressionDotNet.1.1.0\lib\net20\DeltaCompressionDotNet.dll</HintPath>
+    </Reference>
+    <Reference Include="DeltaCompressionDotNet.MsDelta, Version=1.1.0.0, Culture=neutral, PublicKeyToken=46b2138a390abf55, processorArchitecture=MSIL">
+      <HintPath>..\packages\DeltaCompressionDotNet.1.1.0\lib\net20\DeltaCompressionDotNet.MsDelta.dll</HintPath>
+    </Reference>
+    <Reference Include="DeltaCompressionDotNet.PatchApi, Version=1.1.0.0, Culture=neutral, PublicKeyToken=3e8888ee913ed789, processorArchitecture=MSIL">
+      <HintPath>..\packages\DeltaCompressionDotNet.1.1.0\lib\net20\DeltaCompressionDotNet.PatchApi.dll</HintPath>
+    </Reference>
     <Reference Include="Fluent, Version=4.0.3.394, Culture=neutral, PublicKeyToken=3e436e32a8c5546f, processorArchitecture=MSIL">
       <HintPath>..\packages\Fluent.Ribbon.4.0.3.394\lib\net45\Fluent.dll</HintPath>
       <Private>True</Private>
@@ -91,10 +95,41 @@
       <Private>True</Private>
     </Reference>
     <Reference Include="Microsoft.CSharp" />
+    <Reference Include="Microsoft.WindowsAPICodePack, Version=1.1.2.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\packages\WindowsAPICodePack-Core.1.1.2\lib\Microsoft.WindowsAPICodePack.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.WindowsAPICodePack.Shell, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\packages\WindowsAPICodePack-Shell.1.1.1\lib\Microsoft.WindowsAPICodePack.Shell.dll</HintPath>
+    </Reference>
+    <Reference Include="Mono.Cecil, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+      <HintPath>..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.dll</HintPath>
+    </Reference>
+    <Reference Include="Mono.Cecil.Mdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+      <HintPath>..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Mdb.dll</HintPath>
+    </Reference>
+    <Reference Include="Mono.Cecil.Pdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+      <HintPath>..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Pdb.dll</HintPath>
+    </Reference>
+    <Reference Include="Mono.Cecil.Rocks, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+      <HintPath>..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Rocks.dll</HintPath>
+    </Reference>
     <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
       <HintPath>..\packages\NLog.4.4.9\lib\net45\NLog.dll</HintPath>
     </Reference>
+    <Reference Include="NuGet.Squirrel, Version=3.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\packages\squirrel.windows.1.8.0\lib\Net45\NuGet.Squirrel.dll</HintPath>
+    </Reference>
+    <Reference Include="SharpCompress, Version=0.17.1.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
+      <HintPath>..\packages\SharpCompress.0.17.1\lib\net45\SharpCompress.dll</HintPath>
+    </Reference>
+    <Reference Include="Splat, Version=1.6.2.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\packages\Splat.1.6.2\lib\Net45\Splat.dll</HintPath>
+    </Reference>
+    <Reference Include="Squirrel, Version=1.8.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\packages\squirrel.windows.1.8.0\lib\Net45\Squirrel.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
+    <Reference Include="System.Configuration" />
     <Reference Include="System.Drawing" />
     <Reference Include="System.Windows.Controls.Input.Toolkit, Version=3.5.40128.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -113,6 +148,7 @@
     <Reference Include="System.Xaml">
       <RequiredTargetFramework>4.0</RequiredTargetFramework>
     </Reference>
+    <Reference Include="System.Xml.Linq" />
     <Reference Include="WindowsBase" />
     <Reference Include="PresentationCore" />
     <Reference Include="PresentationFramework" />
@@ -170,11 +206,13 @@
     <Compile Include="Models\UpdateData.cs" />
     <Compile Include="Properties\Annotations.cs" />
     <Compile Include="Repositories\ItemFilterScriptRepository.cs" />
+    <Compile Include="Services\Bootstrapper.cs" />
     <Compile Include="Services\ClipboardService.cs" />
     <Compile Include="Services\HTTPService.cs" />
     <Compile Include="Services\ItemFilterPersistenceService.cs" />
+    <Compile Include="Services\SettingsService.cs" />
     <Compile Include="Services\StaticDataService.cs" />
-    <Compile Include="Services\UpdateCheckService.cs" />
+    <Compile Include="Services\UpdateService.cs" />
     <Compile Include="Settings.cs" />
     <Compile Include="UserControls\AutoScrollingListBox.cs" />
     <Compile Include="UserControls\BlockItemControl.xaml.cs">
@@ -191,10 +229,13 @@
     <Compile Include="UserControls\ThemeComponentSelectionControl.xaml.cs">
       <DependentUpon>ThemeComponentSelectionControl.xaml</DependentUpon>
     </Compile>
+    <Compile Include="ViewModels\DesignTime\DesignTimeSettingsPageViewModel.cs" />
     <Compile Include="Views\AttachedProperties\SelectedItemsAttachedProperty.cs" />
     <Compile Include="Utility\RoutedCommandHandler.cs" />
     <Compile Include="Utility\RoutedCommandHandlers.cs" />
     <Compile Include="ViewModels\AvalonDockWorkspaceViewModel.cs" />
+    <Compile Include="ViewModels\DesignTime\DesignTimeMainWindowViewModel.cs" />
+    <Compile Include="ViewModels\DesignTime\DesignTimeUpdateViewModel.cs" />
     <Compile Include="ViewModels\Factories\IItemFilterCommentBlockViewModelFactory.cs" />
     <Compile Include="ViewModels\Factories\ItemFilterBlockBaseViewModelFactory.cs" />
     <Compile Include="ViewModels\ItemFilterBlockViewModelBase.cs" />
@@ -211,7 +252,7 @@
     <Compile Include="ViewModels\ToolPanes\CommentBlockBrowserViewModel.cs" />
     <Compile Include="ViewModels\StartPageViewModel.cs" />
     <Compile Include="ViewModels\ToolPanes\ToolViewModel.cs" />
-    <Compile Include="ViewModels\UpdateAvailableViewModel.cs" />
+    <Compile Include="ViewModels\UpdateViewModel.cs" />
     <Compile Include="Views\AttachedProperties\SelectingItemAttachedProperty.cs" />
     <Compile Include="Views\AvalonDock\AvalonDockWorkspaceView.xaml.cs">
       <DependentUpon>AvalonDockWorkspaceView.xaml</DependentUpon>
@@ -267,8 +308,11 @@
     <Compile Include="Views\ToolPanes\CommentBlockBrowserView.xaml.cs">
       <DependentUpon>CommentBlockBrowserView.xaml</DependentUpon>
     </Compile>
-    <Compile Include="Views\UpdateAvailableView.xaml.cs">
-      <DependentUpon>UpdateAvailableView.xaml</DependentUpon>
+    <Compile Include="Views\UpdateTabView.xaml.cs">
+      <DependentUpon>UpdateTabView.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Views\UpdateView.xaml.cs">
+      <DependentUpon>UpdateView.xaml</DependentUpon>
     </Compile>
     <Compile Include="WindsorInstallers\RepositoriesInstaller.cs" />
     <Compile Include="WindsorInstallers\ServicesInstaller.cs" />
@@ -371,7 +415,11 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
-    <Page Include="Views\UpdateAvailableView.xaml">
+    <Page Include="Views\UpdateTabView.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="Views\UpdateView.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
@@ -394,13 +442,16 @@
     <EmbeddedResource Include="Properties\Resources.resx">
       <Generator>ResXFileCodeGenerator</Generator>
       <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
     </EmbeddedResource>
     <Content Include="LICENSE.txt">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
     <Content Include="NLog.config">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+      <SubType>Designer</SubType>
     </Content>
+    <None Include="Filtration.nuspec" />
     <None Include="NLog.xsd">
       <SubType>Designer</SubType>
     </None>
@@ -580,12 +631,33 @@
     </BootstrapperPackage>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="$(XamlSpyInstallPath)MSBuild\FirstFloor.XamlSpy.WPF.targets" Condition="'$(XamlSpyInstallPath)' != '' and '$(Configuration)' == 'DEBUG'" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+  <Target Name="AfterBuild" Condition=" '$(Configuration)' == 'Releasify'">
+    <GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
+      <Output TaskParameter="Assemblies" ItemName="myAssemblyInfo" />
+    </GetAssemblyIdentity>
+    <ReadLinesFromFile File="$(ProjectDir)\Properties\AssemblyInfo.cs">
+      <Output TaskParameter="Lines" ItemName="ItemsFromFile" />
+    </ReadLinesFromFile>
+    <ItemGroup>
+      <!-- If your .NET version is <3.5 and you get build error, move this ItemGroup outside of Target -->
+      <NuGetExe Include="..\packages\NuGet.CommandLine.*\tools\nuget.exe" />
+      <SquirrelExe Include="..\packages\Squirrel.Windows.*\tools\squirrel.exe" />
+    </ItemGroup>
+    <PropertyGroup>
+      <ReleaseDir>..\Releases\</ReleaseDir>
+      <!-- Extra optional params for squirrel. can be empty -->
+      <SquirrelParams>--no-msi</SquirrelParams>
+      <Pattern>(?&lt;=\[assembly: AssemblyInformationalVersion\(").*?(?="\)\])</Pattern>
+      <In>@(ItemsFromFile)</In>
+      <SemVerNumber>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern)))</SemVerNumber>
+      <!-- <SemVerNumber>$([System.Version]::Parse(%(myAssemblyInfo.Version)).ToString(3))</SemVerNumber> -->
+    </PropertyGroup>
+    <!-- Add some nice errors for the next person that comes along -->
+    <Error Condition="!Exists(%(NuGetExe.FullPath))" Text="You are trying to use the NuGet.CommandLine package, but it is not installed. Please install NuGet.CommandLine from the Package Manager." />
+    <Error Condition="!Exists(%(SquirrelExe.FullPath))" Text="You are trying to use the Squirrel.Windows package, but it is not installed. Please install Squirrel.Windows from the Package Manager." />
+    <!-- Build nupkg into the project local bin\Release\ directory temporarily -->
+    <Exec Command="&quot;%(NuGetExe.FullPath)&quot; pack $(TargetName).nuspec -Version $(SemVerNumber) -OutputDirectory $(OutDir) -BasePath $(OutDir)" />
+    <!-- Squirrelify into the release dir (usually at solution level. Change the property above for a different location -->
+    <Exec Command="&quot;%(SquirrelExe.FullPath)&quot; --releasify $(OutDir)Filtration.$(SemVerNumber).nupkg --releaseDir=$(ReleaseDir) $(SquirrelParams)" />
+  </Target>
 </Project>
\ No newline at end of file
diff --git a/Filtration/Filtration.nuspec b/Filtration/Filtration.nuspec
new file mode 100644
index 0000000..f89e215
--- /dev/null
+++ b/Filtration/Filtration.nuspec
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
+  <metadata>
+    <id>Filtration</id>
+    <!-- version will be replaced by MSBuild -->
+    <version>0.0.0.0</version>
+    <title>Filtration</title>
+    <authors>Ben Wallis</authors>
+    <description>A Path of Exile loot filter script editor</description>
+    <requireLicenseAcceptance>false</requireLicenseAcceptance>
+    <copyright>Copyright 2018</copyright>
+    <releaseNotes>The release notes for 1.0.0 have not been written yet!</releaseNotes>
+    <dependencies />
+  </metadata>
+  <files>
+    <file src="*.*" target="lib\net45\" exclude="*.pdb;*.nupkg;*.vshost.*;*.xml"/>
+  </files>
+</package>
\ No newline at end of file
diff --git a/Filtration/NLog.config b/Filtration/NLog.config
index 9c219f8..af4b9bb 100644
--- a/Filtration/NLog.config
+++ b/Filtration/NLog.config
@@ -10,6 +10,7 @@
             layout="${longdate} ${uppercase:${level}} ${message}" />
     <target xsi:type="File" name="fDebug" fileName="${basedir}/Filtration_debug_${shortdate}.log"
             layout="${longdate} ${uppercase:${level}} ${message}" />
+    <target xsi:type="Debugger" name="cDebug" layout="${longdate} ${uppercase:${level}} ${message}"/>
   </targets>
 
   <rules>
@@ -17,6 +18,7 @@
     <!-- Uncomment the Debug line to enable Debug logging -->
     <!--<logger name="*" minlevel="Debug" writeTo="fDebug" final="true" />-->
     <logger name="*" minlevel="Error" writeTo="fErrors" />
+    <logger name="*" minlevel="Trace" writeTo="cDebug" />
     
   </rules>
 </nlog>
\ No newline at end of file
diff --git a/Filtration/Properties/AssemblyInfo.cs b/Filtration/Properties/AssemblyInfo.cs
index cc32a0b..395dec4 100644
--- a/Filtration/Properties/AssemblyInfo.cs
+++ b/Filtration/Properties/AssemblyInfo.cs
@@ -10,7 +10,8 @@ using System.Runtime.CompilerServices;
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 
-[assembly: AssemblyVersion("0.21")]
+[assembly: AssemblyVersion("1.0.0")]
+[assembly: AssemblyInformationalVersion("1.0.0-beta1")]
 
 [assembly: InternalsVisibleTo("Filtration.Tests")]
 [assembly: InternalsVisibleTo("Filtration.ItemFilterPreview.Tests")]
diff --git a/Filtration/Properties/Settings.Designer.cs b/Filtration/Properties/Settings.Designer.cs
index 49ad864..57a3ddc 100644
--- a/Filtration/Properties/Settings.Designer.cs
+++ b/Filtration/Properties/Settings.Designer.cs
@@ -12,7 +12,7 @@ namespace Filtration.Properties {
     
     
     [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.8.0.0")]
     internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
         
         private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
@@ -121,123 +121,111 @@ namespace Filtration.Properties {
                 return ((string)(this["UpdateDataUrl"]));
             }
         }
-
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("False")]
+        public bool DownloadPrereleaseUpdates {
+            get {
+                return ((bool)(this["DownloadPrereleaseUpdates"]));
+            }
+            set {
+                this["DownloadPrereleaseUpdates"] = value;
+            }
+        }
+        
         [global::System.Configuration.UserScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
         [global::System.Configuration.DefaultSettingValueAttribute("True")]
-        public bool ShowSectionBrowser
-        {
-            get
-            {
+        public bool ShowSectionBrowser {
+            get {
                 return ((bool)(this["ShowSectionBrowser"]));
             }
-            set
-            {
+            set {
                 this["ShowSectionBrowser"] = value;
             }
         }
-
+        
         [global::System.Configuration.UserScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("False")]
-        public bool ShowBlockGroupBrowser
-        {
-            get
-            {
+        [global::System.Configuration.DefaultSettingValueAttribute("True")]
+        public bool ShowBlockGroupBrowser {
+            get {
                 return ((bool)(this["ShowBlockGroupBrowser"]));
             }
-            set
-            {
+            set {
                 this["ShowBlockGroupBrowser"] = value;
             }
         }
-
+        
         [global::System.Configuration.UserScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("False")]
-        public bool ShowBlockOutputPreview
-        {
-            get
-            {
+        [global::System.Configuration.DefaultSettingValueAttribute("True")]
+        public bool ShowBlockOutputPreview {
+            get {
                 return ((bool)(this["ShowBlockOutputPreview"]));
             }
-            set
-            {
+            set {
                 this["ShowBlockOutputPreview"] = value;
             }
         }
-
+        
         [global::System.Configuration.UserScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
         [global::System.Configuration.DefaultSettingValueAttribute("False")]
-        public bool ShowAdvanced
-        {
-            get
-            {
+        public bool ShowAdvanced {
+            get {
                 return ((bool)(this["ShowAdvanced"]));
             }
-            set
-            {
+            set {
                 this["ShowAdvanced"] = value;
             }
         }
-
+        
         [global::System.Configuration.UserScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
         [global::System.Configuration.DefaultSettingValueAttribute("Normal")]
-        public global::System.Windows.WindowState WindowState
-        {
-            get
-            {
+        public global::System.Windows.WindowState WindowState {
+            get {
                 return ((global::System.Windows.WindowState)(this["WindowState"]));
             }
-            set
-            {
+            set {
                 this["WindowState"] = value;
             }
         }
-
+        
         [global::System.Configuration.UserScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("960")]
-        public int WindowWidth
-        {
-            get
-            {
+        [global::System.Configuration.DefaultSettingValueAttribute("1200")]
+        public int WindowWidth {
+            get {
                 return ((int)(this["WindowWidth"]));
             }
-            set
-            {
+            set {
                 this["WindowWidth"] = value;
             }
         }
-
+        
         [global::System.Configuration.UserScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("720")]
-        public int WindowHeight
-        {
-            get
-            {
+        [global::System.Configuration.DefaultSettingValueAttribute("800")]
+        public int WindowHeight {
+            get {
                 return ((int)(this["WindowHeight"]));
             }
-            set
-            {
+            set {
                 this["WindowHeight"] = value;
             }
         }
-
+        
         [global::System.Configuration.UserScopedSettingAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
         [global::System.Configuration.DefaultSettingValueAttribute("")]
-        public string LastActiveDocument
-        {
-            get
-            {
+        public string LastActiveDocument {
+            get {
                 return ((string)(this["LastActiveDocument"]));
             }
-            set
-            {
+            set {
                 this["LastActiveDocument"] = value;
             }
         }
diff --git a/Filtration/Properties/Settings.settings b/Filtration/Properties/Settings.settings
index 79cafbc..802669b 100644
--- a/Filtration/Properties/Settings.settings
+++ b/Filtration/Properties/Settings.settings
@@ -29,5 +29,32 @@
     <Setting Name="UpdateDataUrl" Type="System.String" Scope="Application">
       <Value Profile="(Default)">http://ben-wallis.github.io/Filtration/filtration_version.xml</Value>
     </Setting>
+    <Setting Name="DownloadPrereleaseUpdates" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">False</Value>
+    </Setting>
+    <Setting Name="ShowSectionBrowser" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">True</Value>
+    </Setting>
+    <Setting Name="ShowBlockGroupBrowser" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">True</Value>
+    </Setting>
+    <Setting Name="ShowBlockOutputPreview" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">True</Value>
+    </Setting>
+    <Setting Name="ShowAdvanced" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">False</Value>
+    </Setting>
+    <Setting Name="WindowState" Type="System.Windows.WindowState" Scope="User">
+      <Value Profile="(Default)">Normal</Value>
+    </Setting>
+    <Setting Name="WindowWidth" Type="System.Int32" Scope="User">
+      <Value Profile="(Default)">1200</Value>
+    </Setting>
+    <Setting Name="WindowHeight" Type="System.Int32" Scope="User">
+      <Value Profile="(Default)">800</Value>
+    </Setting>
+    <Setting Name="LastActiveDocument" Type="System.String" Scope="User">
+      <Value Profile="(Default)" />
+    </Setting>
   </Settings>
 </SettingsFile>
\ No newline at end of file
diff --git a/Filtration/Services/Bootstrapper.cs b/Filtration/Services/Bootstrapper.cs
new file mode 100644
index 0000000..b79b58f
--- /dev/null
+++ b/Filtration/Services/Bootstrapper.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Threading.Tasks;
+using System.Windows;
+using Filtration.Views;
+using NLog;
+
+namespace Filtration.Services
+{
+    internal interface IBootstrapper
+    {
+        Task GoAsync();
+    }
+
+    internal class Bootstrapper : IBootstrapper
+    {
+        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
+
+        private readonly IMainWindow _mainWindow;
+        private readonly ISettingsService _settingsService;
+        private readonly IUpdateService _updateService;
+
+        public Bootstrapper(IMainWindow mainWindow,
+                            ISettingsService settingsService,
+                            IUpdateService updateService)
+        {
+            _mainWindow = mainWindow;
+            _settingsService = settingsService;
+            _updateService = updateService;
+        }
+
+        public async Task GoAsync()
+        {
+            AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
+
+            // Attempt to restore user settings - this is required because after an update any
+            // user settings will have been lost due to Squirrel changing the app directory
+            // with each update
+            _settingsService.RestoreSettings();
+
+            _mainWindow.Show();
+
+            await _updateService.CheckForUpdates();
+        }
+
+        private void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e)
+        {
+            var exception = (Exception) e.ExceptionObject;
+
+            Logger.Fatal(exception);
+            var exceptionMessage = exception.Message + Environment.NewLine + exception.StackTrace;
+            var innerException = exception.InnerException != null
+                ? exception.InnerException.Message + Environment.NewLine +
+                  exception.InnerException.StackTrace
+                : string.Empty;
+
+            MessageBox.Show(exceptionMessage + Environment.NewLine + innerException, "Unhandled Exception", MessageBoxButton.OK, MessageBoxImage.Error);
+        }
+    }
+}
diff --git a/Filtration/Services/SettingsService.cs b/Filtration/Services/SettingsService.cs
new file mode 100644
index 0000000..ecfee9a
--- /dev/null
+++ b/Filtration/Services/SettingsService.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Configuration;
+using System.IO;
+using System.Reflection;
+using Filtration.Properties;
+using NLog;
+
+namespace Filtration.Services
+{
+    internal interface ISettingsService
+    {
+        void BackupSettings();
+        void RestoreSettings();
+    }
+
+    internal class SettingsService : ISettingsService
+    {
+        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
+
+        public void BackupSettings()
+        {
+            var currentUserSettingsFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath;
+            var backupFile = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\..\\last.config";
+
+            try
+            {
+                File.Copy(currentUserSettingsFile, backupFile, overwrite: true);
+            }
+            catch (Exception e)
+            {
+                Logger.Error(e);
+            }
+        }
+
+        public void RestoreSettings()
+        {
+            Settings.Default.Save();
+            string currentUserSettingsFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath;
+            string backupFile = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\..\\last.config";
+
+            // Check if we have settings that we need to restore
+            if (!File.Exists(backupFile))
+            {
+                // Nothing we need to do
+                return;
+            }
+            
+            try
+            {
+                // Overwrite the current user settings file with the backed up user settings file
+                File.Copy(backupFile, currentUserSettingsFile, overwrite: true);
+
+                // Delete backup file
+                File.Delete(backupFile);
+
+                Settings.Default.Reload();
+            }
+            catch (Exception e)
+            {
+                Logger.Error(e);
+            }
+        }
+    }
+}
diff --git a/Filtration/Services/UpdateCheckService.cs b/Filtration/Services/UpdateCheckService.cs
deleted file mode 100644
index cd94bdc..0000000
--- a/Filtration/Services/UpdateCheckService.cs
+++ /dev/null
@@ -1,137 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Reflection;
-using System.Windows;
-using System.Xml.Serialization;
-using Filtration.Models;
-using Filtration.Properties;
-using Filtration.ViewModels;
-using Filtration.Views;
-using NLog;
-
-namespace Filtration.Services
-{
-    internal interface IUpdateCheckService
-    {
-        void CheckForUpdates();
-    }
-
-    internal class UpdateCheckService : IUpdateCheckService
-    {
-        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
-
-        private readonly IHTTPService _httpService;
-        private readonly IUpdateAvailableViewModel _updateAvailableViewModel;
-
-        public UpdateCheckService(IHTTPService httpService,
-                                  IUpdateAvailableViewModel updateAvailableViewModel)
-        {
-            _httpService = httpService;
-            _updateAvailableViewModel = updateAvailableViewModel;
-        }
-
-        public void CheckForUpdates()
-        {
-            var assemblyVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);
-
-            try
-            {
-                var updateData = GetUpdateData();
-                updateData.CurrentVersionMajorPart = assemblyVersion.FileMajorPart;
-                updateData.CurrentVersionMinorPart = assemblyVersion.FileMinorPart;
-
-                if (updateData.LatestVersionMajorPart >= updateData.CurrentVersionMajorPart &&
-                    updateData.LatestVersionMinorPart > updateData.CurrentVersionMinorPart)
-                {
-                    if (Settings.Default.SuppressUpdates == false || LatestVersionIsNewerThanSuppressedVersion(updateData))
-                    {
-                        Settings.Default.SuppressUpdates = false;
-                        Settings.Default.Save();
-
-                        updateData.UpdateAvailable = true;
-                    }
-                }
-
-                if (updateData.StaticDataUpdatedDate > Settings.Default.StaticDataLastUpdated)
-                {
-                    var result = MessageBox.Show("New static data files are available (Item Base Types and Item Classes). Do you wish to download them?",
-                        "Static Data Update Available", MessageBoxButton.YesNo, MessageBoxImage.Question);
-
-                    if (result == MessageBoxResult.Yes)
-                    {
-                        try
-                        {
-                            UpdateStaticDataFiles();
-                            Settings.Default.StaticDataLastUpdated = DateTime.Now;
-                            Settings.Default.Save();
-
-                            MessageBox.Show("Static Data successfully updated!", "Update Success", MessageBoxButton.OK, MessageBoxImage.Information);
-                        }
-                        catch (Exception e)
-                        {
-                            Logger.Error(e);
-                            MessageBox.Show($"An error occurred while updating the static data files {Environment.NewLine}{e.Message}", "Update Error", MessageBoxButton.OK,
-                                MessageBoxImage.Error);
-                        }
-                    }
-                }
-                
-                if (updateData.UpdateAvailable)
-                {
-                    var updateAvailableView = new UpdateAvailableView { DataContext = _updateAvailableViewModel };
-                    _updateAvailableViewModel.Initialise(updateData);
-                    _updateAvailableViewModel.OnRequestClose += (s, e) => updateAvailableView.Close();
-                    updateAvailableView.ShowDialog();
-                }
-            }
-            catch (Exception e)
-            {
-                Logger.Debug(e);
-                // We don't care if the update check fails, because it could fail for multiple reasons 
-                // including the user blocking Filtration in their firewall.
-            }
-        }
-        
-        private static bool LatestVersionIsNewerThanSuppressedVersion(UpdateData updateData)
-        {
-            return Settings.Default.SuppressUpdatesUpToVersionMajorPart < updateData.LatestVersionMajorPart ||
-                   (Settings.Default.SuppressUpdatesUpToVersionMajorPart <= updateData.LatestVersionMajorPart &&
-                    Settings.Default.SuppressUpdatesUpToVersionMinorPart < updateData.LatestVersionMinorPart);
-        }
-
-        private UpdateData GetUpdateData()
-        {
-            var updateXml = _httpService.GetContent(Settings.Default.UpdateDataUrl);
-            return DeserializeUpdateData(updateXml);
-        }
-
-        private void UpdateStaticDataFiles()
-        {
-            var itemClassesStaticData = _httpService.GetContent(Settings.Default.ItemClassesStaticDataUrl);
-            var itemBaseTypesStaticData = _httpService.GetContent(Settings.Default.ItemBaseTypesStaticDataUrl);
-
-            var appdatapath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Filtration\";
-            Directory.CreateDirectory(appdatapath);
-
-            var itemClassesPath = appdatapath + "ItemClasses.txt";
-            var itemBaseTypesPath = appdatapath + "ItemBaseTypes.txt";
-
-            File.WriteAllText(itemClassesPath, itemClassesStaticData);
-            File.WriteAllText(itemBaseTypesPath, itemBaseTypesStaticData);
-        }
-
-        private UpdateData DeserializeUpdateData(string updateDataString)
-        {
-            var serializer = new XmlSerializer(typeof(UpdateData));
-            object result;
-
-            using (TextReader reader = new StringReader(updateDataString))
-            {
-                result = serializer.Deserialize(reader);
-            }
-
-            return result as UpdateData;
-        }
-    }
-}
diff --git a/Filtration/Services/UpdateService.cs b/Filtration/Services/UpdateService.cs
new file mode 100644
index 0000000..b41e092
--- /dev/null
+++ b/Filtration/Services/UpdateService.cs
@@ -0,0 +1,258 @@
+using System;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using Filtration.Properties;
+using NLog;
+using Squirrel;
+
+namespace Filtration.Services
+{
+    public enum UpdateStatus
+    {
+        NoUpdateAvailable,
+        CheckingForUpdate,
+        UpdateAvailable,
+        Downloading,
+        ReadyToApplyUpdate,
+        Updating,
+        UpdateComplete,
+        Error
+    }
+
+    internal class UpdateStatusChangedEventArgs : EventArgs
+    {
+        public UpdateStatusChangedEventArgs(UpdateStatus updateStatus)
+        {
+            UpdateStatus = updateStatus;
+        }
+
+        public UpdateStatus UpdateStatus { get; }
+    }
+
+    internal class UpdateProgressChangedEventArgs : EventArgs
+    {
+        public UpdateProgressChangedEventArgs(int progress)
+        {
+            Progress = progress;
+        }
+
+        public int Progress { get; }
+    }
+
+    internal interface IUpdateService
+    {
+        event EventHandler<UpdateStatusChangedEventArgs> UpdateStatusChanged;
+
+        event EventHandler<UpdateProgressChangedEventArgs> UpdateProgressChanged;
+
+        UpdateStatus UpdateStatus { get; }
+
+        string LatestReleaseNotes { get; }
+
+        string LatestReleaseVersion { get; }
+
+        Task CheckForUpdates();
+
+        Task DownloadUpdatesAsync();
+
+        Task ApplyUpdatesAsync();
+
+        void RestartAfterUpdate();
+    }
+
+    internal class UpdateService : IUpdateService
+    {
+        private readonly ISettingsService _settingsService;
+        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
+
+        private const string _localUpdatePath = @"C:\Repos\Filtration\Releases";
+        private ReleaseEntry _latestRelease;
+        private UpdateInfo _updates;
+
+        private UpdateStatus _updateStatus;
+
+        public UpdateService(ISettingsService settingsService)
+        {
+            _settingsService = settingsService;
+
+            UpdateStatus = UpdateStatus.NoUpdateAvailable;
+        }
+
+        public event EventHandler<UpdateStatusChangedEventArgs> UpdateStatusChanged;
+        public event EventHandler<UpdateProgressChangedEventArgs> UpdateProgressChanged;
+
+        public UpdateStatus UpdateStatus
+        {
+            get => _updateStatus;
+            private set
+            {
+                _updateStatus = value;
+                UpdateStatusChanged?.Invoke(this, new UpdateStatusChangedEventArgs(value));
+            }
+        }
+
+        public string LatestReleaseNotes { get; private set; }
+
+        public string LatestReleaseVersion { get; private set; }
+
+        public async Task CheckForUpdates()
+        {
+            if (UpdateStatus != UpdateStatus.NoUpdateAvailable)
+            {
+                throw new InvalidOperationException();
+            }
+
+
+            Logger.Debug("Checking for update...");
+            UpdateStatus = UpdateStatus.CheckingForUpdate;
+
+            try
+            {
+                bool downloadPrereleaseUpdates;
+                downloadPrereleaseUpdates = Settings.Default.DownloadPrereleaseUpdates;
+#if DEBUG
+                downloadPrereleaseUpdates = true;
+#endif
+                using (var mgr = await UpdateManager.GitHubUpdateManager("https://github.com/ben-wallis/Filtration", prerelease: downloadPrereleaseUpdates))
+                {
+                    _updates = await mgr.CheckForUpdate(progress: progress => UpdateProgressChanged?.Invoke(this, new UpdateProgressChangedEventArgs(progress)));
+                }
+
+                // Local file update source for testing
+                //using (var mgr = new UpdateManager(_localUpdatePath))
+                //{
+
+                //    _updates = await mgr.CheckForUpdate(progress: progress => UpdateProgressChanged?.Invoke(this, new UpdateProgressChangedEventArgs(progress)));
+                //}
+            }
+            catch (Exception e)
+            {
+                Logger.Error(e);
+                UpdateStatus = UpdateStatus.Error;
+                return;
+            }
+
+
+            if (_updates.ReleasesToApply.Any())
+            {
+                _latestRelease = _updates.ReleasesToApply.OrderBy(x => x.Version).Last();
+                LatestReleaseVersion = _latestRelease.Version.ToString();
+
+                Logger.Debug($"Update found ({LatestReleaseVersion}), fetching release notes...");
+
+                try
+                {
+                    var releaseNotes = _latestRelease.GetReleaseNotes(_localUpdatePath);
+                    LatestReleaseNotes = ProcessReleaseNotes(releaseNotes);
+                }
+                catch (Exception e)
+                {
+                    Logger.Error(e);
+                    UpdateStatus = UpdateStatus.Error;
+                    return;
+                }
+
+                UpdateStatus = UpdateStatus.UpdateAvailable;
+            }
+            else
+            {
+                UpdateStatus = UpdateStatus.NoUpdateAvailable;
+                Logger.Debug("No update available");
+            }
+        }
+
+        private string ProcessReleaseNotes(string rawReleaseNotes)
+        {
+            var regex = new Regex(@"<!\[CDATA\[(.*)]]>", RegexOptions.Singleline);
+            var matches = regex.Match(rawReleaseNotes);
+            if (matches.Success)
+            {
+                var releaseNotes = matches.Groups[1].Value;
+                return "<font face=\"Segoe UI\" size=\"2\">" + releaseNotes + "</font>";
+            }
+
+            return string.Empty;
+        }
+
+        public async Task DownloadUpdatesAsync()
+        {
+            if (_updates == null || UpdateStatus != UpdateStatus.UpdateAvailable)
+            {
+                throw new InvalidOperationException();
+            }
+
+            UpdateStatus = UpdateStatus.Downloading;
+
+            try
+            {
+                using (var updateManager = new UpdateManager(_localUpdatePath))
+                {
+                    await updateManager.DownloadReleases(_updates.ReleasesToApply, OnProgressChanged);
+                }
+            }
+            catch (Exception e)
+            {
+                Logger.Error(e);
+                UpdateStatus = UpdateStatus.Error;
+                return;
+            }
+
+            UpdateStatus = UpdateStatus.ReadyToApplyUpdate;
+        }
+
+
+        public async Task ApplyUpdatesAsync()
+        {
+            if (UpdateStatus != UpdateStatus.ReadyToApplyUpdate)
+            {
+                throw new InvalidOperationException();
+            }
+
+            UpdateStatus = UpdateStatus.Updating;
+
+            // Back up the current user settings before updating as updating using Squirrel
+            // wipes out user settings due to the application directory changing with each update
+            _settingsService.BackupSettings();
+
+            try
+            {
+                using (var updateManager = new UpdateManager(_localUpdatePath))
+                {
+                    await updateManager.ApplyReleases(_updates, OnProgressChanged);
+                }
+            }
+            catch (Exception e)
+            {
+                Logger.Error(e);
+                UpdateStatus = UpdateStatus.Error;
+                return;
+            }
+
+            UpdateStatus = UpdateStatus.UpdateComplete;
+        }
+
+        public void RestartAfterUpdate()
+        {
+            if (UpdateStatus != UpdateStatus.UpdateComplete)
+            {
+                throw new InvalidOperationException();
+            }
+
+            try
+            {
+                UpdateManager.RestartApp();
+            }
+            catch (Exception e)
+            {
+                Logger.Error(e);
+                UpdateStatus = UpdateStatus.Error;
+            }
+        }
+
+        private void OnProgressChanged(int progress)
+        {
+            UpdateProgressChanged?.Invoke(this, new UpdateProgressChangedEventArgs(progress));
+        }
+    }
+}
diff --git a/Filtration/ViewModels/DesignTime/DesignTimeMainWindowViewModel.cs b/Filtration/ViewModels/DesignTime/DesignTimeMainWindowViewModel.cs
new file mode 100644
index 0000000..a8cbfef
--- /dev/null
+++ b/Filtration/ViewModels/DesignTime/DesignTimeMainWindowViewModel.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using GalaSoft.MvvmLight.CommandWpf;
+
+namespace Filtration.ViewModels.DesignTime
+{
+    public class DesignTimeMainWindowViewModel : IMainWindowViewModel
+    {
+        public RelayCommand OpenScriptCommand { get; }
+        public RelayCommand NewScriptCommand { get; }
+
+        public int WindowWidth
+        {
+            get => 1200; set {} }
+
+        public int WindowHeight
+        {
+            get => 800; set { }
+        }
+
+        public IUpdateViewModel UpdateViewModel => new DesignTimeUpdateViewModel();
+
+        public Task<bool> CloseAllDocumentsAsync()
+        {
+            throw new NotImplementedException();
+        }
+
+        public Task OpenDroppedFilesAsync(List<string> filenames)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}
diff --git a/Filtration/ViewModels/DesignTime/DesignTimeSettingsPageViewModel.cs b/Filtration/ViewModels/DesignTime/DesignTimeSettingsPageViewModel.cs
new file mode 100644
index 0000000..a4ffea7
--- /dev/null
+++ b/Filtration/ViewModels/DesignTime/DesignTimeSettingsPageViewModel.cs
@@ -0,0 +1,23 @@
+using GalaSoft.MvvmLight.CommandWpf;
+
+namespace Filtration.ViewModels.DesignTime
+{
+    public class DesignTimeSettingsPageViewModel : ISettingsPageViewModel
+    {
+        public RelayCommand SetItemFilterScriptDirectoryCommand { get; }
+
+        public string DefaultFilterDirectory
+        {
+            get => @"c:\users\longusernamehere\Documents\My Games\Path of Exile";
+            set { }
+        }
+
+        public bool ExtraLineBetweenBlocks
+        {
+            get => true;
+            set { }
+        }
+
+        public bool DownloadPrereleaseUpdates { get; set; }
+    }
+}
diff --git a/Filtration/ViewModels/DesignTime/DesignTimeUpdateViewModel.cs b/Filtration/ViewModels/DesignTime/DesignTimeUpdateViewModel.cs
new file mode 100644
index 0000000..fff23b1
--- /dev/null
+++ b/Filtration/ViewModels/DesignTime/DesignTimeUpdateViewModel.cs
@@ -0,0 +1,49 @@
+using System.Threading.Tasks;
+using Filtration.Services;
+using GalaSoft.MvvmLight.CommandWpf;
+
+namespace Filtration.ViewModels.DesignTime
+{
+    public class DesignTimeUpdateViewModel : IUpdateViewModel
+    {
+        public RelayCommand HideUpdateWindowCommand { get; }
+
+        public RelayCommand NextStepCommand { get; }
+
+        public UpdateStatus UpdateStatus => UpdateStatus.Updating;
+        
+        public string NextStepButtonText
+        {
+            get => "Downloading... (100%)"; set {} }
+
+        public bool Visible => true;
+
+        public bool IsInErrorState { get; }
+
+        public string Version => "1.2.3";
+
+        public string ReleaseNotes => @"Added support for DisableDropSound filter block items
+        Added support for GemLevel filter block items
+        Added support for HasExplicitMod filter block items
+        Added support for StackSize filter block items
+        Added support for CustomAlertSound filter block items
+        Added support for MinimapIcon filter block items
+        Added support for MapTier filter block items
+        Added support for PlayEffect filter block items
+        Added theme support for several filter blocks
+            Added collapse/expand support for sections
+            Added support for performing actions on whole sections(copy/move/delete etc)
+        Added search box to Section Browser
+        Improved parsing to support different syntaxes
+        Small bugfixes";
+
+        public bool IsScript { get; }
+        public bool IsTheme { get; }
+        public Task Close()
+        {
+            throw new System.NotImplementedException();
+        }
+
+        public RelayCommand CloseCommand { get; }
+    }
+}
diff --git a/Filtration/ViewModels/MainWindowViewModel.cs b/Filtration/ViewModels/MainWindowViewModel.cs
index be5f314..0fd0c99 100644
--- a/Filtration/ViewModels/MainWindowViewModel.cs
+++ b/Filtration/ViewModels/MainWindowViewModel.cs
@@ -34,6 +34,9 @@ namespace Filtration.ViewModels
     {
         RelayCommand OpenScriptCommand { get; }
         RelayCommand NewScriptCommand { get; }
+        int WindowWidth { get; set; }
+        int WindowHeight { get; set; }
+        IUpdateViewModel UpdateViewModel { get; }
         Task<bool> CloseAllDocumentsAsync();
         Task OpenDroppedFilesAsync(List<string> filenames);
     }
@@ -63,7 +66,8 @@ namespace Filtration.ViewModels
                                    IThemeProvider themeProvider,
                                    IThemeService themeService,
                                    IMessageBoxService messageBoxService,
-                                   IClipboardService clipboardService)
+                                   IClipboardService clipboardService,
+                                   IUpdateViewModel updateViewModel)
         {
             _itemFilterScriptRepository = itemFilterScriptRepository;
             _itemFilterScriptTranslator = itemFilterScriptTranslator;
@@ -74,6 +78,8 @@ namespace Filtration.ViewModels
             _themeService = themeService;
             _messageBoxService = messageBoxService;
             _clipboardService = clipboardService;
+            UpdateViewModel = updateViewModel;
+
             _windowState = Settings.Default.WindowState;
             _windowWidth = Settings.Default.WindowWidth;
             _windowHeight = Settings.Default.WindowHeight;
@@ -266,13 +272,15 @@ namespace Filtration.ViewModels
         public IAvalonDockWorkspaceViewModel AvalonDockWorkspaceViewModel => _avalonDockWorkspaceViewModel;
         public ISettingsPageViewModel SettingsPageViewModel { get; }
 
+        public IUpdateViewModel UpdateViewModel { get; }
+
         public string WindowTitle
         {
             get
             {
                 var assembly = Assembly.GetExecutingAssembly();
                 var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
-                return "Filtration v" + fvi.FileMajorPart + "." +  fvi.FileMinorPart;
+                return "Filtration v" + fvi.ProductVersion;
             }
         }
 
diff --git a/Filtration/ViewModels/SettingsPageViewModel.cs b/Filtration/ViewModels/SettingsPageViewModel.cs
index d30d731..53102b5 100644
--- a/Filtration/ViewModels/SettingsPageViewModel.cs
+++ b/Filtration/ViewModels/SettingsPageViewModel.cs
@@ -1,16 +1,21 @@
 using System.IO;
 using System.Windows;
 using Filtration.Common.Services;
-using Filtration.Common.ViewModels;
 using Filtration.Properties;
 using Filtration.Services;
 using GalaSoft.MvvmLight;
 using GalaSoft.MvvmLight.CommandWpf;
+using Microsoft.WindowsAPICodePack.Dialogs;
 
 namespace Filtration.ViewModels
 {
     internal interface ISettingsPageViewModel
     {
+        RelayCommand SetItemFilterScriptDirectoryCommand { get; }
+
+        string DefaultFilterDirectory { get; }
+        bool ExtraLineBetweenBlocks { get; set; }
+        bool DownloadPrereleaseUpdates { get; set; }
     }
 
     internal class SettingsPageViewModel : ViewModelBase, ISettingsPageViewModel
@@ -22,31 +27,44 @@ namespace Filtration.ViewModels
         {
             _itemFilterPersistenceService = itemFilterPersistenceService;
             _messageBoxService = messageBoxService;
-            SaveCommand = new RelayCommand(OnSaveCommand);
-
-            DefaultFilterDirectory = Settings.Default.DefaultFilterDirectory;
-            ExtraLineBetweenBlocks = Settings.Default.ExtraLineBetweenBlocks;
-            SuppressUpdateNotifications = Settings.Default.SuppressUpdates;
+            SetItemFilterScriptDirectoryCommand = new RelayCommand(OnSetItemFilterScriptDirectoryCommand);
         }
-        public RelayCommand SaveCommand { get; private set; }
 
-        public string DefaultFilterDirectory { get; set; }
-        public bool ExtraLineBetweenBlocks { get; set; }
-        public bool SuppressUpdateNotifications { get; set; }
+        public RelayCommand SetItemFilterScriptDirectoryCommand { get; }
 
-        private void OnSaveCommand()
+        public string DefaultFilterDirectory => Settings.Default.DefaultFilterDirectory;
+
+        public bool ExtraLineBetweenBlocks
         {
-            try
-            {
-                _itemFilterPersistenceService.SetItemFilterScriptDirectory(DefaultFilterDirectory);
+            get => Settings.Default.ExtraLineBetweenBlocks;
+            set => Settings.Default.ExtraLineBetweenBlocks = value;
+        }
 
-                Settings.Default.ExtraLineBetweenBlocks = ExtraLineBetweenBlocks;
-                Settings.Default.SuppressUpdates = SuppressUpdateNotifications;
-            }
-            catch (DirectoryNotFoundException)
+        public bool DownloadPrereleaseUpdates
+        {
+            get => Settings.Default.DownloadPrereleaseUpdates;
+            set => Settings.Default.DownloadPrereleaseUpdates = value;
+        }
+
+        private void OnSetItemFilterScriptDirectoryCommand()
+        {
+            using (var dialog = new CommonOpenFileDialog())
             {
-                _messageBoxService.Show("Error", "The entered Default Filter Directory is invalid or does not exist.",
-                    MessageBoxButton.OK, MessageBoxImage.Exclamation);
+                dialog.IsFolderPicker = true;
+                var result = dialog.ShowDialog();
+                if (result == CommonFileDialogResult.Ok)
+                {
+                    try
+                    {
+                        _itemFilterPersistenceService.SetItemFilterScriptDirectory(dialog.FileName);
+                        RaisePropertyChanged(nameof(DefaultFilterDirectory));
+                    }
+                    catch (DirectoryNotFoundException)
+                    {
+                        _messageBoxService.Show("Error", "The entered Default Filter Directory is invalid or does not exist.",
+                            MessageBoxButton.OK, MessageBoxImage.Exclamation);
+                    }
+                }
             }
         }
     }
diff --git a/Filtration/ViewModels/StartPageViewModel.cs b/Filtration/ViewModels/StartPageViewModel.cs
index aab59e4..6a896a3 100644
--- a/Filtration/ViewModels/StartPageViewModel.cs
+++ b/Filtration/ViewModels/StartPageViewModel.cs
@@ -12,7 +12,6 @@ namespace Filtration.ViewModels
 
     internal class StartPageViewModel : PaneViewModel, IStartPageViewModel
     {
-
         public StartPageViewModel()
         {
             Title = "Start Page";
@@ -20,8 +19,8 @@ namespace Filtration.ViewModels
             NewScriptCommand = new RelayCommand(OnNewScriptCommand);
         }
         
-        public RelayCommand OpenScriptCommand { get; private set; }
-        public RelayCommand NewScriptCommand { get; private set; }
+        public RelayCommand OpenScriptCommand { get; }
+        public RelayCommand NewScriptCommand { get; }
 
         public bool IsScript => false;
         public bool IsTheme => false;
@@ -31,6 +30,8 @@ namespace Filtration.ViewModels
             throw new System.NotImplementedException();
         }
 
+        public RelayCommand CloseCommand { get; }
+
         private static void OnOpenScriptCommand()
         {
             Messenger.Default.Send(new NotificationMessage("OpenScript"));
diff --git a/Filtration/ViewModels/UpdateAvailableViewModel.cs b/Filtration/ViewModels/UpdateAvailableViewModel.cs
deleted file mode 100644
index 90c0bf0..0000000
--- a/Filtration/ViewModels/UpdateAvailableViewModel.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-using System;
-using System.Diagnostics;
-using Filtration.Models;
-using Filtration.Properties;
-using GalaSoft.MvvmLight.CommandWpf;
-
-namespace Filtration.ViewModels
-{
-    internal interface IUpdateAvailableViewModel
-    {
-        event EventHandler OnRequestClose;
-        void Initialise(UpdateData updateData);
-        string CurrentVersion { get; }
-        string NewVersion { get; }
-        string ReleaseNotes { get; }
-        DateTime ReleaseDate { get; }
-    }
-
-    internal class UpdateAvailableViewModel : IUpdateAvailableViewModel
-    {
-        private UpdateData _updateData;
-        private int _currentVersionMajorPart;
-        private int _currentVersionMinorPart;
-
-        public UpdateAvailableViewModel()
-        {
-            DownloadCommand = new RelayCommand(OnDownloadCommand);
-            AskLaterCommand = new RelayCommand(OnAskLaterCommand);
-            NeverAskAgainCommand = new RelayCommand(OnNeverAskAgainCommand);
-        }
-
-        public event EventHandler OnRequestClose;
-
-        public RelayCommand NeverAskAgainCommand { get; private set; }
-        public RelayCommand AskLaterCommand { get; private set; }
-        public RelayCommand DownloadCommand { get; private set; }
-
-        public void Initialise(UpdateData updateData)
-        {
-            _currentVersionMajorPart = updateData.CurrentVersionMajorPart;
-            _currentVersionMinorPart = updateData.CurrentVersionMinorPart;
-            _updateData = updateData;
-        }
-
-        public string CurrentVersion => _currentVersionMajorPart + "." + _currentVersionMinorPart;
-
-        public string NewVersion => _updateData.LatestVersionMajorPart + "." + _updateData.LatestVersionMinorPart;
-
-        public string ReleaseNotes => _updateData.ReleaseNotes;
-
-        public DateTime ReleaseDate => _updateData.ReleaseDate;
-
-        private void OnDownloadCommand()
-        {
-            Process.Start(_updateData.DownloadUrl);
-        }
-
-        private void OnNeverAskAgainCommand()
-        {
-            Settings.Default.SuppressUpdates = true;
-            Settings.Default.SuppressUpdatesUpToVersionMajorPart = _updateData.LatestVersionMajorPart;
-            Settings.Default.SuppressUpdatesUpToVersionMinorPart = _updateData.LatestVersionMinorPart;
-            Settings.Default.Save();
-            CloseWindow();
-        }
-
-        private void OnAskLaterCommand()
-        {
-            CloseWindow();
-        }
-
-        private void CloseWindow()
-        {
-            OnRequestClose?.Invoke(this, new EventArgs());
-        }
-    }
-
-}
-
diff --git a/Filtration/ViewModels/UpdateViewModel.cs b/Filtration/ViewModels/UpdateViewModel.cs
new file mode 100644
index 0000000..6ae0edf
--- /dev/null
+++ b/Filtration/ViewModels/UpdateViewModel.cs
@@ -0,0 +1,203 @@
+using System;
+using System.Threading.Tasks;
+using Filtration.Common.ViewModels;
+using Filtration.Interface;
+using Filtration.Services;
+using GalaSoft.MvvmLight.CommandWpf;
+
+namespace Filtration.ViewModels
+{
+    public interface IUpdateViewModel : IDocument
+    {
+        RelayCommand HideUpdateWindowCommand { get; }
+
+        RelayCommand NextStepCommand { get; }
+
+        UpdateStatus UpdateStatus { get; }
+
+        string ReleaseNotes { get; }
+
+        string Version { get; }
+
+        string NextStepButtonText { get; }
+
+        bool Visible { get; }
+        bool IsInErrorState { get; }
+    }
+
+    /// <summary>
+    /// This ViewModel is shared between UpdateView.xaml and UpdateTabView.xaml since they are both
+    /// parts of the same update process, first the user gets given the opportunity to download the
+    /// update from the UpdateView box and then once it is ready to install they click Update
+    /// and are taken to the UpdateTabView tab where they can see the changes and begin the installation
+    /// of the update.
+    /// </summary>
+    internal class UpdateViewModel : PaneViewModel, IUpdateViewModel
+    {
+        private readonly IAvalonDockWorkspaceViewModel _avalonDockWorkspaceViewModel;
+
+        private readonly IUpdateService _updateService;
+        private string _nextStepButtonText;
+        private bool _visible;
+        private bool _updateTabShown;
+
+        public UpdateViewModel(IAvalonDockWorkspaceViewModel avalonDockWorkspaceViewModel,
+                               IUpdateService updateService)
+        {
+            _avalonDockWorkspaceViewModel = avalonDockWorkspaceViewModel;
+            _updateService = updateService;
+
+            updateService.UpdateProgressChanged += UpdateServiceOnUpdateProgressChanged;
+            updateService.UpdateStatusChanged += UpdateServiceOnUpdateStatusChanged;
+
+            
+            HideUpdateWindowCommand = new RelayCommand(OnHideUpdateWindowCommand, () => UpdateStatus == UpdateStatus.UpdateAvailable || UpdateStatus == UpdateStatus.Error);
+            NextStepCommand = new RelayCommand(async () => await OnNextStepCommandAsync(), () => NextStepCommandEnabled);
+
+            Title = "Update Available";
+        }
+
+        public RelayCommand NextStepCommand { get; }
+
+        public RelayCommand HideUpdateWindowCommand { get; }
+
+        public UpdateStatus UpdateStatus => _updateService.UpdateStatus;
+
+        public bool IsInErrorState => UpdateStatus == UpdateStatus.Error;
+
+        public async Task Close()
+        {
+            await Task.FromResult(true);
+        }
+
+        public RelayCommand CloseCommand { get; }
+
+        public bool IsScript => false;
+        public bool IsTheme => false;
+
+        public bool Visible
+        {
+            get => _visible;
+            private set
+            {
+                _visible = value;
+                RaisePropertyChanged();
+            }
+        }
+
+        public string ReleaseNotes => _updateService.LatestReleaseNotes;
+
+        public string Version => _updateService.LatestReleaseVersion;
+
+        public string NextStepButtonText
+        {
+            get => _nextStepButtonText;
+            set
+            {
+                _nextStepButtonText = value;
+                RaisePropertyChanged();
+            }
+        }
+
+        private bool NextStepCommandEnabled => UpdateStatus == UpdateStatus.UpdateAvailable || UpdateStatus == UpdateStatus.ReadyToApplyUpdate || UpdateStatus == UpdateStatus.UpdateComplete;
+        
+        private async Task OnNextStepCommandAsync()
+        {
+            switch (UpdateStatus)
+            {
+                case UpdateStatus.UpdateAvailable:
+                {
+                    await _updateService.DownloadUpdatesAsync();
+                    break;
+                }
+                case UpdateStatus.ReadyToApplyUpdate:
+                {
+                    if (!_updateTabShown)
+                    {
+                        // When the update has downloaded and is ready to apply, clicking the button
+                        // closes the update popup and shows the update tab.
+                        _avalonDockWorkspaceViewModel.AddDocument(this);
+                        Visible = false;
+                        _updateTabShown = true;
+                        NextStepButtonText = "Update";
+                    }
+                    else
+                    {
+                        await _updateService.ApplyUpdatesAsync();
+                    }
+
+                    break;
+                }
+                case UpdateStatus.UpdateComplete:
+                {
+                    _updateService.RestartAfterUpdate();
+                    break;
+                }
+            }
+        }
+
+        private void UpdateServiceOnUpdateStatusChanged(object sender, UpdateStatusChangedEventArgs e)
+        {
+            switch (UpdateStatus)
+            {
+                case UpdateStatus.UpdateAvailable:
+                {
+                    Visible = true;
+                    NextStepButtonText = "Download";
+                    RaisePropertyChanged(nameof(ReleaseNotes));
+                    RaisePropertyChanged(nameof(Version));
+                    break;
+                }
+                case UpdateStatus.Downloading:
+                {
+                    HideUpdateWindowCommand.RaiseCanExecuteChanged();
+                    NextStepButtonText = "Downloading (0%)";
+                    break;
+                }
+                case UpdateStatus.ReadyToApplyUpdate:
+                {
+                    NextStepButtonText = "Update Ready";
+                    break;
+                }
+                case UpdateStatus.Updating:
+                {
+                    NextStepButtonText = "Updating (0%)";
+                    break;
+                }
+                case UpdateStatus.UpdateComplete:
+                {
+                    NextStepButtonText = "Restart";
+                    break;
+                }
+                case UpdateStatus.Error:
+                {
+                    NextStepButtonText = "Update Error - Check Logs";
+                    Visible = true;
+                    break;
+                }
+            }
+
+            NextStepCommand.RaiseCanExecuteChanged();
+            RaisePropertyChanged(nameof(UpdateStatus));
+            RaisePropertyChanged(nameof(IsInErrorState));
+
+        }
+
+        private void UpdateServiceOnUpdateProgressChanged(object sender, UpdateProgressChangedEventArgs e)
+        {
+            if (UpdateStatus == UpdateStatus.Downloading)
+            {
+                NextStepButtonText = $"Downloading ({e.Progress}%)";
+            }
+            else if (UpdateStatus == UpdateStatus.Updating)
+            {
+                NextStepButtonText = $"Updating ({e.Progress}%)";
+            }
+        }
+
+        private void OnHideUpdateWindowCommand()
+        {
+            Visible = false;
+        }
+    }
+}
diff --git a/Filtration/Views/AboutWindow.xaml.cs b/Filtration/Views/AboutWindow.xaml.cs
index 0facfaa..0a1b2d1 100644
--- a/Filtration/Views/AboutWindow.xaml.cs
+++ b/Filtration/Views/AboutWindow.xaml.cs
@@ -26,7 +26,7 @@ namespace Filtration.Views
             {
                 var assembly = Assembly.GetExecutingAssembly();
                 var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
-                return "Version " + fvi.FileMajorPart + "." + fvi.FileMinorPart;
+                return "Version " + fvi.ProductVersion;
             }
         }
     }
diff --git a/Filtration/Views/AvalonDock/AvalonDockWorkspaceView.xaml b/Filtration/Views/AvalonDock/AvalonDockWorkspaceView.xaml
index fdd92e3..4cb5f4a 100644
--- a/Filtration/Views/AvalonDock/AvalonDockWorkspaceView.xaml
+++ b/Filtration/Views/AvalonDock/AvalonDockWorkspaceView.xaml
@@ -61,6 +61,11 @@
                             <themeEditorViews:ThemeEditorView DataContext="{Binding}" />
                         </DataTemplate>
                     </viewsAvalonDock:PanesTemplateSelector.ThemeTemplate>
+                    <viewsAvalonDock:PanesTemplateSelector.UpdateTemplate>
+                        <DataTemplate>
+                            <views:UpdateTabView DataContext="{Binding}" />
+                        </DataTemplate>
+                    </viewsAvalonDock:PanesTemplateSelector.UpdateTemplate>
                 </viewsAvalonDock:PanesTemplateSelector>
             </xcad:DockingManager.LayoutItemTemplateSelector>
 
diff --git a/Filtration/Views/AvalonDock/PanesTemplateSelector.cs b/Filtration/Views/AvalonDock/PanesTemplateSelector.cs
index a256dda..d9f1d09 100644
--- a/Filtration/Views/AvalonDock/PanesTemplateSelector.cs
+++ b/Filtration/Views/AvalonDock/PanesTemplateSelector.cs
@@ -15,11 +15,10 @@ namespace Filtration.Views.AvalonDock
         public DataTemplate BlockOutputPreviewTemplate { get; set; }
         public DataTemplate StartPageTemplate { get; set; }
         public DataTemplate ThemeTemplate { get; set; }
+        public DataTemplate UpdateTemplate { get; set; }
 
         public override DataTemplate SelectTemplate(object item, DependencyObject container)
         {
-            var itemAsLayoutContent = item as LayoutContent;
-
             if (item is ItemFilterScriptViewModel)
             {
                 return ItemFilterScriptTemplate;
@@ -50,6 +49,11 @@ namespace Filtration.Views.AvalonDock
                 return StartPageTemplate;
             }
 
+            if (item is IUpdateViewModel)
+            {
+                return UpdateTemplate;
+            }
+
             return base.SelectTemplate(item, container);
         }
     }
diff --git a/Filtration/Views/MainWindow.xaml b/Filtration/Views/MainWindow.xaml
index 928e347..6da3899 100644
--- a/Filtration/Views/MainWindow.xaml
+++ b/Filtration/Views/MainWindow.xaml
@@ -10,8 +10,9 @@
         xmlns:views="clr-namespace:Filtration.Views"
         xmlns:gif="http://wpfanimatedgif.codeplex.com"
         xmlns:utility="clr-namespace:Filtration.Utility"
-        mc:Ignorable="d"
-        d:DataContext="{d:DesignInstance Type=viewModels:MainWindowViewModel}"
+        xmlns:designTime="clr-namespace:Filtration.ViewModels.DesignTime"
+        mc:Ignorable="d" d:DesignWidth="1200" d:DesignHeight="800"
+        d:DataContext="{d:DesignInstance Type=designTime:DesignTimeMainWindowViewModel, IsDesignTimeCreatable=True}"
         Title="{Binding WindowTitle}" Height="{Binding WindowHeight, Mode=TwoWay}" Width="{Binding WindowWidth, Mode=TwoWay}" IsIconVisible="True" WindowState="{Binding WindowState}"
         Closing="MainWindow_OnClosing" Drop="MainWindow_OnDrop" AllowDrop="True">
 
@@ -166,6 +167,7 @@
                     </Border>
                 </Grid>
             </Grid>
+            <views:UpdateView DataContext="{Binding UpdateViewModel}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="4" Height="90" />
         </Grid>
     </DockPanel>
 </fluent:RibbonWindow>
diff --git a/Filtration/Views/SettingsPageView.xaml b/Filtration/Views/SettingsPageView.xaml
index a462640..23f8832 100644
--- a/Filtration/Views/SettingsPageView.xaml
+++ b/Filtration/Views/SettingsPageView.xaml
@@ -3,12 +3,11 @@
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-        xmlns:viewModels="clr-namespace:Filtration.ViewModels"
-        mc:Ignorable="d"
-        d:DataContext="{d:DesignInstance Type=viewModels:SettingsPageViewModel}">
-    <!--IsMaxRestoreButtonEnabled="False"-->
+        xmlns:designTime="clr-namespace:Filtration.ViewModels.DesignTime"
+        mc:Ignorable="d" d:DesignWidth="1200"
+        d:DataContext="{d:DesignInstance Type=designTime:DesignTimeSettingsPageViewModel, IsDesignTimeCreatable=True}">
     <Border BorderBrush="Black" BorderThickness="1">
-        <DockPanel Margin="10">
+        <DockPanel Margin="10" MaxWidth="600" HorizontalAlignment="Left">
             <Grid DockPanel.Dock="Bottom">
                 <Grid.RowDefinitions>
                     <RowDefinition Height="Auto" />
@@ -18,7 +17,7 @@
                     <Grid.ColumnDefinitions>
                         <ColumnDefinition Width="Auto" />
                         <ColumnDefinition Width="5" />
-                        <ColumnDefinition></ColumnDefinition>
+                        <ColumnDefinition />
                     </Grid.ColumnDefinitions>
                     <Grid.RowDefinitions>
                         <RowDefinition Height="Auto" />
@@ -28,22 +27,22 @@
                         <RowDefinition Height="Auto" />
                         <RowDefinition Height="Auto" />
                     </Grid.RowDefinitions>
-                    <TextBlock Grid.Row="0" Grid.Column="0">Default Filter Directory:</TextBlock>
-                    <TextBox Grid.Row="0" Grid.Column="2" Text="{Binding DefaultFilterDirectory}" Width="250" />
+                    <TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center">Default Filter Directory:</TextBlock>
+                    <Grid Grid.Row="0" Grid.Column="2" Height="40" Width="300">
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="*" />
+                            <ColumnDefinition Width="40" />
+                        </Grid.ColumnDefinitions>
+                        <TextBlock Grid.Column="0" Text="{Binding DefaultFilterDirectory}" TextWrapping="Wrap" VerticalAlignment="Center" />
+                        <Button Grid.Column="1" Margin="5,0,0,0" Width="30" Height="30" Command="{Binding SetItemFilterScriptDirectoryCommand}">
+                            <ContentControl Content="{StaticResource OpenIcon}" Width="16" Height="16"></ContentControl>
+                        </Button>
+                    </Grid>
                     <TextBlock Grid.Row="2" Grid.Column="0" VerticalAlignment="Center">Add blank line between blocks when saving</TextBlock>
                     <CheckBox Grid.Row="2" Grid.Column="2" IsChecked="{Binding ExtraLineBetweenBlocks}"  />
-                    <TextBlock Grid.Row="4" Grid.Column="0" VerticalAlignment="Center">Suppress update notifications for current version</TextBlock>
-                    <CheckBox Grid.Row="4" Grid.Column="2" IsChecked="{Binding SuppressUpdateNotifications}"  />
+                    <TextBlock Grid.Row="4" Grid.Column="0" VerticalAlignment="Center">Download pre-release updates (use with caution)</TextBlock>
+                    <CheckBox Grid.Row="4" Grid.Column="2" IsChecked="{Binding DownloadPrereleaseUpdates}"  />
                 </Grid>
-                <StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Right">
-                    <StackPanel.Resources>
-                        <Style TargetType="{x:Type Button}">
-                            <Setter Property="Width" Value="80" />
-                            <Setter Property="Margin" Value="3" />
-                        </Style>
-                    </StackPanel.Resources>
-                    <Button Command="{Binding SaveCommand}">Save</Button>
-                </StackPanel>
             </Grid>
         </DockPanel>
     </Border>
diff --git a/Filtration/Views/UpdateAvailableView.xaml b/Filtration/Views/UpdateAvailableView.xaml
deleted file mode 100644
index 76f58a5..0000000
--- a/Filtration/Views/UpdateAvailableView.xaml
+++ /dev/null
@@ -1,38 +0,0 @@
-<Window x:Class="Filtration.Views.UpdateAvailableView"
-        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
-        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-        xmlns:viewModels="clr-namespace:Filtration.ViewModels"
-        Title="Filtration - New Version Available!" Height="300" Width="500" Icon="../Resources/filtration.ico"
-        mc:Ignorable="d"  
-        d:DataContext="{d:DesignInstance Type=viewModels:UpdateAvailableViewModel}">
-    <Grid Margin="10">
-        <Grid.RowDefinitions>
-            <RowDefinition Height="Auto" />
-            <RowDefinition Height="Auto" />
-            <RowDefinition Height="Auto" />
-            <RowDefinition Height="Auto" />
-            <RowDefinition Height="*" />
-        </Grid.RowDefinitions>
-        <Grid.ColumnDefinitions>
-            <ColumnDefinition Width="Auto" />
-            <ColumnDefinition Width="5" />
-            <ColumnDefinition Width="*"/>
-        </Grid.ColumnDefinitions>
-        <TextBlock Grid.Row="0" Text="Current Version:" />
-        <TextBlock Grid.Row="0" Grid.Column="2" Text="{Binding CurrentVersion}" />
-        <TextBlock Grid.Row="1" Grid.Column="0"  Text="New Version:" />
-        <TextBlock Grid.Row="1" Grid.Column="2" Text="{Binding NewVersion}" />
-        <TextBlock Grid.Row="2" Grid.Column="0"  Text="Release Date:" />
-        <TextBlock Grid.Row="2" Grid.Column="2" Text="{Binding ReleaseDate, StringFormat={}{0:yyyy-MM-dd}}" />
-        <TextBlock Grid.Row="3" Grid.Column="0"  Text="Release Notes:" />
-        <TextBox MaxHeight="150" IsReadOnly="True" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden" Grid.Row="3" Grid.Column="2" Text="{Binding ReleaseNotes, Mode=OneWay}" TextWrapping="Wrap" />
-        
-        <StackPanel Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="3" Orientation="Horizontal" Height="30" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,5">
-            <Button Padding="2"  Margin="0,0,5,0" Command="{Binding DownloadCommand}">Download from Filtration homepage</Button>
-            <Button Padding="2" Margin="0,0,5,0" Command="{Binding AskLaterCommand}">Ask me later</Button>
-            <Button Padding="2" Margin="0,0,5,0" Command="{Binding NeverAskAgainCommand}">Never ask again for this version</Button>
-        </StackPanel>
-    </Grid>
-</Window>
diff --git a/Filtration/Views/UpdateTabView.xaml b/Filtration/Views/UpdateTabView.xaml
new file mode 100644
index 0000000..eb0fea3
--- /dev/null
+++ b/Filtration/Views/UpdateTabView.xaml
@@ -0,0 +1,39 @@
+<UserControl x:Class="Filtration.Views.UpdateTabView"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+             xmlns:designTime="clr-namespace:Filtration.ViewModels.DesignTime"
+             mc:Ignorable="d" 
+             d:DesignHeight="650" d:DesignWidth="1024" d:DataContext="{d:DesignInstance designTime:DesignTimeUpdateViewModel, IsDesignTimeCreatable=True}">
+    <Grid Margin="16">
+        <Grid.RowDefinitions>
+            <RowDefinition Height="Auto" />
+            <RowDefinition Height="*" />
+        </Grid.RowDefinitions>
+        <Grid.ColumnDefinitions>
+            <ColumnDefinition Width="Auto" />
+            <ColumnDefinition Width="*" />
+        </Grid.ColumnDefinitions>
+        <Grid Grid.Row="0" Grid.Column="0">
+            <Grid>
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="Auto" />
+                    <RowDefinition Height="5" />
+                    <RowDefinition Height="350" />
+                    <RowDefinition Height="5" />
+                    <RowDefinition Height="Auto" />
+                    <RowDefinition Height="*" />
+                </Grid.RowDefinitions>
+                <Grid.ColumnDefinitions>
+                    <ColumnDefinition Width="Auto" />
+                    <ColumnDefinition Width="*" />
+                </Grid.ColumnDefinitions>
+                <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" FontSize="18" FontWeight="SemiBold"><Run>Version </Run> <Run Text="{Binding Version, Mode=OneWay}" /></TextBlock>
+                
+                <WebBrowser x:Name="ReleaseNotesWebBrowser" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Width="600" />
+                <Button Grid.Row="4" Grid.Column="0" Height="40" Width="150" Command="{Binding NextStepCommand}" Content="{Binding NextStepButtonText}" />
+            </Grid>
+        </Grid>
+    </Grid>
+</UserControl>
diff --git a/Filtration/Views/UpdateTabView.xaml.cs b/Filtration/Views/UpdateTabView.xaml.cs
new file mode 100644
index 0000000..3b3104f
--- /dev/null
+++ b/Filtration/Views/UpdateTabView.xaml.cs
@@ -0,0 +1,21 @@
+using System.Windows;
+using Filtration.ViewModels;
+
+namespace Filtration.Views
+{
+    public partial class UpdateTabView
+    {
+        public UpdateTabView()
+        {
+            InitializeComponent();
+
+            DataContextChanged += OnDataContextChanged;
+        }
+
+        private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
+        {
+            var updateViewModel = (UpdateViewModel)DataContext;
+            ReleaseNotesWebBrowser.NavigateToString(updateViewModel.ReleaseNotes);
+        }
+    }
+}
diff --git a/Filtration/Views/UpdateView.xaml b/Filtration/Views/UpdateView.xaml
new file mode 100644
index 0000000..ba21128
--- /dev/null
+++ b/Filtration/Views/UpdateView.xaml
@@ -0,0 +1,41 @@
+<UserControl x:Class="Filtration.Views.UpdateView"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:designTime="clr-namespace:Filtration.ViewModels.DesignTime"
+             mc:Ignorable="d" 
+             Visibility="{Binding Visible, Converter={StaticResource BooleanToVisibilityConverter}}"
+             Height="90" Width="250"
+             d:DataContext="{d:DesignInstance designTime:DesignTimeUpdateViewModel, IsDesignTimeCreatable=True}"
+             Background="White">
+    <UserControl.RenderTransform>
+        <TranslateTransform x:Name="UpdatePopupTransform" X="250" />
+    </UserControl.RenderTransform>
+    <UserControl.Triggers>
+        <!-- This EventTrigger/Storyboard animates the UpdateView so it slides in from the right when it is shown -->
+        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
+            <BeginStoryboard>
+                <Storyboard>
+                    <DoubleAnimation Storyboard.TargetName="UpdatePopupTransform" Storyboard.TargetProperty="(X)" To="0" Duration="0:0:1.25" />
+                </Storyboard>
+            </BeginStoryboard>
+        </EventTrigger>
+    </UserControl.Triggers>
+    <Border BorderBrush="Black" BorderThickness="1">
+        <Grid Margin="4">
+            <Grid.RowDefinitions>
+                <RowDefinition />
+                <RowDefinition />
+            </Grid.RowDefinitions>
+            <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Visibility="{Binding IsInErrorState, Converter={StaticResource InverseBooleanVisibilityConverter}}">A new version of Filtration is available!</TextBlock>
+            <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Red" Visibility="{Binding IsInErrorState, Converter={StaticResource BooleanToVisibilityConverter}}" TextWrapping="Wrap">An error occured while checking for updates</TextBlock>
+            <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center">
+            <Button  Command="{Binding NextStepCommand}" Width="160" Height="30">
+                <TextBlock Text="{Binding NextStepButtonText}" />
+            </Button>
+                <Button Height="30" Width="50" Margin="10,0,0,0" Command="{Binding HideUpdateWindowCommand}">Cancel</Button>
+            </StackPanel>
+        </Grid>
+    </Border>
+</UserControl>
diff --git a/Filtration/Views/UpdateAvailableView.xaml.cs b/Filtration/Views/UpdateView.xaml.cs
similarity index 55%
rename from Filtration/Views/UpdateAvailableView.xaml.cs
rename to Filtration/Views/UpdateView.xaml.cs
index 4274251..ac56223 100644
--- a/Filtration/Views/UpdateAvailableView.xaml.cs
+++ b/Filtration/Views/UpdateView.xaml.cs
@@ -1,8 +1,8 @@
 namespace Filtration.Views
 {
-    public partial class UpdateAvailableView
+    public partial class UpdateView
     {
-        public UpdateAvailableView()
+        public UpdateView()
         {
             InitializeComponent();
         }
diff --git a/Filtration/WindsorInstallers/ServicesInstaller.cs b/Filtration/WindsorInstallers/ServicesInstaller.cs
index d96e5a1..f736c1e 100644
--- a/Filtration/WindsorInstallers/ServicesInstaller.cs
+++ b/Filtration/WindsorInstallers/ServicesInstaller.cs
@@ -25,14 +25,24 @@ namespace Filtration.WindsorInstallers
                     .LifeStyle.Singleton);
 
             container.Register(
-                Component.For<IUpdateCheckService>()
-                    .ImplementedBy<UpdateCheckService>()
+                Component.For<IUpdateService>()
+                    .ImplementedBy<UpdateService>()
                     .LifeStyle.Singleton);
 
             container.Register(
                 Component.For<IClipboardService>()
                     .ImplementedBy<ClipboardService>()
                     .LifeStyle.Singleton);
+
+            container.Register(
+                Component.For<IBootstrapper>()
+                    .ImplementedBy<Bootstrapper>()
+                    .LifeStyle.Singleton);
+
+            container.Register(
+                Component.For<ISettingsService>()
+                    .ImplementedBy<SettingsService>()
+                    .LifeStyle.Singleton);
         }
     }
 }
diff --git a/Filtration/WindsorInstallers/ViewModelsInstaller.cs b/Filtration/WindsorInstallers/ViewModelsInstaller.cs
index 30afd6e..e4924af 100644
--- a/Filtration/WindsorInstallers/ViewModelsInstaller.cs
+++ b/Filtration/WindsorInstallers/ViewModelsInstaller.cs
@@ -68,9 +68,9 @@ namespace Filtration.WindsorInstallers
                     .LifeStyle.Transient);
 
             container.Register(
-                Component.For<IUpdateAvailableViewModel>()
-                    .ImplementedBy<UpdateAvailableViewModel>()
-                    .LifeStyle.Transient);
+                Component.For<IUpdateViewModel>()
+                    .ImplementedBy<UpdateViewModel>()
+                    .LifeStyle.Singleton);
 
             container.Register(
                 Component.For<IItemFilterBlockViewModelFactory>().AsFactory());
diff --git a/Filtration/packages.config b/Filtration/packages.config
index d24e04a..0b98c5b 100644
--- a/Filtration/packages.config
+++ b/Filtration/packages.config
@@ -5,13 +5,21 @@
   <package id="Castle.Windsor" version="3.4.0" targetFramework="net461" />
   <package id="CommonServiceLocator" version="1.3" targetFramework="net451" />
   <package id="ControlzEx" version="2.2.0.4" targetFramework="net461" />
+  <package id="DeltaCompressionDotNet" version="1.1.0" targetFramework="net461" />
   <package id="Extended.Wpf.Toolkit" version="2.9" targetFramework="net461" />
   <package id="Fluent.Ribbon" version="4.0.3.394" targetFramework="net461" />
   <package id="MahApps.Metro" version="1.2.4.0" targetFramework="net461" />
+  <package id="Mono.Cecil" version="0.9.6.1" targetFramework="net461" />
   <package id="MvvmLightLibs" version="5.3.0.0" targetFramework="net461" />
   <package id="NLog" version="4.4.9" targetFramework="net461" />
   <package id="NLog.Config" version="4.3.7" targetFramework="net461" />
   <package id="NLog.Schema" version="4.4.9" targetFramework="net461" />
+  <package id="NuGet.CommandLine" version="4.7.1" targetFramework="net461" developmentDependency="true" />
+  <package id="SharpCompress" version="0.17.1" targetFramework="net461" />
+  <package id="Splat" version="1.6.2" targetFramework="net461" />
+  <package id="squirrel.windows" version="1.8.0" targetFramework="net461" />
+  <package id="WindowsAPICodePack-Core" version="1.1.2" targetFramework="net461" />
+  <package id="WindowsAPICodePack-Shell" version="1.1.1" targetFramework="net461" />
   <package id="WpfAnimatedGif" version="1.4.14" targetFramework="net461" />
   <package id="WPFToolkit" version="3.5.50211.1" targetFramework="net451" />
 </packages>
\ No newline at end of file