@Override
  public void onDestroy() {
    if (AppConfig.DEBUG) Log.d(TAG, "Service shutting down");
    isRunning = false;
    updateReport();

    stopForeground(true);
    NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    nm.cancel(NOTIFICATION_ID);

    downloadCompletionThread.interrupt();
    syncExecutor.shutdown();
    schedExecutor.shutdown();
    cancelNotificationUpdater();
    unregisterReceiver(cancelDownloadReceiver);
  }
  @SuppressLint("NewApi")
  @Override
  public void onCreate() {
    if (AppConfig.DEBUG) Log.d(TAG, "Service started");
    isRunning = true;
    handler = new Handler();
    completedDownloads = Collections.synchronizedList(new ArrayList<DownloadStatus>());
    downloads = new ArrayList<Downloader>();
    numberOfDownloads = new AtomicInteger(0);

    IntentFilter cancelDownloadReceiverFilter = new IntentFilter();
    cancelDownloadReceiverFilter.addAction(ACTION_CANCEL_ALL_DOWNLOADS);
    cancelDownloadReceiverFilter.addAction(ACTION_CANCEL_DOWNLOAD);
    registerReceiver(cancelDownloadReceiver, cancelDownloadReceiverFilter);
    syncExecutor =
        Executors.newSingleThreadExecutor(
            new ThreadFactory() {

              @Override
              public Thread newThread(Runnable r) {
                Thread t = new Thread(r);
                t.setPriority(Thread.MIN_PRIORITY);
                return t;
              }
            });
    downloadExecutor =
        new ExecutorCompletionService<Downloader>(
            Executors.newFixedThreadPool(
                NUM_PARALLEL_DOWNLOADS,
                new ThreadFactory() {

                  @Override
                  public Thread newThread(Runnable r) {
                    Thread t = new Thread(r);
                    t.setPriority(Thread.MIN_PRIORITY);
                    return t;
                  }
                }));
    schedExecutor =
        new ScheduledThreadPoolExecutor(
            SCHED_EX_POOL_SIZE,
            new ThreadFactory() {

              @Override
              public Thread newThread(Runnable r) {
                Thread t = new Thread(r);
                t.setPriority(Thread.MIN_PRIORITY);
                return t;
              }
            },
            new RejectedExecutionHandler() {

              @Override
              public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                Log.w(TAG, "SchedEx rejected submission of new task");
              }
            });
    downloadCompletionThread.start();
    setupNotificationBuilders();
    requester = DownloadRequester.getInstance();
  }