private void SyncJobs(DateTime runTime)
        {
            try
            {
                //Convert time to UTC
                runTime = runTime.ToUniversalTime();
                var systemJobs = _schedulerDbTools.GetSystemJobs();

                var jobGroups = new List <string>();
                //Get all quartz job group names
                jobGroups.AddRange(_quartzScheduler.GetJobGroupNames());
                //Get all database jobs that are not in quartz
                jobGroups.AddRange(systemJobs.Select(s => s.JobClassType).Where(s => !jobGroups.Contains(s)));

                //Here all jobs will be saved based on their state
                var jobsToAdd    = new List <JobKey>();
                var jobsToUpdate = new List <JobKey>();
                var jobsToRemove = new List <JobKey>();

                foreach (var quartzJobName in jobGroups)
                {
                    //Get all system and quartz jobs by current job group name
                    var groupSysJobs = systemJobs.Where(s => s.JobClassType.Equals(quartzJobName)).ToArray();
                    var groupJobKeys = _quartzScheduler.GetJobKeys(GroupMatcher <JobKey> .GroupEquals(quartzJobName));

                    //If there are no jobs for such group name continue
                    if (!groupSysJobs.Any() && !groupJobKeys.Any())
                    {
                        continue;
                    }
                    //If there are no system jobs and some quartz jobs exist for given group name they have to be stopped
                    if (!groupSysJobs.Any() && groupJobKeys.Any())
                    {
                        jobsToRemove.AddRange(groupJobKeys);
                        continue;
                    }
                    //Get available system jobs
                    var availableSysJobs = groupSysJobs.Where(j => j.IsEnabled &&
                                                              ((j.AllowMultipleInstances) || (!j.AllowMultipleInstances && _isPrimary))).ToArray();

                    //If there are some system jobs avaialble and no such quartz jobs, they all have to be added
                    if (availableSysJobs.Any() && !groupJobKeys.Any())
                    {
                        jobsToAdd.AddRange(availableSysJobs.Select(j => new JobKey(j.SystemJobId, j.JobClassType)));
                        continue;
                    }

                    //Keys that are in quartz jobs but not in available system jobs
                    var remove = groupJobKeys.Where(gk => availableSysJobs.All(j => j.SystemJobId != gk.Name));

                    //Keys that are in system jobs but not in quartz
                    var add = availableSysJobs.Where(j => groupJobKeys.All(gk => j.SystemJobId != gk.Name))
                              .Select(j => new JobKey(j.SystemJobId, j.JobClassType));

                    jobsToRemove.AddRange(remove);
                    jobsToAdd.AddRange(add);

                    //Remaining keys that are in both system and quartz so need to be checked for changes
                    foreach (var updateKey in groupJobKeys.Except(remove))
                    {
                        var job = systemJobs.First(s => s.SystemJobId == updateKey.Name);

                        if (job.IsEnabled &&
                            ((job.AllowMultipleInstances) ||
                             (!job.AllowMultipleInstances && _isPrimary)))
                        {
                            //check if job was modified during current interval
                            if (job.LastModified.HasValue &&
                                job.LastModified.Value.AddMilliseconds(Interval) >= runTime ||
                                job.JobParameters.Any(x => x.LastModified.HasValue &&
                                                      x.LastModified.Value.AddMilliseconds(Interval) >= runTime))
                            {
                                jobsToUpdate.Add(updateKey);
                            }
                        }
                        else
                        {
                            jobsToRemove.Add(updateKey);
                        }
                    }
                }

                //Remove jobs
                foreach (var jobKey in jobsToRemove.Where(jobKey => _quartzScheduler.CheckExists(jobKey)))
                {
                    _quartzScheduler.DeleteJob(jobKey);
                }

                //Add and Update Jobs
                foreach (var jobKey in jobsToAdd.Union(jobsToUpdate))
                {
                    AddJob(_quartzScheduler, systemJobs.First(x => x.SystemJobId == jobKey.Name), _getJob);
                }

                if (!_quartzScheduler.IsStarted)
                {
                    _quartzScheduler.Start();
                }
            }
            catch (Exception ex)
            {
                _traceSource.Error(ex.ToString());

                //If database does not exist
                if (ex is ConfigurationErrorsException)
                {
                    Stop();
                }
            }
        }