public function getJobList() {
    $job_list = [];

    foreach ($this->collectorClassNames as $collector_class_name) {
      // Get the list of jobs from each collector.
      $collector_helper = $this->getHelper($collector_class_name);
      $collector_job_list = $collector_helper->getJobList();

      if (is_null($collector_job_list)) {
        // Collector doesn't support jobs: create just a single job for it.
        $job_list[] = [
          'collector' => $collector_class_name,
          'process_label' => $collector_helper->getReportingKey(),
          // A singleton job is by definition the last one.
          // Simpler to do this and have the analysis waste time trying to load
          // a temporary file than add special handling for singleton jobs.
          'last' => TRUE,
        ];
      }
      else {
        array_walk($collector_job_list, function(&$item) use ($collector_class_name) {
          $item['collector'] = $collector_class_name;
        });

        // Mark the final one so we know when to write the data to the
        // permanent location.
        $keys = array_keys($collector_job_list);
        $last_index = end($keys);
        $collector_job_list[$last_index]['last'] = TRUE;

        $job_list = array_merge($job_list, $collector_job_list);
      }
    }

    return $job_list;
  }