/**
  * If the thread is currently active, calls {@link #executionCancelled()} to notify children. If
  * not active, removes the thread from the queue so it won't become active.
  */
 public final void cancel() {
   boolean dependentThreads = false;
   synchronized (LOCK) {
     dependentThreads = checkQueuedThreadDependOnCurrentThread();
   }
   if (dependentThreads) {
     if (ConfirmDialog.OK_OPTION
         != SwingTools.showConfirmDialog(
             "cancel_pg_with_dependencies", ConfirmDialog.OK_CANCEL_OPTION)) {
       return;
     } else {
       synchronized (LOCK) {
         removeQueuedThreadsWithDependency(getID());
       }
     }
   }
   synchronized (LOCK) {
     cancelled = true;
     if (started) {
       executionCancelled();
       currentThreads.remove(this);
     } else {
       // cancel and not started? Can only be in queue
       queuedThreads.remove(this);
     }
   }
   taskCancelled(this);
 }
  /**
   * Removes all queued threads that depend on the progress threads with the provided IDs. Also all
   * thread that depend on the threads that have been removed are removed recursively.
   *
   * <p><strong>ATTENTION: Make sure this is only called from inside a synchronized block!</strong>
   *
   * @param ids the progress thread IDs the queued progress threads should be checked for
   */
  private static final void removeQueuedThreadsWithDependency(String... ids) {
    Iterator<ProgressThread> iterator = queuedThreads.iterator();

    // iterator over queued threads and remove the remove the ones that depend on one of the
    // provided IDs
    Set<String> cancelledThreads = new HashSet<>();
    while (iterator.hasNext()) {
      ProgressThread pg = iterator.next();
      if (!Collections.disjoint(Arrays.asList(ids), pg.getDependencies())) {
        iterator.remove();
        cancelledThreads.add(pg.getID());
      }
    }

    // also remove all the ones depending on the ones that have been cancelled.
    if (!cancelledThreads.isEmpty()) {
      removeQueuedThreadsWithDependency(
          cancelledThreads.toArray(new String[cancelledThreads.size()]));
    }
  }