// see DirectoryScannerMXBean
  public void scan() {
    final ScanTask task;

    synchronized (this) {
      final LinkedList<File> list;
      switch (state) {
        case RUNNING:
        case SCHEDULED:
          throw new IllegalStateException(state.toString());
        case STOPPED:
        case COMPLETED:
          // only accept to scan if state is STOPPED or COMPLETED.
          list = new LinkedList<File>();
          list.add(rootFile);
          break;
        default:
          throw new IllegalStateException(String.valueOf(state));
      }

      // Create a new ScanTask object for our root directory file.
      //
      currentTask = task = new ScanTask(list, this);

      // transient state... will be switched to RUNNING when
      // task.execute() is called. This code could in fact be modified
      // to use java.util.concurent.Future and, to push the task to
      // an executor. We would then need to wait for the task to
      // complete before returning.  However, this wouldn't buy us
      // anything - since this method should wait for the task to
      // finish anyway: so why would we do it?
      // As it stands, we simply call task.execute() in the current
      // thread - brave and fearless readers may want to attempt the
      // modification ;-)
      //
      setStateAndNotify(SCHEDULED);
    }
    task.execute();
  }