private static void ConfigureJob <T>(ServiceConfigurator <T> configurator, Action <QuartzConfigurator> jobConfigurator) where T : class
        {
            var log = HostLogger.Get(typeof(ScheduleJobServiceConfiguratorExtensions));

            var jobConfig = new QuartzConfigurator();

            jobConfigurator(jobConfig);

            if (jobConfig.JobEnabled == null || jobConfig.JobEnabled() || (jobConfig.Job == null || jobConfig.Triggers == null))
            {
                var jobDetail   = jobConfig.Job();
                var jobTriggers = jobConfig.Triggers.Select(triggerFactory => triggerFactory()).Where(trigger => trigger != null);

                configurator.BeforeStartingService(() =>
                {
                    log.Debug("[Topshelf.Quartz] Scheduler starting up...");
                    if (Scheduler == null)
                    {
                        Scheduler = GetScheduler();
                    }


                    if (Scheduler != null && jobDetail != null && jobTriggers.Any())
                    {
                        var triggersForJob = new HashSet <ITrigger>(jobTriggers);
                        Scheduler.ScheduleJob(jobDetail, triggersForJob, false);
                        log.Info(string.Format("[Topshelf.Quartz] Scheduled Job: {0}", jobDetail.Key));

                        foreach (var trigger in triggersForJob)
                        {
                            log.Info(string.Format("[Topshelf.Quartz] Job Schedule: {0} - Next Fire Time (local): {1}", trigger, trigger.GetNextFireTimeUtc().HasValue ? trigger.GetNextFireTimeUtc().Value.ToLocalTime().ToString() : "none"));
                        }

                        Scheduler.Start();
                        log.Info("[Topshelf.Quartz] Scheduler started...");
                    }
                });

                configurator.BeforeStoppingService(() =>
                {
                    log.Info("[Topshelf.Quartz] Scheduler shutting down...");

                    var executingJobs = Scheduler.GetCurrentlyExecutingJobs();
                    foreach (var job in executingJobs)
                    {
                        log.InfoFormat("[Topshelf.Quartz] Attempt to interrupt currently executing job: {0}", job.JobDetail.JobType);
                        if (job.JobInstance.GetType().GetInterfaces().Contains(typeof(IInterruptableJob)))
                        {
                            ((IInterruptableJob)job.JobInstance).Interrupt();
                        }
                    }
                    Scheduler.Shutdown(true);
                    log.Info("[Topshelf.Quartz] Scheduler shut down...");
                });
            }
        }
        private static void ConfigureJob <T>(ServiceConfigurator <T> configurator, Action <QuartzConfigurator> jobConfigurator, bool replaceJob = false) where T : class
        {
            var log = HostLogger.Get(typeof(ScheduleJobServiceConfiguratorExtensions));

            var jobConfig = new QuartzConfigurator();

            jobConfigurator(jobConfig);

            if (jobConfig.JobEnabled == null || jobConfig.JobEnabled() || (jobConfig.Job == null || jobConfig.Triggers == null))
            {
                var jobDetail         = jobConfig.Job();
                var jobTriggers       = jobConfig.Triggers.Select(triggerFactory => triggerFactory()).Where(trigger => trigger != null);
                var jobListeners      = jobConfig.JobListeners;
                var triggerListeners  = jobConfig.TriggerListeners;
                var scheduleListeners = jobConfig.ScheduleListeners;
                configurator.BeforeStartingService(() =>
                {
                    log.Debug("[Topshelf.Quartz] Scheduler starting up...");
                    if (Scheduler == null)
                    {
                        Scheduler = GetScheduler();
                    }


                    if (Scheduler != null && jobDetail != null && jobTriggers.Any())
                    {
                        var triggersForJob = new HashSet <ITrigger>(jobTriggers);
                        Scheduler.ScheduleJob(jobDetail, triggersForJob, replaceJob);
                        log.Info(string.Format("[Topshelf.Quartz] Scheduled Job: {0}", jobDetail.Key));

                        foreach (var trigger in triggersForJob)
                        {
                            log.Info(string.Format("[Topshelf.Quartz] Job Schedule: {0} - Next Fire Time (local): {1}", trigger, trigger.GetNextFireTimeUtc().HasValue ? trigger.GetNextFireTimeUtc().Value.ToLocalTime().ToString() : "none"));
                        }

                        if (jobListeners.Any())
                        {
                            foreach (var listener in jobListeners)
                            {
                                var config = listener();
                                Scheduler.ListenerManager.AddJobListener(
                                    config.Listener, config.Matchers);
                                log.Info(
                                    string.Format(
                                        "[Topshelf.Quartz] Added Job Listener: {0}",
                                        config.Listener.Name));
                            }
                        }

                        if (triggerListeners.Any())
                        {
                            foreach (var listener in triggerListeners)
                            {
                                var config = listener();
                                Scheduler.ListenerManager.AddTriggerListener(config.Listener, config.Matchers);
                                log.Info(
                                    string.Format(
                                        "[Topshelf.Quartz] Added Trigger Listener: {0}",
                                        config.Listener.Name));
                            }
                        }
                        if (scheduleListeners.Any())
                        {
                            foreach (var listener in scheduleListeners)
                            {
                                var schedListener = listener();
                                Scheduler.ListenerManager.AddSchedulerListener(schedListener);
                                string.Format(
                                    "[Topshelf.Quartz] Added Schedule Listener: {0}",
                                    schedListener.GetType());
                            }
                        }

                        Scheduler.Start();
                        log.Info("[Topshelf.Quartz] Scheduler started...");
                    }
                });

                configurator.BeforeStoppingService(() =>
                {
                    log.Debug("[Topshelf.Quartz] Scheduler shutting down...");
                    if (Scheduler != null)
                    {
                        if (!Scheduler.IsShutdown)
                        {
                            Scheduler.Shutdown();
                        }
                    }
                    log.Info("[Topshelf.Quartz] Scheduler shut down...");
                });
            }
        }