refactor class Task
diff --git a/include/event-scheduler.h b/include/event-scheduler.h
index 2a10b67..2055598 100644
--- a/include/event-scheduler.h
+++ b/include/event-scheduler.h
@@ -58,16 +58,13 @@
   // used to match tasks
   typedef boost::function<bool (const TaskPtr &task)> TaskMatcher;
 
-  // generator is needed only when this is a periodic task
-  // two simple generators implementation (SimpleIntervalGenerator and RandomIntervalGenerator) are provided;
-  // if user needs more complex pattern in the intervals between calls, extend class IntervalGenerator
 
   // Task is associated with Schedulers due to the requirement that libevent event is associated with an libevent event_base
-  Task(const Callback &callback, const Tag &tag, const SchedulerPtr &scheduler, const IntervalGeneratorPtr &generator = IntervalGenerator::Null);
-  ~Task();
+  Task(const Callback &callback, const Tag &tag, const SchedulerPtr &scheduler);
+  virtual ~Task();
 
   virtual void
-  run();
+  run() = 0;
 
   Tag
   tag() { return m_tag; }
@@ -78,20 +75,17 @@
   timeval *
   tv() { return m_tv; }
 
+  // Task needs to be resetted after the callback is invoked if it is to be schedule again; just for safety
+  // it's called by scheduler automatically when addTask or rescheduleTask is called;
+  // Tasks should do preparation work here (e.g. set up new delay, etc. )
+  virtual void
+  reset() = 0;
+
+  // set delay
+  // This overrides whatever delay kept in m_tv
   void
   setTv(double delay);
 
-  bool
-  isPeriodic() { return m_generator != IntervalGenerator::Null; }
-
-  // Task needs to be resetted after the callback is invoked if it is to be schedule again; just for safety
-  void
-  reset();
-
-protected:
-  void
-  selfClean();
-
 protected:
   Callback m_callback;
   Tag m_tag;
@@ -99,9 +93,49 @@
   bool m_invoked;
   event *m_event;
   timeval *m_tv;
-  IntervalGeneratorPtr m_generator;
 };
 
+class OneTimeTask : public Task
+{
+public:
+  OneTimeTask(const Callback &callback, const Tag &tag, const SchedulerPtr &scheduler, double delay);
+  virtual ~OneTimeTask(){}
+
+  // invoke callback and mark self as invoked and deregister self from scheduler
+  virtual void
+  run() _OVERRIDE;
+
+  // after reset, the task is marked as un-invoked and can be add to scheduler again, with same delay
+  // if not invoked yet, no effect
+  virtual void
+  reset() _OVERRIDE;
+
+private:
+  // this is to deregister itself from scheduler automatically after invoke
+  void
+  deregisterSelf();
+};
+
+class PeriodicTask : public Task
+{
+public:
+  // generator is needed only when this is a periodic task
+  // two simple generators implementation (SimpleIntervalGenerator and RandomIntervalGenerator) are provided;
+  // if user needs more complex pattern in the intervals between calls, extend class IntervalGenerator
+  PeriodicTask(const Callback &callback, const Tag &tag, const SchedulerPtr &scheduler, const IntervalGeneratorPtr &generator);
+  virtual ~PeriodicTask(){}
+
+  // invoke callback, reset self and ask scheduler to schedule self with the next delay interval
+  virtual void
+  run() _OVERRIDE;
+
+  // set the next delay and mark as un-invoke
+  virtual void
+  reset() _OVERRIDE;
+
+private:
+  IntervalGeneratorPtr m_generator;
+};
 
 struct SchedulerException : virtual boost::exception, virtual exception { };
 
@@ -119,13 +153,7 @@
   virtual void
   shutdown();
 
-  // add a one time task, delay is in seconds
-  // if task with the same tag exists, return false
-  virtual bool
-  addTask(const TaskPtr &task, double delay);
-
-  // add periodic task; task must have an interval generator
-  // if task with the same tag exists, return false
+  // if task with the same tag exists, the task is not added and return false
   virtual bool
   addTask(const TaskPtr &task);
 
@@ -142,8 +170,8 @@
   virtual void
   deleteTask(const Task::TaskMatcher &matcher);
 
-  // for periodic tasks, reschedule the next invoke
   // task must already have been added to the scheduler, otherwise this is no effect
+  // this is usually used by PeriodicTask
   virtual void
   rescheduleTask(const Task::Tag &tag);
 
diff --git a/src/event-scheduler.cpp b/src/event-scheduler.cpp
index 77b86d2..be67aad 100644
--- a/src/event-scheduler.cpp
+++ b/src/event-scheduler.cpp
@@ -14,14 +14,13 @@
   task = NULL;
 }
 
-Task::Task(const Callback &callback, const Tag &tag, const SchedulerPtr &scheduler, const IntervalGeneratorPtr &generator)
+Task::Task(const Callback &callback, const Tag &tag, const SchedulerPtr &scheduler)
      : m_callback(callback)
      , m_tag(tag)
      , m_scheduler(scheduler)
      , m_invoked(false)
      , m_event(NULL)
      , m_tv(NULL)
-     , m_generator(generator)
 {
   m_event = evtimer_new(scheduler->base(), eventCallback, this);
   m_tv = new timeval;
@@ -43,42 +42,6 @@
 }
 
 void
-Task::run()
-{
-  if (!m_invoked)
-  {
-    m_callback();
-    m_invoked = true;
-  }
-  if (isPeriodic())
-  {
-    reset();
-    m_scheduler->rescheduleTask(m_tag);
-  }
-  else
-  {
-    selfClean();
-  }
-}
-
-void
-Task::selfClean()
-{
-  m_scheduler->deleteTask(m_tag);
-}
-
-void
-Task::reset()
-{
-  m_invoked = false;
-  if (isPeriodic())
-  {
-    double interval = m_generator->nextInterval();
-    setTv(interval);
-  }
-}
-
-void
 Task::setTv(double delay)
 {
   double intPart, fraction;
@@ -87,6 +50,60 @@
   m_tv->tv_usec = static_cast<int>((fraction * 1000000));
 }
 
+OneTimeTask::OneTimeTask(const Callback &callback, const Tag &tag, const SchedulerPtr &scheduler, double delay)
+            : Task(callback, tag, scheduler)
+{
+  setTv(delay);
+}
+
+void
+OneTimeTask::run()
+{
+  if (!m_invoked)
+  {
+    m_callback();
+    m_invoked = true;
+    deregisterSelf();
+  }
+}
+
+void
+OneTimeTask::deregisterSelf()
+{
+  m_scheduler->deleteTask(m_tag);
+}
+
+void
+OneTimeTask::reset()
+{
+  m_invoked = false;
+}
+
+PeriodicTask::PeriodicTask(const Callback &callback, const Tag &tag, const SchedulerPtr &scheduler, const IntervalGeneratorPtr &generator)
+             : Task(callback, tag, scheduler)
+             , m_generator(generator)
+{
+}
+
+void
+PeriodicTask::run()
+{
+  if (!m_invoked)
+  {
+    m_callback();
+    m_invoked = true;
+    m_scheduler->rescheduleTask(m_tag);
+  }
+}
+
+void
+PeriodicTask::reset()
+{
+  m_invoked = false;
+  double interval = m_generator->nextInterval();
+  setTv(interval);
+}
+
 RandomIntervalGenerator::RandomIntervalGenerator(double interval, double percent, Direction direction)
                         : m_interval(interval)
                         , m_rng(time(NULL))
@@ -144,26 +161,9 @@
 }
 
 bool
-Scheduler::addTask(const TaskPtr &task, double delay)
-{
-  TaskPtr newTask = task;
-  newTask->setTv(delay);
-  if (addToMap(newTask))
-  {
-    evtimer_add(newTask->ev(), newTask->tv());
-    return true;
-  }
-  return false;
-}
-
-bool
 Scheduler::addTask(const TaskPtr &task)
 {
   TaskPtr newTask = task;
-  if (!newTask->isPeriodic())
-  {
-    return false;
-  }
 
   if (addToMap(newTask))
   {
@@ -183,10 +183,8 @@
   if (it != m_taskMap.end())
   {
     TaskPtr task = it->second;
-    if (task->isPeriodic())
-    {
-      evtimer_add(task->ev(), task->tv());
-    }
+    task->reset();
+    evtimer_add(task->ev(), task->tv());
   }
 }
 
diff --git a/src/sync-core.h b/src/sync-core.h
index 97d559d..7e787d3 100644
--- a/src/sync-core.h
+++ b/src/sync-core.h
@@ -24,6 +24,7 @@
 
 #include "sync-log.h"
 #include <ccnx-wrapper.h>
+#include <event-scheduler.h>
 
 using namespace std;
 using namespace Ccnx;
@@ -31,12 +32,13 @@
 class SyncCore
 {
 public:
-  SyncCore(const string &path, const Name &localName, CcnxWrapperPtr handle);
+  SyncCore(const string &path, const Name &localName, CcnxWrapperPtr handle, SchedulerPtr scheduler);
   ~SyncCore();
 
 protected:
   SyncLog m_log;
   CcnxWrapperPtr m_handle;
+  SchedulerPtr m_scheduler;
 };
 
 #endif // SYNC_CORE_H
diff --git a/test/test-event-scheduler.cc b/test/test-event-scheduler.cc
index 950a69e..4642d95 100644
--- a/test/test-event-scheduler.cc
+++ b/test/test-event-scheduler.cc
@@ -42,33 +42,29 @@
   string tag2 = "world";
   string tag3 = "period";
 
-  TaskPtr task1(new Task(boost::bind(func, tag1), tag1, scheduler));
-  TaskPtr task2(new Task(boost::bind(func, tag2), tag2, scheduler));
-  TaskPtr task3(new Task(boost::bind(func, tag3), tag3, scheduler, generator));
+  TaskPtr task1(new OneTimeTask(boost::bind(func, tag1), tag1, scheduler, 0.5));
+  TaskPtr task2(new OneTimeTask(boost::bind(func, tag2), tag2, scheduler, 0.5));
+  TaskPtr task3(new PeriodicTask(boost::bind(func, tag3), tag3, scheduler, generator));
 
   scheduler->start();
-  scheduler->addTask(task1, 0.5);
-  scheduler->addTask(task2, 0.5);
+  scheduler->addTask(task1);
+  scheduler->addTask(task2);
   scheduler->addTask(task3);
   BOOST_CHECK_EQUAL(scheduler->size(), 3);
   usleep(600000);
   BOOST_CHECK_EQUAL(scheduler->size(), 1);
-  task1->reset();
-  scheduler->addTask(task1, 0.5);
+  scheduler->addTask(task1);
   BOOST_CHECK_EQUAL(scheduler->size(), 2);
   usleep(600000);
-  task1->reset();
-  scheduler->addTask(task1, 0.5);
+  scheduler->addTask(task1);
   BOOST_CHECK_EQUAL(scheduler->size(), 2);
   usleep(400000);
   scheduler->deleteTask(task1->tag());
   BOOST_CHECK_EQUAL(scheduler->size(), 1);
   usleep(200000);
 
-  task1->reset();
-  task2->reset();
-  scheduler->addTask(task1, 0.5);
-  scheduler->addTask(task2, 0.5);
+  scheduler->addTask(task1);
+  scheduler->addTask(task2);
   BOOST_CHECK_EQUAL(scheduler->size(), 3);
   usleep(100000);
   scheduler->deleteTask(bind(matcher, _1));