private void StartCompiler()
        {
            CompileInProgress = true;
            //Settings.Save(); //Persist controller mixin option, keybinds injection
            NamedBackgroundWorker nbw = new NamedBackgroundWorker(@"ModmakerCompiler");

            nbw.DoWork += (a, b) =>
            {
                string modDelta = null;

                if (int.TryParse(ModMakerCode, out var code))
                {
                    DownloadAndModNameText = M3L.GetString(M3L.string_downloadingModDeltaFromME3Tweaks);
                    var normalEndpoint = OnlineContent.ModmakerModsEndpoint + code;
                    var lzmaEndpoint   = normalEndpoint + @"&method=lzma";
                    Log.Information($@"Downloading modmaker mod {code}");

                    //Try LZMA first
                    try
                    {
                        var download = OnlineContent.DownloadToMemory(lzmaEndpoint, (done, total) =>
                        {
                            if (total != -1)
                            {
                                var suffix             = $@" {(done * 100.0 / total).ToString(@"0")}%"; //do not localize
                                DownloadAndModNameText = M3L.GetString(M3L.string_downloadingModDeltaFromME3Tweaks) + suffix;
                            }
                            else
                            {
                                DownloadAndModNameText = M3L.GetString(M3L.string_downloadingModDeltaFromME3Tweaks);
                            }
                        });
                        if (download.errorMessage == null)
                        {
                            DownloadAndModNameText = M3L.GetString(M3L.string_decompressingDelta);
                            // OK
                            modDelta = Encoding.UTF8.GetString(StreamingLZMAWrapper.DecompressLZMA(download.result));
                        }
                        else
                        {
                            Log.Error(@"Error downloading lzma mod delta to memory: " + download.errorMessage);
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Error(@"Error downloading LZMA mod delta to memory: " + e.Message);
                    }

                    if (modDelta == null)
                    {
                        //failed to download LZMA.
                        var download = OnlineContent.DownloadToMemory(normalEndpoint, (done, total) =>
                        {
                            var suffix             = $" {(done * 100.0 / total).ToString(@"0")}%"; //do not localize
                            DownloadAndModNameText = M3L.GetString(M3L.string_downloadingModDeltaFromME3Tweaks) + suffix;
                        });
                        if (download.errorMessage == null)
                        {
                            //OK
                            modDelta = Encoding.UTF8.GetString(download.result.ToArray());
                        }
                        else
                        {
                            Log.Error(@"Error downloading decompressed mod delta to memory: " + download.errorMessage);
                        }
                    }
                }
                else if (File.Exists(LocalFilePath))
                {
                    modDelta = File.ReadAllText(LocalFilePath);
                }


                if (modDelta != null)
                {
                    KeepOpenWhenThreadFinishes = false;
                    var compiler = new ModMakerCompiler(code);
                    compiler.SetCurrentMaxCallback               = SetCurrentMax;
                    compiler.SetCurrentValueCallback             = SetCurrentProgressValue;
                    compiler.SetOverallMaxCallback               = SetOverallMax;
                    compiler.SetOverallValueCallback             = SetOverallValue;
                    compiler.SetCurrentTaskIndeterminateCallback = SetCurrentTaskIndeterminate;
                    compiler.SetCurrentTaskStringCallback        = SetCurrentTaskString;
                    compiler.SetModNameCallback       = SetModNameOrDownloadText;
                    compiler.SetCompileStarted        = CompilationInProgress;
                    compiler.SetModNotFoundCallback   = ModNotFound;
                    compiler.NotifySomeDLCIsMissing   = NotifySomeDLCIsMissing;
                    compiler.ShowErrorMessageCallback = ShowErrorMessage;
                    var m = compiler.DownloadAndCompileMod(modDelta);
                    if (m != null && !LocalFileOption)
                    {
                        var sanitizedname = Utilities.SanitizePath(m.ModName);
                        File.WriteAllText(Path.Combine(Utilities.GetModmakerDefinitionsCache(), $@"{code}-{sanitizedname}.xml"), modDelta);
                    }
                    b.Result = m;
                }
            };
            nbw.RunWorkerCompleted += (a, b) =>
            {
                if (b.Error != null)
                {
                    Log.Error($@"Exception occurred in {nbw.Name} thread: {b.Error.Message}");
                }
                CompileInProgress = false;
                if (!KeepOpenWhenThreadFinishes && b.Result is Mod m)
                {
                    OnClosing(new DataEventArgs(m));
                }
                else
                {
                    CloseProgressPanel();
                    //ShowCloseButton = true;
                }
                CommandManager.InvalidateRequerySuggested();
            };
            nbw.RunWorkerAsync();
        }
        private void UpdateModMakerMod(OnlineContent.ModMakerModUpdateInfo mui, Action downloadCompleted)
        {
            //throw new NotImplementedException();
            NamedBackgroundWorker nbw = new NamedBackgroundWorker(@"ModmakerModUpdaterThread-" + mui.mod.ModName);

            nbw.WorkerReportsProgress = true;
            nbw.ProgressChanged      += (a, b) =>
            {
                if (b.UserState is double d)
                {
                    TaskbarHelper.SetProgress(d);
                }
            };
            nbw.DoWork += (a, b) =>
            {
                mui.DownloadButtonText = M3L.GetString(M3L.string_compiling);

                OperationInProgress  = true;
                mui.UpdateInProgress = true;
                mui.Indeterminate    = false;

                mui.UIStatusString = M3L.GetString(M3L.string_downloadingDelta);
                var normalEndpoint = OnlineContent.ModmakerModsEndpoint + mui.ModMakerId;
                var lzmaEndpoint   = normalEndpoint + @"&method=lzma";

                string modDelta = null;

                //Try LZMA first
                try
                {
                    var download = OnlineContent.DownloadToMemory(lzmaEndpoint);
                    if (download.errorMessage == null)
                    {
                        mui.UIStatusString = M3L.GetString(M3L.string_decompressingDelta);
                        // OK
                        var decompressed = StreamingLZMAWrapper.DecompressLZMA(download.result);
                        modDelta = Encoding.UTF8.GetString(decompressed);
                    }
                    else
                    {
                        Log.Error(@"Error downloading lzma mod delta to memory: " + download.errorMessage);
                    }
                }
                catch (Exception e)
                {
                    Log.Error(@"Error downloading LZMA mod delta to memory: " + e.Message);
                }

                if (modDelta == null)
                {
                    //failed to download LZMA.
                    var download = OnlineContent.DownloadToMemory(normalEndpoint);
                    if (download.errorMessage == null)
                    {
                        //OK
                        modDelta = Encoding.UTF8.GetString(download.result.ToArray());
                    }
                    else
                    {
                        Log.Error(@"Error downloading decompressed mod delta to memory: " + download.errorMessage);
                    }
                }

                void setOverallMax(int max)
                {
                    mui.OverallProgressMax = max;
                }

                void setOverallValue(int current)
                {
                    mui.OverallProgressValue = current;
                    nbw.ReportProgress(0, current * 1.0 / mui.OverallProgressMax);
                    if (current > mui.OverallProgressMax)
                    {
                        Debugger.Break();
                    }
                }

                void setCurrentTaskString(string str)
                {
                    mui.UIStatusString = str;
                }

                if (modDelta != null)
                {
                    var compiler = new ModMakerCompiler(mui.ModMakerId);
                    compiler.SetOverallMaxCallback        = setOverallMax;
                    compiler.SetOverallValueCallback      = setOverallValue;
                    compiler.SetCurrentTaskStringCallback = setCurrentTaskString;
                    var m = compiler.DownloadAndCompileMod(modDelta, mui.mod.ModPath);
                    if (m != null)
                    {
                        try
                        {
                            File.WriteAllText(System.IO.Path.Combine(Utilities.GetModmakerDefinitionsCache(), mui.ModMakerId + @".xml"), modDelta);
                        }
                        catch (Exception e)
                        {
                            Log.Error(@"Couldn't cache modmaker xml file: " + e.Message);
                        }

                        mui.DownloadButtonText = M3L.GetString(M3L.string_updated);
                        mui.UIStatusString     = M3L.GetString(M3L.string_interp_modMakerCodeX, mui.ModMakerId);
                        mui.UpdateInProgress   = false;
                        mui.CanUpdate          = false;
                        AnyModUpdated          = true;
                    }
                    else
                    {
                        mui.UpdateInProgress   = false;
                        mui.DownloadButtonText = M3L.GetString(M3L.string_compilingFailed);
                        mui.UpdateInProgress   = false;
                    }
                }
            };
            nbw.RunWorkerCompleted += (a, b) =>
            {
                if (b.Error != null)
                {
                    Log.Error($@"Exception occurred in {nbw.Name} thread: {b.Error.Message}");
                }
                Analytics.TrackEvent(@"Updated mod", new Dictionary <string, string>()
                {
                    { @"Type", @"ModMaker" },
                    { @"ModName", mui.mod.ModName },
                    { @"Result", mui.CanUpdate ? @"Success" : @"Failed" }
                });

                TaskbarHelper.SetProgressState(TaskbarProgressBarState.NoProgress);
                OperationInProgress = false;
                CommandManager.InvalidateRequerySuggested();
                downloadCompleted?.Invoke();
            };
            TaskbarHelper.SetProgress(0);
            TaskbarHelper.SetProgressState(TaskbarProgressBarState.Normal);
            nbw.RunWorkerAsync();
        }