async Task Run()
        {
            Launcher launcher = null;
            IInstallLocation installLocation = null;
            try
            {
                launcher = new Launcher(Path.Combine(config.RootDirFullPath, "Launcher"));
                installLocation = new InstallLocation(Path.Combine(config.RootDirFullPath, "Bin"),
                    config.WurmAssistantExeFileName,
                    new ProcessRunner());

                launcher.EnterLock();

                LauncherData launcherData = launcher.GetPersistentData();

                IStagingLocation stagingLocation =
                    new StagingLocation(Path.Combine(config.RootDirFullPath, "Staging"));
                IWurmAssistantService wurmAssistantService = new WurmAssistantService(
                    config.WebServiceRootUrl,
                    stagingLocation);

                stagingLocation.ClearExtractionDir();

                if (installLocation.Installed)
                {
                    if (stagingLocation.AnyPackageStaged)
                    {
                        var latestStagedPackage = stagingLocation.GetLatestStagedPackage();
                        gui.ShowGui();
                        gui.AddUserMessage("Updating to version " + latestStagedPackage.Version);
                        gui.SetProgressStatus("Updating...");
                        gui.SetProgressPercent(null);
                        stagingLocation.ExtractIntoExtractionDir(latestStagedPackage);
                        installLocation.ClearLocation();
                        stagingLocation.MoveExtractionDir(installLocation.InstallLocationPath);
                        stagingLocation.ClearStagingArea();
                        launcherData.WurmAssistantInstalledVersion = latestStagedPackage.Version;
                        launcher.SavePersistentData();
                        gui.AddUserMessage("Update complete");
                        gui.SetProgressStatus("Update complete");
                        await Task.Delay(TimeSpan.FromSeconds(1));
                        gui.HideGui();
                    }
                    TryRunWurmAssistant(installLocation);

                    await CheckAndDownloadLatestPackage(wurmAssistantService, launcher, launcherData);
                }
                else
                {
                    gui.ShowGui();
                    gui.AddUserMessage("Installing latest version of Wurm Assistant");
                    var latestVersion = await wurmAssistantService.GetLatestVersionAsync(gui);
                    var latestPackage = await wurmAssistantService.GetPackageAsync(gui, latestVersion);
                    gui.AddUserMessage("Extracting Wurm Assistant version " + latestVersion);
                    latestPackage.ExtractIntoDirectory(installLocation.InstallLocationPath);
                    launcherData.WurmAssistantInstalledVersion = latestVersion;
                    launcher.SavePersistentData();
                    gui.AddUserMessage("Installation complete.");
                    gui.AddUserMessage("Starting Wurm Assistant...");
                    await Task.Delay(TimeSpan.FromSeconds(1));
                    installLocation.RunWurmAssistant();
                    gui.HideGui();
                    stagingLocation.ClearStagingArea();
                }

                launcher.SavePersistentData();

                gui.HideGui();
                host.Close();
            }
            catch (LockFailedException exception)
            {
                debug.Write("LockFailedException: " + exception.ToString());
                if (installLocation != null)
                {
                    if (installLocation.Installed)
                    {
                        TryRunWurmAssistant(installLocation);
                    }
                }
                host.Close();
            }
            finally
            {
                if (launcher != null)
                {
                    launcher.ReleaseLock();
                }
            }
        }