/// <summary>
        /// Steps to take on succesful (re)authorization
        /// </summary>
        /// <param name="target"></param>
        private static RenewResult OnRenewSuccess(ILifetimeScope renewalScope, ScheduledRenewal renewal)
        {
            RenewResult result = null;

            try
            {
                var certificateService = renewalScope.Resolve <CertificateService>();
                var storePlugin        = renewalScope.Resolve <IStorePlugin>();
                var oldCertificate     = renewal.Certificate(storePlugin);
                var newCertificate     = certificateService.RequestCertificate(renewal.Binding);

                // Test if a new certificate has been generated
                if (newCertificate == null)
                {
                    return(new RenewResult(new Exception("No certificate generated")));
                }
                else
                {
                    result = new RenewResult(newCertificate);
                }

                // Early escape for testing validation only
                if (_options.Test &&
                    renewal.New &&
                    !_input.PromptYesNo($"[--test] Do you want to install the certificate?"))
                {
                    return(result);
                }

                try
                {
                    // Check if the newly requested certificate is already in the store,
                    // which might be the case due to the cache mechanism built into the
                    // RequestCertificate function
                    var storedCertificate = storePlugin.FindByThumbprint(newCertificate.Certificate.Thumbprint);
                    if (storedCertificate != null)
                    {
                        // Copy relevant properties
                        _log.Warning("Certificate with thumbprint {thumbprint} is already in the store", newCertificate.Certificate.Thumbprint);
                        newCertificate.Store = storedCertificate.Store;
                    }
                    else
                    {
                        // Save to store
                        storePlugin.Save(newCertificate);
                    }
                }
                catch (Exception ex)
                {
                    _log.Error(ex, "Unable to store certificate");
                    result.Success      = false;
                    result.ErrorMessage = $"Store failed: {ex.Message}";
                    return(result);
                }

                // Run installation plugin(s)
                try
                {
                    var installFactories = renewalScope.Resolve <List <IInstallationPluginFactory> >();
                    var steps            = installFactories.Count();
                    for (var i = 0; i < steps; i++)
                    {
                        var installFactory = installFactories[i];
                        if (!(installFactory is INull))
                        {
                            var installInstance = (IInstallationPlugin)renewalScope.Resolve(installFactory.Instance);
                            if (steps > 1)
                            {
                                _log.Information("Installation step {n}/{m}: {name}...", i + 1, steps, installFactory.Description);
                            }
                            else
                            {
                                _log.Information("Installing with {name}...", installFactory.Description);
                            }
                            installInstance.Install(newCertificate, oldCertificate);
                        }
                    }
                }
                catch (Exception ex)
                {
                    _log.Error(ex, "Unable to install certificate");
                    result.Success      = false;
                    result.ErrorMessage = $"Install failed: {ex.Message}";
                }

                // Delete the old certificate if not forbidden, found and not re-used
                if ((!renewal.KeepExisting ?? false) &&
                    oldCertificate != null &&
                    newCertificate.Certificate.Thumbprint != oldCertificate.Certificate.Thumbprint)
                {
                    try
                    {
                        storePlugin.Delete(oldCertificate);
                    }
                    catch (Exception ex)
                    {
                        _log.Error(ex, "Unable to delete previous certificate");
                        //result.Success = false; // not a show-stopper, consider the renewal a success
                        result.ErrorMessage = $"Delete failed: {ex.Message}";
                    }
                }

                // Add or update renewal
                if (renewal.New &&
                    !_options.NoTaskScheduler &&
                    (!_options.Test ||
                     _input.PromptYesNo($"Do you want to automatically renew this certificate in {_renewalService.RenewalPeriod} days?")))
                {
                    var taskScheduler = _container.Resolve <TaskSchedulerService>();
                    taskScheduler.EnsureTaskScheduler();
                    _renewalService.Save(renewal, result);
                }
                return(result);
            }
            catch (Exception ex)
            {
                // Result might still contain the Thumbprint of the certificate
                // that was requested and (partially? installed, which might help
                // with debugging
                HandleException(ex);
                if (result == null)
                {
                    result = new RenewResult(ex);
                }
                else
                {
                    result.Success      = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return(result);
        }
        /// <summary>
        /// Steps to take on succesful (re)authorization
        /// </summary>
        /// <param name="target"></param>
        private static RenewResult OnRenewSuccess(ILifetimeScope renewalScope, ScheduledRenewal renewal)
        {
            RenewResult result = null;

            try
            {
                var certificateService = renewalScope.Resolve <CertificateService>();
                var storePlugin        = renewalScope.Resolve <IStorePlugin>();
                var oldCertificate     = renewal.Certificate(storePlugin);
                var newCertificate     = certificateService.RequestCertificate(renewal.Binding);
                if (newCertificate == null)
                {
                    return(new RenewResult(new Exception("No certificate generated")));
                }
                else
                {
                    result = new RenewResult(newCertificate);
                }

                // Early escape for testing validation only
                if (_options.Test &&
                    renewal.New &&
                    !_input.PromptYesNo($"Do you want to save the certificate?"))
                {
                    return(result);
                }

                // Save to store
                storePlugin.Save(newCertificate);

                // Run installation plugin(s)
                try
                {
                    var installFactories = renewalScope.Resolve <List <IInstallationPluginFactory> >();
                    var steps            = installFactories.Count();
                    for (var i = 0; i < steps; i++)
                    {
                        var installFactory = installFactories[i];
                        if (!(installFactory is INull))
                        {
                            var installInstance = (IInstallationPlugin)renewalScope.Resolve(installFactory.Instance);
                            if (steps > 1)
                            {
                                _log.Information("Installation step {n}/{m}: {name}...", i + 1, steps, installFactory.Description);
                            }
                            else
                            {
                                _log.Information("Installing with {name}...", installFactory.Description);
                            }
                            installInstance.Install(newCertificate, oldCertificate);
                        }
                    }
                }
                catch (Exception ex)
                {
                    _log.Error(ex, "Unable to install certificate");
                    result.Success      = false;
                    result.ErrorMessage = $"Install failed: {ex.Message}";
                }

                // Delete the old certificate if specified and found
                if (!renewal.KeepExisting && oldCertificate != null)
                {
                    try
                    {
                        storePlugin.Delete(oldCertificate);
                    }
                    catch (Exception ex)
                    {
                        _log.Error(ex, "Unable to delete previous certificate");
                        //result.Success = false; // not a show-stopper, consider the renewal a success
                        result.ErrorMessage = $"Delete failed: {ex.Message}";
                    }
                }

                // Add or update renewal
                if (renewal.New &&
                    !_options.NoTaskScheduler &&
                    (!_options.Test ||
                     _input.PromptYesNo($"Do you want to automatically renew this certificate in {_renewalService.RenewalPeriod} days? This will add a task scheduler task.")))
                {
                    var taskScheduler = _container.Resolve <TaskSchedulerService>();
                    taskScheduler.EnsureTaskScheduler();
                    _renewalService.Save(renewal, result);
                }
                return(result);
            }
            catch (Exception ex)
            {
                // Result might still contain the Thumbprint of the certificate
                // that was requested and (partially? installed, which might help
                // with debugging
                HandleException(ex);
                if (result == null)
                {
                    result = new RenewResult(ex);
                }
                else
                {
                    result.Success      = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return(result);
        }
        /// <summary>
        /// Steps to take on succesful (re)authorization
        /// </summary>
        /// <param name="binding"></param>
        public static RenewResult OnAutoSuccess(Target binding)
        {
            RenewResult result = new RenewResult(new Exception("Unknown error after validation"));

            try
            {
                var scheduled         = _renewalService.Find(binding);
                var oldCertificate    = FindCertificate(scheduled);
                var newCertificate    = _certificateService.RequestCertificate(binding);
                var newCertificatePfx = new FileInfo(_certificateService.PfxFilePath(binding));
                result = new RenewResult(newCertificate);

                if (_options.Test &&
                    !_options.Renew &&
                    !_input.PromptYesNo($"Do you want to install the certificate?"))
                {
                    return(result);
                }

                SaveCertificate(binding.GetHosts(true), newCertificate, newCertificatePfx);

                if (_options.Renew ||
                    !_options.Test ||
                    _input.PromptYesNo($"Do you want to add/update the certificate to your server software?"))
                {
                    _log.Information("Installing SSL certificate in server software");
                    if (_options.CentralSsl)
                    {
                        binding.Plugin.Install(binding);
                    }
                    else
                    {
                        binding.Plugin.Install(binding, newCertificatePfx.FullName, _certificateStoreService.DefaultStore, newCertificate, oldCertificate);
                    }

                    if (!_options.KeepExisting && oldCertificate != null)
                    {
                        DeleteCertificate(oldCertificate.Thumbprint);
                    }
                }

                if (!_options.Renew &&
                    (scheduled != null ||
                     !_options.Test ||
                     _input.PromptYesNo($"Do you want to automatically renew this certificate in {_renewalService.RenewalPeriod} days? This will add a task scheduler task.")))
                {
                    _renewalService.CreateOrUpdate(binding, result);
                }
                return(result);
            }
            catch (Exception ex)
            {
                // Result might still contain the Thumbprint of the certificate
                // that was requested and (partially? installed, which might help
                // with debugging
                HandleException(ex);
                result.Success      = false;
                result.ErrorMessage = ex.Message;
            }
            return(result);
        }