@Override
  public void execute(JobExecutionContext context) throws JobExecutionException {
    BundleManagerLocal bundleManager = LookupUtil.getBundleManager();
    SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();

    Subject overlord = subjectManager.getOverlord();

    PageList<BundleDeployment> deployments =
        bundleManager.findBundleDeploymentsByCriteria(overlord, getCriteriaFromContext(context));

    if (deployments.size() > 0) {
      BundleDeployment bundleDeployment = deployments.get(0);
      SchedulerLocal scheduler = LookupUtil.getSchedulerBean();
      JobDetail jobDetail = context.getJobDetail();

      BundleDeploymentStatus bundleDeploymentStatus =
          bundleManager.determineBundleDeploymentStatus(bundleDeployment.getId());
      if (bundleDeploymentStatus.isTerminal()) {
        // delete this job, we've assigned a final status
        try {
          context.setResult(bundleDeploymentStatus); // Return status to possible listeners
          scheduler.deleteJob(jobDetail.getName(), jobDetail.getGroup());
        } catch (SchedulerException e) {
          throw new JobExecutionException(
              "Could not delete the bundle deployment completion check job for "
                  + bundleDeployment
                  + ".",
              e);
        }
      } else {
        // try again in 10s
        try {
          Trigger trigger = QuartzUtil.getFireOnceOffsetTrigger(jobDetail, 10000L);
          // just need a trigger name unique for this job
          trigger.setName(String.valueOf(System.currentTimeMillis()));
          scheduler.scheduleJob(trigger);
        } catch (SchedulerException e) {
          throw new JobExecutionException(
              "Could not schedule the bundle deployment completion check job for "
                  + bundleDeployment
                  + ".",
              e);
        }
      }
    }
  }
  /**
   * Construct the job details using the given parameter map and schedule the job to be executed by
   * the given job class using the given trigger.
   *
   * @param jobName The name of the job to be executed.
   * @param manager The BeanManager implementation.
   * @param trigger The trigger representing the schedule of the job.
   * @param jobKlass The class which will execute the job on schedule.
   * @param jobParams The parameters to be passed to the job executor.
   * @throws SchedulerException
   */
  private void scheduleJob(final Trigger schedTrigger, final TriggerDetail triggerDetails)
      throws CronProviderInitialisationException {

    // common Second payload sample and start time
    final GregorianCalendar gc = new GregorianCalendar();
    gc.add(GregorianCalendar.SECOND, 1);
    final Date startTime = new Date(gc.getTimeInMillis());
    schedTrigger.setStartTime(startTime);

    final String jobName = triggerDetails.toString() + "-trigger";
    schedTrigger.setName(jobName);

    final JobDetail job = new JobDetail(jobName, schedTrigger.getGroup(), TriggerJob.class);
    job.setJobDataMap(new JobDataMap());
    job.getJobDataMap()
        .put(TRIGGER_SUPPLIES, new TriggerSupplies(beanManager, triggerDetails.getQualifier()));
    try {
      getScheduler().scheduleJob(job, schedTrigger);
    } catch (SchedulerException e) {
      throw new CronProviderInitialisationException(
          "Error scheduling job " + jobName + " with Quartz provider", e);
    }
    log.info("Scheduler for " + jobName + " initialised");
  }
  public static org.quartz.Trigger convertTriggerToNativeObject(Trigger spagobiTrigger) {
    org.quartz.Trigger quartzTrigger;

    logger.debug("IN");

    quartzTrigger = null;
    try {
      Assert.assertNotNull(spagobiTrigger, "Input parameter [spagobiTrigger] csannot be null");

      if (spagobiTrigger.isRunImmediately()) {

        quartzTrigger = TriggerUtils.makeImmediateTrigger(spagobiTrigger.getName(), 0, 10000);
        quartzTrigger.setJobName(spagobiTrigger.getJob().getName());
        quartzTrigger.setJobGroup(spagobiTrigger.getJob().getGroupName());
        JobDataMap jobDataMap =
            convertParametersToNativeObject(spagobiTrigger.getJob().getParameters());
        quartzTrigger.setJobDataMap(jobDataMap);

      } else {

        if (spagobiTrigger.isSimpleTrigger()) {
          quartzTrigger = new org.quartz.SimpleTrigger();
        } else {
          org.quartz.CronTrigger quartzCronTrigger = new org.quartz.CronTrigger();
          String quartzCronExpression =
              convertCronExpressionToNativeObject(
                  spagobiTrigger.getChronExpression(), spagobiTrigger.getStartTime());
          quartzCronTrigger.setCronExpression(quartzCronExpression);
          quartzTrigger = quartzCronTrigger;
          // dirty trick
          spagobiTrigger
              .getJob()
              .addParameter(
                  SPAGOBI_CRON_EXPRESSION, spagobiTrigger.getChronExpression().getExpression());
        }

        quartzTrigger.setName(spagobiTrigger.getName());
        quartzTrigger.setDescription(spagobiTrigger.getDescription());
        if (spagobiTrigger.getGroupName() == null) {
          quartzTrigger.setGroup(Scheduler.DEFAULT_GROUP);
        } else {
          quartzTrigger.setGroup(spagobiTrigger.getGroupName());
        }

        quartzTrigger.setStartTime(spagobiTrigger.getStartTime());
        if (spagobiTrigger.getEndTime() != null) {
          quartzTrigger.setEndTime(spagobiTrigger.getEndTime());
        }
        quartzTrigger.setJobName(spagobiTrigger.getJob().getName());
        if (spagobiTrigger.getJob().getGroupName() == null) {
          quartzTrigger.setJobGroup(Scheduler.DEFAULT_GROUP);
        } else {
          quartzTrigger.setJobGroup(spagobiTrigger.getJob().getGroupName());
        }

        quartzTrigger.setVolatility(spagobiTrigger.getJob().isVolatile());

        JobDataMap jobDataMap =
            convertParametersToNativeObject(spagobiTrigger.getJob().getParameters());
        quartzTrigger.setJobDataMap(jobDataMap);
      }
    } catch (Throwable t) {
      throw new SpagoBIRuntimeException(
          "An unexpected error occured while converting Trigger to native object", t);
    } finally {
      logger.debug("OUT");
    }

    return quartzTrigger;
  }