/** Clear all kept jobs. */
  public void clearAll() {
    synchronized (keptjobinfos) {
      JobTreeElement[] all =
          (JobTreeElement[]) keptjobinfos.toArray(new JobTreeElement[keptjobinfos.size()]);
      for (int i = 0; i < all.length; i++) {
        disposeAction(all[i]);
      }
      keptjobinfos.clear();
      finishedTime.clear();
    }

    // notify listeners
    Object l[] = getListeners();
    for (int i = 0; i < l.length; i++) {
      KeptJobsListener jv = (KeptJobsListener) l[i];
      jv.removed(null);
    }
  }
  boolean remove(JobTreeElement jte) {
    boolean fire = false;
    boolean removed = false;

    synchronized (keptjobinfos) {
      if (keptjobinfos.remove(jte)) {
        removed = true;
        finishedTime.remove(jte);
        disposeAction(jte);

        // delete all elements that have jte as their direct or indirect
        // parent
        JobTreeElement jtes[] =
            (JobTreeElement[]) keptjobinfos.toArray(new JobTreeElement[keptjobinfos.size()]);
        for (int i = 0; i < jtes.length; i++) {
          JobTreeElement parent = (JobTreeElement) jtes[i].getParent();
          if (parent != null) {
            if (parent == jte || parent.getParent() == jte) {
              if (keptjobinfos.remove(jtes[i])) {
                disposeAction(jtes[i]);
              }
              finishedTime.remove(jtes[i]);
            }
          }
        }
        fire = true;
      }
    }

    if (fire) {
      // notify listeners
      Object l[] = getListeners();
      for (int i = 0; i < l.length; i++) {
        KeptJobsListener jv = (KeptJobsListener) l[i];
        jv.removed(jte);
      }
    }
    return removed;
  }