diff --git a/src/handles/watch-handle.cpp b/src/handles/watch-handle.cpp
new file mode 100644
index 0000000..15a82fa
--- /dev/null
+++ b/src/handles/watch-handle.cpp
@@ -0,0 +1,379 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "watch-handle.hpp"
+
+namespace repo {
+
+static const milliseconds PROCESS_DELETE_TIME(10000);
+static const milliseconds DEFAULT_INTEREST_LIFETIME(4000);
+
+WatchHandle::WatchHandle(Face& face, RepoStorage& storageHandle, KeyChain& keyChain,
+                         Scheduler& scheduler, ValidatorConfig& validator)
+  : BaseHandle(face, storageHandle, keyChain, scheduler)
+  , m_validator(validator)
+  , m_interestNum(0)
+  , m_maxInterestNum(0)
+  , m_interestLifetime(DEFAULT_INTEREST_LIFETIME)
+  , m_watchTimeout(0)
+  , m_startTime(steady_clock::now())
+  , m_size(0)
+{
+}
+
+void
+WatchHandle::deleteProcess(const Name& name)
+{
+  m_processes.erase(name);
+}
+
+// Interest.
+void
+WatchHandle::onInterest(const Name& prefix, const Interest& interest)
+{
+  m_validator.validate(interest,
+                       bind(&WatchHandle::onValidated, this, _1, prefix),
+                       bind(&WatchHandle::onValidationFailed, this, _1, _2));
+}
+
+void
+WatchHandle::onRegistered(const Name& prefix)
+{
+  getFace().setInterestFilter(Name().append(prefix).append("start"),
+                              bind(&WatchHandle::onInterest, this, _1, _2));
+  getFace().setInterestFilter(Name().append(prefix).append("check"),
+                              bind(&WatchHandle::onCheckInterest, this, _1, _2));
+  getFace().setInterestFilter(Name().append(prefix).append("stop"),
+                              bind(&WatchHandle::onStopInterest, this, _1, _2));
+}
+
+// onRegisterFailed for watch start.
+void
+WatchHandle::onRegisterFailed(const Name& prefix, const std::string& reason)
+{
+  std::cerr << reason << std::endl;
+  throw Error("watch prefix registration failed");
+}
+
+void
+WatchHandle::onValidated(const shared_ptr<const Interest>& interest, const Name& prefix)
+{
+  RepoCommandParameter parameter;
+  try {
+    extractParameter(*interest, prefix, parameter);
+  }
+  catch (RepoCommandParameter::Error) {
+    negativeReply(*interest, 403);
+    return;
+  }
+
+  processWatchCommand(*interest, parameter);
+}
+
+void WatchHandle::watchStop(const Name& name)
+{
+  m_processes[name].second = false;
+  m_maxInterestNum = 0;
+  m_interestNum = 0;
+  m_startTime = steady_clock::now();
+  m_watchTimeout = milliseconds(0);
+  m_interestLifetime = DEFAULT_INTEREST_LIFETIME;
+  m_size = 0;
+}
+
+void
+WatchHandle::onValidationFailed(const shared_ptr<const Interest>& interest, const string& reason)
+{
+  std::cerr << reason << std::endl;
+  negativeReply(*interest, 401);
+}
+
+void
+WatchHandle::onData(const Interest& interest, ndn::Data& data, const Name& name)
+{
+  m_validator.validate(data,
+                       bind(&WatchHandle::onDataValidated, this, interest, _1, name),
+                       bind(&WatchHandle::onDataValidationFailed, this, interest, _1, _2, name));
+}
+
+void
+WatchHandle::onDataValidated(const Interest& interest, const shared_ptr<const Data>& data,
+                             const Name& name)
+{
+  if (!m_processes[name].second) {
+    return;
+  }
+  if (getStorageHandle().insertData(*data)) {
+    m_size++;
+    if (!onRunning(name))
+      return;
+
+    Interest fetchInterest(interest.getName());
+    fetchInterest.setSelectors(interest.getSelectors());
+    fetchInterest.setInterestLifetime(m_interestLifetime);
+    fetchInterest.setChildSelector(1);
+
+    // update selectors
+    // if data name is equal to interest name, use MinSuffixComponents selecor to exclude this data
+    if (data->getName().size() == interest.getName().size()) {
+      fetchInterest.setMinSuffixComponents(2);
+    }
+    else {
+      Exclude exclude;
+      if (!interest.getExclude().empty()) {
+        exclude = interest.getExclude();
+      }
+
+      exclude.excludeBefore(data->getName()[interest.getName().size()]);
+      fetchInterest.setExclude(exclude);
+    }
+
+    ++m_interestNum;
+    getFace().expressInterest(fetchInterest,
+                              bind(&WatchHandle::onData, this, _1, _2, name),
+                              bind(&WatchHandle::onTimeout, this, _1, name));
+  }
+  else {
+    throw Error("Insert into Repo Failed");
+  }
+  m_processes[name].first.setInsertNum(m_size);
+}
+
+void
+WatchHandle::onDataValidationFailed(const Interest& interest, const shared_ptr<const Data>& data,
+                                    const std::string& reason, const Name& name)
+{
+  std::cerr << reason << std::endl;
+  if (!m_processes[name].second) {
+    return;
+  }
+  if (!onRunning(name))
+    return;
+
+  Interest fetchInterest(interest.getName());
+  fetchInterest.setSelectors(interest.getSelectors());
+  fetchInterest.setInterestLifetime(m_interestLifetime);
+  fetchInterest.setChildSelector(1);
+
+  // update selectors
+  // if data name is equal to interest name, use MinSuffixComponents selecor to exclude this data
+  if (data->getName().size() == interest.getName().size()) {
+    fetchInterest.setMinSuffixComponents(2);
+  }
+  else {
+    Exclude exclude;
+    if (!interest.getExclude().empty()) {
+      exclude = interest.getExclude();
+    }
+    // Only exclude this data since other data whose names are smaller may be validated and satisfied
+    exclude.excludeBefore(data->getName()[interest.getName().size()]);
+    fetchInterest.setExclude(exclude);
+  }
+
+  ++m_interestNum;
+  getFace().expressInterest(fetchInterest,
+                            bind(&WatchHandle::onData, this, _1, _2, name),
+                            bind(&WatchHandle::onTimeout, this, _1, name));
+}
+
+void
+WatchHandle::onTimeout(const ndn::Interest& interest, const Name& name)
+{
+  std::cerr << "Timeout" << std::endl;
+  if (!m_processes[name].second) {
+    return;
+  }
+  if (!onRunning(name))
+    return;
+  // selectors do not need to be updated
+  Interest fetchInterest(interest.getName());
+  fetchInterest.setSelectors(interest.getSelectors());
+  fetchInterest.setInterestLifetime(m_interestLifetime);
+  fetchInterest.setChildSelector(1);
+
+  ++m_interestNum;
+  getFace().expressInterest(fetchInterest,
+                            bind(&WatchHandle::onData, this, _1, _2, name),
+                            bind(&WatchHandle::onTimeout, this, _1, name));
+
+}
+
+void
+WatchHandle::listen(const Name& prefix)
+{
+  Name baseWatchPrefix(prefix);
+  baseWatchPrefix.append("watch");
+  getFace().registerPrefix(baseWatchPrefix,
+                           bind(&WatchHandle::onRegistered, this, _1),
+                           bind(&WatchHandle::onRegisterFailed, this, _1, _2));
+}
+
+void
+WatchHandle::onStopInterest(const Name& prefix, const Interest& interest)
+{
+  m_validator.validate(interest,
+                       bind(&WatchHandle::onStopValidated, this, _1, prefix),
+                       bind(&WatchHandle::onStopValidationFailed, this, _1, _2));
+}
+
+void
+WatchHandle::onStopValidated(const shared_ptr<const Interest>& interest, const Name& prefix)
+{
+  RepoCommandParameter parameter;
+  try {
+    extractParameter(*interest, prefix, parameter);
+  }
+  catch (RepoCommandParameter::Error) {
+    negativeReply(*interest, 403);
+    return;
+  }
+
+  watchStop(parameter.getName());
+  negativeReply(*interest, 101);
+}
+
+void
+WatchHandle::onStopValidationFailed(const shared_ptr<const Interest>& interest,
+                                    const std::string& reason)
+{
+  std::cerr << reason << std::endl;
+  negativeReply(*interest, 401);
+}
+
+void
+WatchHandle::onCheckInterest(const Name& prefix, const Interest& interest)
+{
+  m_validator.validate(interest,
+                       bind(&WatchHandle::onCheckValidated, this, _1, prefix),
+                       bind(&WatchHandle::onCheckValidationFailed, this, _1, _2));
+}
+
+void
+WatchHandle::onCheckValidated(const shared_ptr<const Interest>& interest, const Name& prefix)
+{
+  RepoCommandParameter parameter;
+  try {
+    extractParameter(*interest, prefix, parameter);
+  }
+  catch (RepoCommandParameter::Error) {
+    negativeReply(*interest, 403);
+    return;
+  }
+
+  if (!parameter.hasName()) {
+    negativeReply(*interest, 403);
+    return;
+  }
+  //check whether this process exists
+  Name name = parameter.getName();
+  if (m_processes.count(name) == 0) {
+    std::cerr << "no such process name: " << name << std::endl;
+    negativeReply(*interest, 404);
+    return;
+  }
+
+  RepoCommandResponse& response = m_processes[name].first;
+    if (!m_processes[name].second) {
+    response.setStatusCode(101);
+  }
+
+  reply(*interest, response);
+
+}
+
+void
+WatchHandle::onCheckValidationFailed(const shared_ptr<const Interest>& interest,
+                                     const std::string& reason)
+{
+  std::cerr << reason << std::endl;
+  negativeReply(*interest, 401);
+}
+
+void
+WatchHandle::deferredDeleteProcess(const Name& name)
+{
+  getScheduler().scheduleEvent(PROCESS_DELETE_TIME,
+                               ndn::bind(&WatchHandle::deleteProcess, this, name));
+}
+
+void
+WatchHandle::processWatchCommand(const Interest& interest,
+                                 RepoCommandParameter& parameter)
+{
+  // if there is no watchTimeout specified, m_watchTimeout will be set as 0 and this handle will run forever
+  if (parameter.hasWatchTimeout()) {
+    m_watchTimeout = parameter.getWatchTimeout();
+  }
+  else {
+    m_watchTimeout = milliseconds(0);
+  }
+
+  // if there is no maxInterestNum specified, m_maxInterestNum will be 0, which means infinity
+  if (parameter.hasMaxInterestNum()) {
+    m_maxInterestNum = parameter.getMaxInterestNum();
+  }
+  else {
+    m_maxInterestNum = 0;
+  }
+
+  if (parameter.hasInterestLifetime()) {
+    m_interestLifetime = parameter.getInterestLifetime();
+  }
+
+  reply(interest, RepoCommandResponse().setStatusCode(100));
+
+  m_processes[parameter.getName()] =
+                std::make_pair(RepoCommandResponse().setStatusCode(300), true);
+  Interest fetchInterest(parameter.getName());
+  if (parameter.hasSelectors()) {
+    fetchInterest.setSelectors(parameter.getSelectors());
+  }
+  fetchInterest.setChildSelector(1);
+  fetchInterest.setInterestLifetime(m_interestLifetime);
+  m_startTime = steady_clock::now();
+  m_interestNum++;
+  getFace().expressInterest(fetchInterest,
+                            bind(&WatchHandle::onData, this, _1, _2, parameter.getName()),
+                            bind(&WatchHandle::onTimeout, this, _1, parameter.getName()));
+}
+
+
+void
+WatchHandle::negativeReply(const Interest& interest, int statusCode)
+{
+  RepoCommandResponse response;
+  response.setStatusCode(statusCode);
+  reply(interest, response);
+}
+
+bool
+WatchHandle::onRunning(const Name& name)
+{
+  bool isTimeout = (m_watchTimeout != milliseconds::zero() &&
+                    steady_clock::now() - m_startTime > m_watchTimeout);
+  bool isMaxInterest = m_interestNum >= m_maxInterestNum && m_maxInterestNum != 0;
+  if (isTimeout || isMaxInterest) {
+    deferredDeleteProcess(name);
+    watchStop(name);
+    return false;
+  }
+  return true;
+}
+
+} //namespace repo
