private Scheduler instantiate() throws SchedulerException {

    // Setup SimpleThreadPool
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //
    SimpleThreadPool threadPool = new SimpleThreadPool();
    threadPool.setThreadCount(threadPoolSize);

    // Setup RAMJobStore
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //
    JobStore jobstore = new RAMJobStore();

    // Set up any TriggerListeners
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    boolean tpInited = false;
    boolean qsInited = false;

    // Fire everything up
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    try {

      JobRunShellFactory jrsf = new StandardJobRunShellFactory(); // Create correct run-shell factory...

      QuartzSchedulerResources quartzSchedulerResources = new QuartzSchedulerResources();
      quartzSchedulerResources.setThreadName("Quartz Scheduler Thread");
      quartzSchedulerResources.setJobRunShellFactory(jrsf);
      quartzSchedulerResources.setMakeSchedulerThreadDaemon(false);
      quartzSchedulerResources.setThreadsInheritInitializersClassLoadContext(false);
      quartzSchedulerResources.setBatchTimeWindow(0L);
      quartzSchedulerResources.setMaxBatchSize(1);
      quartzSchedulerResources.setInterruptJobsOnShutdown(true);
      quartzSchedulerResources.setInterruptJobsOnShutdownWithWait(true);
      quartzSchedulerResources.setThreadPool(threadPool);
      threadPool.setThreadNamePrefix("Quartz_Scheduler_Worker");
      threadPool.initialize();
      tpInited = true;

      quartzSchedulerResources.setJobStore(jobstore);

      quartzScheduler = new QuartzScheduler(quartzSchedulerResources);
      qsInited = true;

      // Set up any SchedulerPlugins
      // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      XMLSchedulingDataProcessorPlugin xmlSchedulingDataProcessorPlugin = new XMLSchedulingDataProcessorPlugin();
      xmlSchedulingDataProcessorPlugin.setFailOnFileNotFound(false);
      xmlSchedulingDataProcessorPlugin.setScanInterval(0);
      quartzSchedulerResources.addSchedulerPlugin(xmlSchedulingDataProcessorPlugin);

      ShutdownHookPlugin shutdownHookPlugin = new ShutdownHookPlugin();
      quartzSchedulerResources.addSchedulerPlugin(shutdownHookPlugin);

      AnnotationJobTriggerPlugin annotationJobTriggerPlugin = new AnnotationJobTriggerPlugin(packageName);
      quartzSchedulerResources.addSchedulerPlugin(annotationJobTriggerPlugin);

      // fire up job store, and runshell factory
      jobstore.initialize(quartzScheduler.getSchedulerSignaler());
      jobstore.setThreadPoolSize(threadPool.getPoolSize());

      // Initialize plugins now that we have a Scheduler instance.
      xmlSchedulingDataProcessorPlugin.initialize("XMLSchedulingDataProcessorPlugin", quartzScheduler);
      shutdownHookPlugin.initialize("ShutdownHookPlugin", quartzScheduler);
      annotationJobTriggerPlugin.initialize("AnnotationJobTriggerPlugin", quartzScheduler);

      jrsf.initialize(quartzScheduler);

      quartzScheduler.initialize(); // starts the thread

      return quartzScheduler;

    } catch (SchedulerException e) {
      if (qsInited) {
        quartzScheduler.shutdown(false);
      } else if (tpInited) {
        threadPool.shutdown(false);
      }
      throw e;
    } catch (RuntimeException re) {
      if (qsInited) {
        quartzScheduler.shutdown(false);
      } else if (tpInited) {
        threadPool.shutdown(false);
      }
      throw re;
    } catch (Error re) {
      if (qsInited) {
        quartzScheduler.shutdown(false);
      } else if (tpInited) {
        threadPool.shutdown(false);
      }
      throw re;
    }
  }