class SingletonTask {

    public void reschedule(long delay, TimeUnit unit) {
        boolean needQueue = true;
        SingletonTaskWorker stw = null;

        synchronized (context) {
            if (context.taskRunning || context.taskShouldRun) {
                if (context.taskRunning) {
                    // schedule to restart at the right time
                    if (delay > 0) {
                        long now = System.nanoTime();
                        long then = now + TimeUnit.NANOSECONDS.convert(delay, unit);
                        context.waitingTask.nextschedule = then;
                        logger.debug("rescheduled task " + this + " for " + TimeUnit.SECONDS.convert(then, TimeUnit.NANOSECONDS) + "s. A bunch of these messages -may- indicate you have a blocked task.");
                    } else {
                        context.waitingTask.nextschedule = 0;
                    }
                    needQueue = false;
                } else {
                    // cancel and requeue
                    context.waitingTask.canceled = true;
                    context.waitingTask = null;
                }
            }

            context.taskShouldRun = true;

            if (needQueue) {
                stw = context.waitingTask = new SingletonTaskWorker(this);                    
            }
        }

        if (needQueue) {
            if (delay <= 0) {
                ses.execute(stw);
            } else {
                ses.schedule(stw, delay, unit);
            }
        }
    }

    public  SingletonTask(ScheduledExecutorService ses,
            Runnable task);

}