/**
  * Schedule a task for execution at varying intervals. After execution, the task will get
  * rescheduled after {@link org.jgroups.util.HashedTimingWheel.Task#nextInterval()} milliseconds.
  * The task is neve done until nextInterval() return a value <= 0 or the task is cancelled.
  *
  * @param task the task to execute Task is rescheduled relative to the last time it
  *     <i>actually</i> started execution
  *     <p><tt>false</tt>:<br>
  *     Task is scheduled relative to its <i>last</i> execution schedule. This has the effect that
  *     the time between two consecutive executions of the task remains the same.
  *     <p>Note that relative is always true; we always schedule the next execution relative to the
  *     last *actual*
  */
 public Future<?> scheduleWithDynamicInterval(Task task) {
   if (task == null) throw new NullPointerException();
   if (isShutdown() || !running) return null;
   RecurringTask task_wrapper = new DynamicIntervalTask(task);
   task_wrapper.doSchedule(); // calls schedule() in ScheduledThreadPoolExecutor
   return task_wrapper;
 }
 public Future<?> scheduleAtFixedRate(
     Runnable task, long initial_delay, long delay, TimeUnit unit) {
   if (task == null) throw new NullPointerException();
   if (isShutdown() || !running) return null;
   RecurringTask wrapper = new FixedRateTask(task, delay);
   wrapper.doSchedule(initial_delay);
   return wrapper;
 }