diff --git a/Wabbajack.Common/Utils.cs b/Wabbajack.Common/Utils.cs
index 3c8a448c..7ca9e3a0 100644
--- a/Wabbajack.Common/Utils.cs
+++ b/Wabbajack.Common/Utils.cs
@@ -652,5 +652,10 @@ namespace Wabbajack.Common
             return d.Deserialize<T>(new StringReader(s));
         }
 
+        public static void LogStatus(string s)
+        {
+            Status(s);
+            Log(s);
+        }
     }
 }
\ No newline at end of file
diff --git a/Wabbajack.Lib/Installer.cs b/Wabbajack.Lib/Installer.cs
index a5bdeabb..cbedd716 100644
--- a/Wabbajack.Lib/Installer.cs
+++ b/Wabbajack.Lib/Installer.cs
@@ -66,7 +66,7 @@ namespace Wabbajack.Lib
             throw new Exception(msg);
         }
 
-        private byte[] LoadBytesFromPath(string path)
+        public byte[] LoadBytesFromPath(string path)
         {
             using (var fs = new FileStream(ModListArchive, FileMode.Open, FileAccess.Read, FileShare.Read))
             using (var ar = new ZipArchive(fs, ZipArchiveMode.Read))
@@ -155,6 +155,8 @@ namespace Wabbajack.Lib
             InstallIncludedFiles();
             BuildBSAs();
 
+            zEditIntegration.GenerateMerges(this);
+
             Info("Installation complete! You may exit the program.");
             // Removed until we decide if we want this functionality
             // Nexus devs weren't sure this was a good idea, I (halgari) agree.
diff --git a/Wabbajack.Lib/zEditIntegration.cs b/Wabbajack.Lib/zEditIntegration.cs
index 93f1327e..386b13ad 100644
--- a/Wabbajack.Lib/zEditIntegration.cs
+++ b/Wabbajack.Lib/zEditIntegration.cs
@@ -115,7 +115,7 @@ namespace Wabbajack.Lib
             }
         }
 
-        class zEditMerge
+        public class zEditMerge
         {
             public string name;
             public string filename;
@@ -123,7 +123,7 @@ namespace Wabbajack.Lib
 
         }
 
-        class zEditMergePlugin
+        public class zEditMergePlugin
         {
             public string filename;
             public string dataFolder;
@@ -147,5 +147,24 @@ namespace Wabbajack.Lib
                 }
             }
         }
+
+        public static void GenerateMerges(Installer installer)
+        {
+            installer.ModList
+                .Directives
+                .OfType<MergedPatch>()
+                .PMap(m =>
+                {
+                    Utils.LogStatus($"Generating zEdit merge: {m.To}");
+
+                    var src_data = m.Sources.Select(s => File.ReadAllBytes(Path.Combine(installer.Outputfolder, s.RelativePath)))
+                        .ConcatArrays();
+
+                    var patch_data = installer.LoadBytesFromPath(m.PatchID);
+
+                    using (var fs = File.OpenWrite(Path.Combine(installer.Outputfolder, m.To))) 
+                        BSDiff.Apply(new MemoryStream(src_data), () => new MemoryStream(patch_data), fs);
+                });
+        }
     }
 }
diff --git a/Wabbajack.Test/ACompilerTest.cs b/Wabbajack.Test/ACompilerTest.cs
index bac2aeeb..9a0eb223 100644
--- a/Wabbajack.Test/ACompilerTest.cs
+++ b/Wabbajack.Test/ACompilerTest.cs
@@ -51,5 +51,20 @@ namespace Wabbajack.Test
             var compiler = new Compiler(utils.MO2Folder);
             return compiler;
         }
+        protected ModList CompileAndInstall(string profile)
+        {
+            var compiler = ConfigureAndRunCompiler(profile);
+            Install(compiler);
+            return compiler.ModList;
+        }
+
+        protected void Install(Compiler compiler)
+        {
+            var modlist = Installer.LoadFromFile(compiler.ModListOutputFile);
+            var installer = new Installer(compiler.ModListOutputFile, modlist, utils.InstallFolder);
+            installer.DownloadFolder = utils.DownloadsFolder;
+            installer.GameFolder = utils.GameFolder;
+            installer.Install();
+        }
     }
 }
diff --git a/Wabbajack.Test/SanityTests.cs b/Wabbajack.Test/SanityTests.cs
index 5c66ec7d..19115113 100644
--- a/Wabbajack.Test/SanityTests.cs
+++ b/Wabbajack.Test/SanityTests.cs
@@ -72,21 +72,5 @@ namespace Wabbajack.Test
             Assert.IsInstanceOfType(directive, typeof(PatchedFromArchive));
         }
 
-
-        private ModList CompileAndInstall(string profile)
-        {
-            var compiler = ConfigureAndRunCompiler(profile);
-            Install(compiler);
-            return compiler.ModList;
-        }
-
-        private void Install(Compiler compiler)
-        {
-            var modlist = Installer.LoadFromFile(compiler.ModListOutputFile);
-            var installer = new Installer(compiler.ModListOutputFile, modlist, utils.InstallFolder);
-            installer.DownloadFolder = utils.DownloadsFolder;
-            installer.GameFolder = utils.GameFolder;
-            installer.Install();
-        }
     }
 }
diff --git a/Wabbajack.Test/Wabbajack.Test.csproj b/Wabbajack.Test/Wabbajack.Test.csproj
index e3a063d3..50b69ed8 100644
--- a/Wabbajack.Test/Wabbajack.Test.csproj
+++ b/Wabbajack.Test/Wabbajack.Test.csproj
@@ -71,6 +71,9 @@
     <Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
       <HintPath>..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
     </Reference>
+    <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+      <HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
+    </Reference>
     <Reference Include="PresentationCore" />
     <Reference Include="PresentationFramework" />
     <Reference Include="ReactiveUI, Version=10.5.0.0, Culture=neutral, processorArchitecture=MSIL">
@@ -122,6 +125,7 @@
     <Compile Include="ContentRightsManagementTests.cs" />
     <Compile Include="CompilationStackTests.cs" />
     <Compile Include="WebAutomationTests.cs" />
+    <Compile Include="zEditIntegrationTests.cs" />
   </ItemGroup>
   <ItemGroup>
     <None Include="app.config" />
diff --git a/Wabbajack.Test/ZEditIntegrationTests.cs b/Wabbajack.Test/ZEditIntegrationTests.cs
new file mode 100644
index 00000000..15fff578
--- /dev/null
+++ b/Wabbajack.Test/ZEditIntegrationTests.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Alphaleonis.Win32.Filesystem;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Wabbajack.Common;
+using Wabbajack.Lib;
+
+namespace Wabbajack.Test
+{
+    [TestClass]
+    public class zEditIntegrationTests : ACompilerTest
+    {
+        [TestMethod]
+        public void CanCreatezEditPatches()
+        {
+            var profile = utils.AddProfile();
+            var moda = utils.AddMod();
+            var modb = utils.AddMod();
+            var moddest = utils.AddMod();
+            var srca = utils.AddModFile(moda, @"srca.esp", 10);
+            var srcb = utils.AddModFile(moda, @"srcb.esp", 10);
+            var srcc = utils.AddModFile(modb, @"srcd.esp", 10);
+            var dest = utils.AddModFile(moddest, @"merged.esp", 20);
+
+            var srcs = new List<string> {srca, srcb, srcc};
+
+
+            Directory.CreateDirectory(Path.Combine(utils.MO2Folder, "tools", "mator", "bleh", "profiles", "myprofile"));
+            new List<zEditIntegration.zEditMerge>()
+            {
+                new zEditIntegration.zEditMerge()
+                {
+                    name = moddest,
+                    filename = "merged.esp",
+                    plugins = new List<zEditIntegration.zEditMergePlugin>()
+                    {
+                        new zEditIntegration.zEditMergePlugin()
+                        {
+                            filename = srca,
+                            dataFolder = Path.GetDirectoryName(srca),
+                        },
+                        new zEditIntegration.zEditMergePlugin()
+                        {
+                            filename = srcb,
+                            dataFolder = Path.GetDirectoryName(srcb),
+                        },
+                        new zEditIntegration.zEditMergePlugin()
+                        {
+                            filename = srcc,
+                            dataFolder = Path.GetDirectoryName(srcc),
+                        }
+                    }
+                }
+            }.ToJSON(Path.Combine(utils.MO2Folder, "tools", "mator", "bleh", "profiles", "myprofile", "merges.json"));
+
+            utils.Configure();
+
+
+            utils.AddManualDownload(
+                new Dictionary<string, byte[]> { { "srca.esp", File.ReadAllBytes(srca) } });
+            utils.AddManualDownload(
+                new Dictionary<string, byte[]> { { "srcb.esp", File.ReadAllBytes(srcb) } });
+            utils.AddManualDownload(
+                new Dictionary<string, byte[]> { { "srcc.esp", File.ReadAllBytes(srcc) } });
+
+            File.AppendAllLines(Path.Combine(utils.MO2Folder, "ModOrganizer.ini"),
+                new List<string>
+                {
+                    "[customExecutables]",
+                    "size=1",
+                    $@"1\binary={utils.MO2Folder.Replace('\\','/')}/tools/mator/bleh/zEdit.exe"
+
+                });
+
+            var modlist = CompileAndInstall(profile);
+            var directive = modlist.Directives.Where(m => m.To == $"mods\\{moddest}\\merged.esp").FirstOrDefault();
+
+            Assert.IsNotNull(directive);
+            Assert.IsInstanceOfType(directive, typeof(MergedPatch));
+
+            var merged = directive as MergedPatch;
+
+            foreach (var (source, path) in merged.Sources.Zip(srcs, (a, b) => (a, b)))
+            {
+                Assert.AreEqual(source.Hash, Utils.FileHash(path));
+            }
+
+            utils.VerifyInstalledFile(moddest, "merged.esp");
+
+        }
+    }
+}
diff --git a/Wabbajack.Test/packages.config b/Wabbajack.Test/packages.config
index 87fd1b36..ce27ac3f 100644
--- a/Wabbajack.Test/packages.config
+++ b/Wabbajack.Test/packages.config
@@ -4,6 +4,7 @@
   <package id="DynamicData" version="6.13.18" targetFramework="net472" />
   <package id="MSTest.TestAdapter" version="1.3.2" targetFramework="net472" />
   <package id="MSTest.TestFramework" version="1.3.2" targetFramework="net472" />
+  <package id="Newtonsoft.Json" version="12.0.2" targetFramework="net472" />
   <package id="ReactiveUI" version="10.5.7" targetFramework="net472" />
   <package id="Splat" version="9.1.1" targetFramework="net472" />
   <package id="Splat.Drawing" version="9.1.1" targetFramework="net472" />