protected void updateJobState(
      Scheduler scheduler, JobKey jobKey, TriggerState triggerState, boolean suppressError)
      throws Exception {

    JobDetail jobDetail = scheduler.getJobDetail(jobKey);

    if (jobDetail == null) {
      return;
    }

    JobDataMap jobDataMap = jobDetail.getJobDataMap();

    JobState jobState = getJobState(jobDataMap);

    if (triggerState != null) {
      jobState.setTriggerState(triggerState);
    }

    if (suppressError) {
      jobState.clearExceptions();
    }

    jobDataMap.put(SchedulerEngine.JOB_STATE, JobStateSerializeUtil.serialize(jobState));

    scheduler.addJob(jobDetail, true);
  }
  protected void unschedule(Scheduler scheduler, JobKey jobKey) throws Exception {

    JobDetail jobDetail = scheduler.getJobDetail(jobKey);

    TriggerKey triggerKey = new TriggerKey(jobKey.getName(), jobKey.getGroup());

    if (jobDetail == null) {
      return;
    }

    unregisterMessageListener(scheduler, jobKey);

    JobDataMap jobDataMap = jobDetail.getJobDataMap();

    JobState jobState = getJobState(jobDataMap);

    Trigger trigger = scheduler.getTrigger(triggerKey);

    if (trigger == null) {
      return;
    }

    jobState.setTriggerDate(SchedulerEngine.END_TIME, new Date());
    jobState.setTriggerDate(SchedulerEngine.FINAL_FIRE_TIME, trigger.getPreviousFireTime());
    jobState.setTriggerDate(SchedulerEngine.NEXT_FIRE_TIME, null);
    jobState.setTriggerDate(SchedulerEngine.PREVIOUS_FIRE_TIME, trigger.getPreviousFireTime());
    jobState.setTriggerDate(SchedulerEngine.START_TIME, trigger.getStartTime());

    jobState.setTriggerState(TriggerState.UNSCHEDULED);

    jobState.clearExceptions();

    jobDataMap.put(SchedulerEngine.JOB_STATE, JobStateSerializeUtil.serialize(jobState));

    scheduler.unscheduleJob(triggerKey);

    scheduler.addJob(jobDetail, true);
  }