public void Execute()
        {
            using (new SecurityDisabler())
            {
                var jobRoot = Database.GetDatabase("master").GetItem(_rootItem);

                foreach (
                    var jobItem in
                    jobRoot.Axes.GetDescendants()
                    .Where(j => j.TemplateID == ScheduledJobTemplateId))
                {
                    try
                    {
                        var lastRun = DateUtil.ParseDateTime(jobItem["Last success"], DateTime.MinValue);

                        if (jobItem["Suspended"] == "1")
                        {
                            continue;
                        }
                        if (!string.IsNullOrWhiteSpace(jobItem["Update interval"]))
                        {
                            var interval = TimeSpan.Parse(jobItem["Update interval"]);
                            if (lastRun + interval > DateTime.Now)
                            {
                                continue;
                            }
                        }


                        var type    = jobItem["Type"];
                        var factory = ParseFactories.Default.Get <IJobLoader>(type);
                        if (factory == null)
                        {
                            throw new Exception(string.Format("No job loader factory is registered for '{0}'", type));
                        }

                        JToken spec;
                        try
                        {
                            spec = JObject.Parse(jobItem["Specification"]);
                        }
                        catch
                        {
                            spec = new JValue(jobItem["Specification"]);
                        }

                        var jobLoader = factory.Parse(null, new JsonParseState(spec, null));
                        var jobSpec   = new UpdateJobWrapper(jobLoader.Load(), lockKey: jobItem.ID.ToString());


                        var fixedJobItem = jobItem;
                        var jobInfo      = ExperienceExtractorApiContainer.JobRepository.CreateJob(jobSpec, job =>
                        {
                            using (new SecurityDisabler())
                                using (new EditContext(fixedJobItem))
                                {
                                    if (job.Status == JobStatus.Completed)
                                    {
                                        fixedJobItem["Last success"] = DateUtil.IsoNow;
                                    }
                                    fixedJobItem["Last status"] = JsonConvert.SerializeObject(job, Formatting.Indented);
                                }
                        });

                        Log.Info(
                            string.Format("Experience Extractor - Updating '{0}' (Job ID: {1})", jobItem.Name, jobInfo.Id),
                            this);

                        using (new EditContext(jobItem))
                        {
                            jobItem["Last run"] = DateUtil.IsoNow;
                        }
                        //context.Response.Write(string.Format(@"<a href='http://sc80rev150427/sitecore/experienceextractor/jobs/{0}' target='_blank'>{0}</a><br />", job.Id));
                    }
                    catch (Exception ex)
                    {
                        Log.SingleError(
                            string.Format("Experience Extractor - Invalid spec for scheduled job {0}. ({1})", jobItem.Name,
                                          ex.Message), this);
                    }
                }
            }
        }
        public void Execute()
        {
            using (new SecurityDisabler())
            {
                var jobRoot = Database.GetDatabase("master").GetItem(_rootItem);

                foreach (
                    var jobItem in
                        jobRoot.Axes.GetDescendants()
                            .Where(j => j.TemplateID == ScheduledJobTemplateId))
                {
                    
                    try
                    {
                        var lastRun = DateUtil.ParseDateTime(jobItem["Last success"], DateTime.MinValue);

                        if (jobItem["Suspended"] == "1") continue;
                        if (!string.IsNullOrWhiteSpace(jobItem["Update interval"]))
                        {
                            var interval = TimeSpan.Parse(jobItem["Update interval"]);
                            if( lastRun + interval > DateTime.Now) continue;                            
                        }


                        var type = jobItem["Type"];
                        var factory = ParseFactories.Default.Get<IJobLoader>(type);
                        if (factory == null)
                        {
                            throw new Exception(string.Format("No job loader factory is registered for '{0}'", type));
                        }

                        JToken spec;
                        try
                        {
                            spec = JObject.Parse(jobItem["Specification"]);
                        }
                        catch
                        {
                            spec = new JValue(jobItem["Specification"]);
                        }                    
                                                                    
                        var jobLoader = factory.Parse(null, new JsonParseState(spec, null));
                        var jobSpec = new UpdateJobWrapper(jobLoader.Load(), lockKey: jobItem.ID.ToString());


                        var fixedJobItem = jobItem;
                        var jobInfo = ExperienceExtractorApiContainer.JobRepository.CreateJob(jobSpec, job =>
                        {
                            using(new SecurityDisabler())
                            using (new EditContext(fixedJobItem))
                            {
                                if (job.Status == JobStatus.Completed)
                                {
                                    fixedJobItem["Last success"] = DateUtil.IsoNow;
                                }
                                fixedJobItem["Last status"] = JsonConvert.SerializeObject(job, Formatting.Indented);
                            }
                        });    
                    
                        Log.Info(
                            string.Format("Experience Extractor - Updating '{0}' (Job ID: {1})", jobItem.Name, jobInfo.Id),
                            this);

                        using (new EditContext(jobItem))
                        {
                            jobItem["Last run"] = DateUtil.IsoNow;
                        }
                        //context.Response.Write(string.Format(@"<a href='http://sc80rev150427/sitecore/experienceextractor/jobs/{0}' target='_blank'>{0}</a><br />", job.Id));
                    }
                    catch (Exception ex)
                    {
                        Log.SingleError(
                            string.Format("Experience Extractor - Invalid spec for scheduled job {0}. ({1})", jobItem.Name,
                                ex.Message), this);
                    }
                }
            }
        }