face: minor refactoring and Doxygen improvements

refs #3248

Change-Id: I8c44b4342b9d7b9e896dbc96fbf671d3e29bcb3c
diff --git a/src/detail/container-with-on-empty-signal.hpp b/src/detail/container-with-on-empty-signal.hpp
index 0c3e7c3..ef5f004 100644
--- a/src/detail/container-with-on-empty-signal.hpp
+++ b/src/detail/container-with-on-empty-signal.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2016 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -28,7 +28,7 @@
 namespace ndn {
 
 /**
- * @brief A simple container that will fire up onEmpty signal when there are no entries left
+ * @brief A container that emits onEmpty signal when it becomes empty
  */
 template<class T>
 class ContainerWithOnEmptySignal
diff --git a/src/detail/face-impl.hpp b/src/detail/face-impl.hpp
index 476e85e..fa5f989 100644
--- a/src/detail/face-impl.hpp
+++ b/src/detail/face-impl.hpp
@@ -45,11 +45,16 @@
 
 namespace ndn {
 
+using ndn::nfd::ControlParameters;
+
+/**
+ * @brief implementation detail of Face
+ */
 class Face::Impl : noncopyable
 {
 public:
   typedef ContainerWithOnEmptySignal<shared_ptr<PendingInterest>> PendingInterestTable;
-  typedef std::list<shared_ptr<InterestFilterRecord> > InterestFilterTable;
+  typedef std::list<shared_ptr<InterestFilterRecord>> InterestFilterTable;
   typedef ContainerWithOnEmptySignal<shared_ptr<RegisteredPrefix>> RegisteredPrefixTable;
 
   explicit
@@ -59,7 +64,7 @@
     , m_processEventsTimeoutEvent(m_scheduler)
   {
     auto postOnEmptyPitOrNoRegisteredPrefixes = [this] {
-      this->m_face.getIoService().post(bind(&Impl::onEmptyPitOrNoRegisteredPrefixes, this));
+      this->m_face.getIoService().post([this] { this->onEmptyPitOrNoRegisteredPrefixes(); });
       // without this extra "post", transport can get paused (-async_read) and then resumed
       // (+async_read) from within onInterest/onData callback.  After onInterest/onData
       // finishes, there is another +async_read with the same memory block.  A few of such
@@ -70,67 +75,7 @@
     m_registeredPrefixTable.onEmpty.connect(postOnEmptyPitOrNoRegisteredPrefixes);
   }
 
-  /////////////////////////////////////////////////////////////////////////////////////////////////
-  /////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void
-  satisfyPendingInterests(Data& data)
-  {
-    for (auto entry = m_pendingInterestTable.begin(); entry != m_pendingInterestTable.end(); ) {
-      if ((*entry)->getInterest()->matchesData(data)) {
-        shared_ptr<PendingInterest> matchedEntry = *entry;
-
-        entry = m_pendingInterestTable.erase(entry);
-
-        matchedEntry->invokeDataCallback(data);
-      }
-      else
-        ++entry;
-    }
-  }
-
-  void
-  nackPendingInterests(const lp::Nack& nack)
-  {
-    for (auto entry = m_pendingInterestTable.begin(); entry != m_pendingInterestTable.end(); ) {
-      const Interest& pendingInterest = *(*entry)->getInterest();
-      if (pendingInterest == nack.getInterest()) {
-        shared_ptr<PendingInterest> matchedEntry = *entry;
-
-        entry = m_pendingInterestTable.erase(entry);
-
-        matchedEntry->invokeNackCallback(nack);
-      }
-      else {
-        ++entry;
-      }
-    }
-  }
-
-  void
-  processInterestFilters(Interest& interest)
-  {
-    for (const auto& filter : m_interestFilterTable) {
-      if (filter->doesMatch(interest.getName())) {
-        filter->invokeInterestCallback(interest);
-      }
-    }
-  }
-
-  /////////////////////////////////////////////////////////////////////////////////////////////////
-  /////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void
-  ensureConnected(bool wantResume)
-  {
-    if (!m_face.m_transport->isConnected())
-      m_face.m_transport->connect(m_face.m_ioService,
-                                  bind(&Face::onReceiveElement, &m_face, _1));
-
-    if (wantResume && !m_face.m_transport->isReceiving())
-      m_face.m_transport->resume();
-  }
-
+public: // consumer
   void
   asyncExpressInterest(shared_ptr<const Interest> interest,
                        const DataCallback& afterSatisfied,
@@ -139,12 +84,8 @@
   {
     this->ensureConnected(true);
 
-    auto entry =
-      m_pendingInterestTable.insert(make_shared<PendingInterest>(interest,
-                                                                 afterSatisfied,
-                                                                 afterNacked,
-                                                                 afterTimeout,
-                                                                 ref(m_scheduler))).first;
+    auto entry = m_pendingInterestTable.insert(make_shared<PendingInterest>(
+      interest, afterSatisfied, afterNacked, afterTimeout, ref(m_scheduler))).first;
     (*entry)->setDeleter([this, entry] { m_pendingInterestTable.erase(entry); });
 
     lp::Packet packet;
@@ -173,6 +114,65 @@
   }
 
   void
+  satisfyPendingInterests(const Data& data)
+  {
+    for (auto entry = m_pendingInterestTable.begin(); entry != m_pendingInterestTable.end(); ) {
+      if ((*entry)->getInterest()->matchesData(data)) {
+        shared_ptr<PendingInterest> matchedEntry = *entry;
+        entry = m_pendingInterestTable.erase(entry);
+        matchedEntry->invokeDataCallback(data);
+      }
+      else {
+        ++entry;
+      }
+    }
+  }
+
+  void
+  nackPendingInterests(const lp::Nack& nack)
+  {
+    for (auto entry = m_pendingInterestTable.begin(); entry != m_pendingInterestTable.end(); ) {
+      const Interest& pendingInterest = *(*entry)->getInterest();
+      if (pendingInterest == nack.getInterest()) {
+        shared_ptr<PendingInterest> matchedEntry = *entry;
+        entry = m_pendingInterestTable.erase(entry);
+        matchedEntry->invokeNackCallback(nack);
+      }
+      else {
+        ++entry;
+      }
+    }
+  }
+
+public: // producer
+  void
+  asyncSetInterestFilter(shared_ptr<InterestFilterRecord> interestFilterRecord)
+  {
+    m_interestFilterTable.push_back(interestFilterRecord);
+  }
+
+  void
+  asyncUnsetInterestFilter(const InterestFilterId* interestFilterId)
+  {
+    InterestFilterTable::iterator i = std::find_if(m_interestFilterTable.begin(),
+                                                   m_interestFilterTable.end(),
+                                                   MatchInterestFilterId(interestFilterId));
+    if (i != m_interestFilterTable.end()) {
+      m_interestFilterTable.erase(i);
+    }
+  }
+
+  void
+  processInterestFilters(Interest& interest)
+  {
+    for (const auto& filter : m_interestFilterTable) {
+      if (filter->doesMatch(interest.getName())) {
+        filter->invokeInterestCallback(interest);
+      }
+    }
+  }
+
+  void
   asyncPutData(const shared_ptr<const Data>& data)
   {
     this->ensureConnected(true);
@@ -204,67 +204,42 @@
     m_face.m_transport->send(packet.wireEncode());
   }
 
-  /////////////////////////////////////////////////////////////////////////////////////////////////
-  /////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void
-  asyncSetInterestFilter(const shared_ptr<InterestFilterRecord>& interestFilterRecord)
-  {
-    m_interestFilterTable.push_back(interestFilterRecord);
-  }
-
-  void
-  asyncUnsetInterestFilter(const InterestFilterId* interestFilterId)
-  {
-    InterestFilterTable::iterator i = std::find_if(m_interestFilterTable.begin(),
-                                                   m_interestFilterTable.end(),
-                                                   MatchInterestFilterId(interestFilterId));
-    if (i != m_interestFilterTable.end())
-      {
-        m_interestFilterTable.erase(i);
-      }
-  }
-
-  /////////////////////////////////////////////////////////////////////////////////////////////////
-  /////////////////////////////////////////////////////////////////////////////////////////////////
-
+public: // prefix registration
   const RegisteredPrefixId*
   registerPrefix(const Name& prefix,
-                 const shared_ptr<InterestFilterRecord>& filter,
+                 shared_ptr<InterestFilterRecord> filter,
                  const RegisterPrefixSuccessCallback& onSuccess,
                  const RegisterPrefixFailureCallback& onFailure,
                  uint64_t flags,
                  const nfd::CommandOptions& options)
   {
-    using namespace nfd;
-
     ControlParameters params;
     params.setName(prefix);
     params.setFlags(flags);
 
     auto prefixToRegister = make_shared<RegisteredPrefix>(prefix, filter, options);
 
-    m_face.m_nfdController->start<RibRegisterCommand>(params,
-                                                      bind(&Impl::afterPrefixRegistered, this,
-                                                           prefixToRegister, onSuccess),
-                                                      bind(onFailure, prefixToRegister->getPrefix(), _2),
-                                                      options);
+    m_face.m_nfdController->start<nfd::RibRegisterCommand>(
+      params,
+      [=] (const ControlParameters&) { this->afterPrefixRegistered(prefixToRegister, onSuccess); },
+      [=] (uint32_t code, const std::string& reason) { onFailure(prefixToRegister->getPrefix(), reason); },
+      options);
 
     return reinterpret_cast<const RegisteredPrefixId*>(prefixToRegister.get());
   }
 
   void
-  afterPrefixRegistered(const shared_ptr<RegisteredPrefix>& registeredPrefix,
+  afterPrefixRegistered(shared_ptr<RegisteredPrefix> registeredPrefix,
                         const RegisterPrefixSuccessCallback& onSuccess)
   {
     m_registeredPrefixTable.insert(registeredPrefix);
 
-    if (static_cast<bool>(registeredPrefix->getFilter())) {
+    if (registeredPrefix->getFilter() != nullptr) {
       // it was a combined operation
       m_interestFilterTable.push_back(registeredPrefix->getFilter());
     }
 
-    if (static_cast<bool>(onSuccess)) {
+    if (onSuccess != nullptr) {
       onSuccess(registeredPrefix->getPrefix());
     }
   }
@@ -274,13 +249,11 @@
                         const UnregisterPrefixSuccessCallback& onSuccess,
                         const UnregisterPrefixFailureCallback& onFailure)
   {
-    using namespace nfd;
     auto i = std::find_if(m_registeredPrefixTable.begin(),
                           m_registeredPrefixTable.end(),
                           MatchRegisteredPrefixId(registeredPrefixId));
     if (i != m_registeredPrefixTable.end()) {
       RegisteredPrefix& record = **i;
-
       const shared_ptr<InterestFilterRecord>& filter = record.getFilter();
 
       if (filter != nullptr) {
@@ -290,10 +263,11 @@
 
       ControlParameters params;
       params.setName(record.getPrefix());
-      m_face.m_nfdController->start<RibUnregisterCommand>(params,
-                                                          bind(&Impl::finalizeUnregisterPrefix, this, i, onSuccess),
-                                                          bind(onFailure, _2),
-                                                          record.getCommandOptions());
+      m_face.m_nfdController->start<nfd::RibUnregisterCommand>(
+        params,
+        [=] (const ControlParameters&) { this->finalizeUnregisterPrefix(i, onSuccess); },
+        [=] (uint32_t code, const std::string& reason) { onFailure(reason); },
+        record.getCommandOptions());
     }
     else {
       if (onFailure != nullptr) {
@@ -310,11 +284,24 @@
   {
     m_registeredPrefixTable.erase(item);
 
-    if (static_cast<bool>(onSuccess)) {
+    if (onSuccess != nullptr) {
       onSuccess();
     }
   }
 
+public: // IO routine
+  void
+  ensureConnected(bool wantResume)
+  {
+    if (!m_face.m_transport->isConnected())
+      m_face.m_transport->connect(m_face.m_ioService,
+                                  [=] (const Block& wire) { m_face.onReceiveElement(wire); });
+
+    if (wantResume && !m_face.m_transport->isReceiving()) {
+      m_face.m_transport->resume();
+    }
+  }
+
   void
   onEmptyPitOrNoRegisteredPrefixes()
   {
diff --git a/src/detail/interest-filter-record.hpp b/src/detail/interest-filter-record.hpp
index f23123e..c2916f8 100644
--- a/src/detail/interest-filter-record.hpp
+++ b/src/detail/interest-filter-record.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2016 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -22,24 +22,40 @@
 #ifndef NDN_DETAIL_INTEREST_FILTER_RECORD_HPP
 #define NDN_DETAIL_INTEREST_FILTER_RECORD_HPP
 
-#include "../common.hpp"
 #include "../name.hpp"
 #include "../interest.hpp"
 
 namespace ndn {
 
+/**
+ * @brief associates an InterestFilter with Interest callback
+ */
 class InterestFilterRecord : noncopyable
 {
 public:
-  typedef function<void (const InterestFilter&, const Interest&)> InterestCallback;
-
-  InterestFilterRecord(const InterestFilter& filter, const InterestCallback& afterInterest)
+  /**
+   * @brief Construct an Interest filter record
+   *
+   * @param filter an InterestFilter that represents what Interest should invoke the callback
+   * @param interestCallback invoked when matching Interest is received
+   */
+  InterestFilterRecord(const InterestFilter& filter,
+                       const InterestCallback& interestCallback)
     : m_filter(filter)
-    , m_afterInterest(afterInterest)
+    , m_interestCallback(interestCallback)
   {
   }
 
   /**
+   * @return the filter
+   */
+  const InterestFilter&
+  getFilter() const
+  {
+    return m_filter;
+  }
+
+  /**
    * @brief Check if Interest name matches the filter
    * @param name Interest Name
    */
@@ -51,28 +67,20 @@
 
   /**
    * @brief invokes the InterestCallback
-   * @note If the DataCallback is an empty function, this method does nothing.
    */
   void
   invokeInterestCallback(const Interest& interest) const
   {
-    m_afterInterest(m_filter, interest);
-  }
-
-  const InterestFilter&
-  getFilter() const
-  {
-    return m_filter;
+    m_interestCallback(m_filter, interest);
   }
 
 private:
   InterestFilter m_filter;
-  InterestCallback m_afterInterest;
+  InterestCallback m_interestCallback;
 };
 
-
 /**
- * @brief Opaque class representing ID of the Interest filter
+ * @brief Opaque type to identify an InterestFilterRecord
  */
 class InterestFilterId;
 
@@ -91,8 +99,9 @@
   bool
   operator()(const shared_ptr<InterestFilterRecord>& interestFilterId) const
   {
-    return (reinterpret_cast<const InterestFilterId*>(interestFilterId.get()) == m_id);
+    return reinterpret_cast<const InterestFilterId*>(interestFilterId.get()) == m_id;
   }
+
 private:
   const InterestFilterId* m_id;
 };
diff --git a/src/detail/pending-interest.hpp b/src/detail/pending-interest.hpp
index bac5836..f21fc2e 100644
--- a/src/detail/pending-interest.hpp
+++ b/src/detail/pending-interest.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2016 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -22,28 +22,30 @@
 #ifndef NDN_DETAIL_PENDING_INTEREST_HPP
 #define NDN_DETAIL_PENDING_INTEREST_HPP
 
-#include "../common.hpp"
 #include "../interest.hpp"
 #include "../data.hpp"
-#include "../util/time.hpp"
-#include "../util/scheduler.hpp"
-#include "../util/scheduler-scoped-event-id.hpp"
 #include "../lp/nack.hpp"
+#include "../util/scheduler-scoped-event-id.hpp"
 
 namespace ndn {
 
+/**
+ * @brief stores a pending Interest and associated callbacks
+ */
 class PendingInterest : noncopyable
 {
 public:
   /**
-   * @brief Create a new PitEntry and set the timeout based on the current time and
-   *        the Interest lifetime.
-   * @param interest shared_ptr for the Interest
-   * @param dataCallback function to call when matching Data packet is received
-   * @param nackCallback function to call when Nack matching Interest is received
-   * @param timeoutCallback function to call if Interest times out
-   * @param scheduler Scheduler instance to use to schedule a timeout event. The scheduled
-   *                  event will be automatically cancelled when pending Interest is destroyed.
+   * @brief Construct a pending Interest record
+   *
+   * The timeout is set based on the current time and the Interest lifetime.
+   * This class will invoke the timeout callback unless the record is deleted before timeout.
+   *
+   * @param interest the Interest
+   * @param dataCallback invoked when matching Data packet is received
+   * @param nackCallback invoked when Nack matching Interest is received
+   * @param timeoutCallback invoked when Interest times out
+   * @param scheduler Scheduler for scheduling the timeout event
    */
   PendingInterest(shared_ptr<const Interest> interest,
                   const DataCallback& dataCallback,
@@ -60,7 +62,7 @@
       scheduler.scheduleEvent(m_interest->getInterestLifetime() > time::milliseconds::zero() ?
                               m_interest->getInterestLifetime() :
                               DEFAULT_INTEREST_LIFETIME,
-                              bind(&PendingInterest::invokeTimeoutCallback, this));
+                              [=] { this->invokeTimeoutCallback(); });
   }
 
   /**
@@ -73,8 +75,7 @@
   }
 
   /**
-   * @brief invokes the DataCallback
-   * @note If the DataCallback is an empty function, this method does nothing.
+   * @brief invokes the Data callback
    */
   void
   invokeDataCallback(const Data& data)
@@ -83,8 +84,7 @@
   }
 
   /**
-   * @brief invokes the NackCallback
-   * @note If the NackCallback is an empty function, this method does nothing.
+   * @brief invokes the Nack callback
    */
   void
   invokeNackCallback(const lp::Nack& nack)
@@ -93,7 +93,7 @@
   }
 
   /**
-   * @brief Set cleanup function to be called after interest times out
+   * @brief Set cleanup function to be invoked when Interest times out
    */
   void
   setDeleter(const std::function<void()>& deleter)
@@ -103,8 +103,7 @@
 
 private:
   /**
-   * @brief invokes the TimeoutCallback
-   * @note If the TimeoutCallback is an empty function, this method does nothing.
+   * @brief invokes the timeout callback (if non-empty) and the deleter
    */
   void
   invokeTimeoutCallback()
@@ -126,11 +125,13 @@
   std::function<void()> m_deleter;
 };
 
-
+/**
+ * @brief Opaque type to identify a PendingInterest
+ */
 class PendingInterestId;
 
 /**
- * @brief Functor to match pending interests against PendingInterestId
+ * @brief Functor to match PendingInterestId
  */
 class MatchPendingInterestId
 {
@@ -144,14 +145,13 @@
   bool
   operator()(const shared_ptr<const PendingInterest>& pendingInterest) const
   {
-    return (reinterpret_cast<const PendingInterestId*>(
-              pendingInterest->getInterest().get()) == m_id);
+    return reinterpret_cast<const PendingInterestId*>(pendingInterest->getInterest().get()) == m_id;
   }
+
 private:
   const PendingInterestId* m_id;
 };
 
-
 } // namespace ndn
 
 #endif // NDN_DETAIL_PENDING_INTEREST_HPP
diff --git a/src/detail/registered-prefix.hpp b/src/detail/registered-prefix.hpp
index 983f5ea..bdc69bf 100644
--- a/src/detail/registered-prefix.hpp
+++ b/src/detail/registered-prefix.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2016 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -32,19 +32,14 @@
 
 namespace ndn {
 
+/**
+ * @brief stores information about a prefix registered in NDN forwarder
+ */
 class RegisteredPrefix : noncopyable
 {
 public:
-  /** \brief a callback on command success
-   */
-  typedef function<void(const nfd::ControlParameters&)> SuccessCallback;
-
-  /** \brief a callback on command failure
-   */
-  typedef function<void(uint32_t/*code*/,const std::string&/*reason*/)> FailureCallback;
-
   RegisteredPrefix(const Name& prefix,
-                   const shared_ptr<InterestFilterRecord>& filter,
+                   shared_ptr<InterestFilterRecord> filter,
                    const nfd::CommandOptions& options)
     : m_prefix(prefix)
     , m_filter(filter)
@@ -77,7 +72,7 @@
 };
 
 /**
- * @brief Opaque class representing ID of the registered prefix
+ * @brief Opaque type to identify a RegisteredPrefix
  */
 class RegisteredPrefixId;
 
@@ -96,13 +91,13 @@
   bool
   operator()(const shared_ptr<RegisteredPrefix>& registeredPrefix) const
   {
-    return (reinterpret_cast<const RegisteredPrefixId*>(registeredPrefix.get()) == m_id);
+    return reinterpret_cast<const RegisteredPrefixId*>(registeredPrefix.get()) == m_id;
   }
+
 private:
   const RegisteredPrefixId* m_id;
 };
 
-
 } // namespace ndn
 
 #endif // NDN_DETAIL_REGISTERED_PREFIX_HPP
diff --git a/src/face.cpp b/src/face.cpp
index 4d68927..b52a54d 100644
--- a/src/face.cpp
+++ b/src/face.cpp
@@ -31,13 +31,13 @@
 
 namespace ndn {
 
-Face::Face()
+Face::Face(shared_ptr<Transport> transport)
   : m_internalIoService(new boost::asio::io_service())
   , m_ioService(*m_internalIoService)
   , m_internalKeyChain(new KeyChain())
   , m_impl(new Impl(*this))
 {
-  construct(nullptr, *m_internalKeyChain);
+  construct(transport, *m_internalKeyChain);
 }
 
 Face::Face(boost::asio::io_service& ioService)
@@ -48,7 +48,7 @@
   construct(nullptr, *m_internalKeyChain);
 }
 
-Face::Face(const std::string& host, const std::string& port/* = "6363"*/)
+Face::Face(const std::string& host, const std::string& port)
   : m_internalIoService(new boost::asio::io_service())
   , m_ioService(*m_internalIoService)
   , m_internalKeyChain(new KeyChain())
@@ -57,19 +57,9 @@
   construct(make_shared<TcpTransport>(host, port), *m_internalKeyChain);
 }
 
-Face::Face(shared_ptr<Transport> transport)
-  : m_internalIoService(new boost::asio::io_service())
-  , m_ioService(*m_internalIoService)
-  , m_internalKeyChain(new KeyChain())
-  , m_impl(new Impl(*this))
-{
-  construct(transport, *m_internalKeyChain);
-}
-
 Face::Face(shared_ptr<Transport> transport, KeyChain& keyChain)
   : m_internalIoService(new boost::asio::io_service())
   , m_ioService(*m_internalIoService)
-  , m_internalKeyChain(nullptr)
   , m_impl(new Impl(*this))
 {
   construct(transport, keyChain);
@@ -85,7 +75,6 @@
 
 Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain)
   : m_ioService(ioService)
-  , m_internalKeyChain(nullptr)
   , m_impl(new Impl(*this))
 {
   construct(transport, keyChain);
@@ -99,8 +88,9 @@
 
   std::string transportUri;
 
-  if (getenv("NDN_CLIENT_TRANSPORT") != nullptr) {
-    transportUri = getenv("NDN_CLIENT_TRANSPORT");
+  const char* transportEnviron = getenv("NDN_CLIENT_TRANSPORT");
+  if (transportEnviron != nullptr) {
+    transportUri = transportEnviron;
   }
   else {
     ConfigFile config;
@@ -171,8 +161,9 @@
   }
 
   // If the same ioService thread, dispatch directly calls the method
-  m_ioService.dispatch([=] { m_impl->asyncExpressInterest(interestToExpress, afterSatisfied,
-                                                          afterNacked, afterTimeout); });
+  m_ioService.dispatch([=] {
+    m_impl->asyncExpressInterest(interestToExpress, afterSatisfied, afterNacked, afterTimeout);
+  });
 
   return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
 }
@@ -199,13 +190,10 @@
 }
 
 const PendingInterestId*
-Face::expressInterest(const Name& name,
-                      const Interest& tmpl,
-                      const OnData& onData, const OnTimeout& onTimeout/* = nullptr*/)
+Face::expressInterest(const Name& name, const Interest& tmpl,
+                      const OnData& onData, const OnTimeout& onTimeout)
 {
-  return expressInterest(Interest(tmpl)
-                         .setName(name)
-                         .setNonce(0),
+  return expressInterest(Interest(tmpl).setName(name).setNonce(0),
                          onData, onTimeout);
 }
 
@@ -256,46 +244,38 @@
 
 const RegisteredPrefixId*
 Face::setInterestFilter(const InterestFilter& interestFilter,
-                  const OnInterest& onInterest,
-                  const RegisterPrefixFailureCallback& onFailure,
-                  const security::SigningInfo& signingInfo,
-                  uint64_t flags)
+                        const InterestCallback& onInterest,
+                        const RegisterPrefixFailureCallback& onFailure,
+                        const security::SigningInfo& signingInfo,
+                        uint64_t flags)
 {
-    return setInterestFilter(interestFilter,
-                             onInterest,
-                             RegisterPrefixSuccessCallback(),
-                             onFailure,
-                             signingInfo,
-                             flags);
+  return setInterestFilter(interestFilter, onInterest, nullptr, onFailure, signingInfo, flags);
 }
 
 const RegisteredPrefixId*
 Face::setInterestFilter(const InterestFilter& interestFilter,
-                  const OnInterest& onInterest,
-                  const RegisterPrefixSuccessCallback& onSuccess,
-                  const RegisterPrefixFailureCallback& onFailure,
-                  const security::SigningInfo& signingInfo,
-                  uint64_t flags)
+                        const InterestCallback& onInterest,
+                        const RegisterPrefixSuccessCallback& onSuccess,
+                        const RegisterPrefixFailureCallback& onFailure,
+                        const security::SigningInfo& signingInfo,
+                        uint64_t flags)
 {
-    shared_ptr<InterestFilterRecord> filter =
-      make_shared<InterestFilterRecord>(interestFilter, onInterest);
+  auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
 
-    nfd::CommandOptions options;
-    options.setSigningInfo(signingInfo);
+  nfd::CommandOptions options;
+  options.setSigningInfo(signingInfo);
 
-    return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
-                                  onSuccess, onFailure,
-                                  flags, options);
+  return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
+                                onSuccess, onFailure, flags, options);
 }
 
 const InterestFilterId*
 Face::setInterestFilter(const InterestFilter& interestFilter,
-                        const OnInterest& onInterest)
+                        const InterestCallback& onInterest)
 {
-  shared_ptr<InterestFilterRecord> filter =
-    make_shared<InterestFilterRecord>(interestFilter, onInterest);
+  auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
 
-  getIoService().post([=] { m_impl->asyncSetInterestFilter(filter); });
+  m_ioService.post([=] { m_impl->asyncSetInterestFilter(filter); });
 
   return reinterpret_cast<const InterestFilterId*>(filter.get());
 }
@@ -314,9 +294,7 @@
   if (!certificate.getName().empty()) {
     signingInfo = signingByCertificate(certificate.getName());
   }
-  return setInterestFilter(interestFilter, onInterest,
-                           onSuccess, onFailure,
-                           signingInfo, flags);
+  return setInterestFilter(interestFilter, onInterest, onSuccess, onFailure, signingInfo, flags);
 }
 
 const RegisteredPrefixId*
@@ -330,8 +308,7 @@
   if (!certificate.getName().empty()) {
     signingInfo = signingByCertificate(certificate.getName());
   }
-  return setInterestFilter(interestFilter, onInterest,
-                             onFailure, signingInfo, flags);
+  return setInterestFilter(interestFilter, onInterest, onFailure, signingInfo, flags);
 }
 
 const RegisteredPrefixId*
@@ -343,7 +320,6 @@
                         uint64_t flags)
 {
   security::SigningInfo signingInfo = signingByIdentity(identity);
-
   return setInterestFilter(interestFilter, onInterest,
                            onSuccess, onFailure,
                            signingInfo, flags);
@@ -357,27 +333,22 @@
                         uint64_t flags)
 {
   security::SigningInfo signingInfo = signingByIdentity(identity);
-
-  return setInterestFilter(interestFilter, onInterest,
-                           onFailure, signingInfo, flags);
+  return setInterestFilter(interestFilter, onInterest, onFailure, signingInfo, flags);
 }
 
 #endif // NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
 
 const RegisteredPrefixId*
 Face::registerPrefix(const Name& prefix,
-               const RegisterPrefixSuccessCallback& onSuccess,
-               const RegisterPrefixFailureCallback& onFailure,
-               const security::SigningInfo& signingInfo,
-               uint64_t flags)
+                     const RegisterPrefixSuccessCallback& onSuccess,
+                     const RegisterPrefixFailureCallback& onFailure,
+                     const security::SigningInfo& signingInfo,
+                     uint64_t flags)
 {
+  nfd::CommandOptions options;
+  options.setSigningInfo(signingInfo);
 
-    nfd::CommandOptions options;
-    options.setSigningInfo(signingInfo);
-
-    return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
-                                  onSuccess, onFailure,
-                                  flags, options);
+  return m_impl->registerPrefix(prefix, nullptr, onSuccess, onFailure, flags, options);
 }
 
 #ifdef NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
@@ -392,8 +363,7 @@
   if (!certificate.getName().empty()) {
     signingInfo = signingByCertificate(certificate.getName());
   }
-  return registerPrefix(prefix, onSuccess,
-                        onFailure, signingInfo, flags);
+  return registerPrefix(prefix, onSuccess, onFailure, signingInfo, flags);
 }
 
 const RegisteredPrefixId*
@@ -404,17 +374,14 @@
                      uint64_t flags)
 {
   security::SigningInfo signingInfo = signingByIdentity(identity);
-  return registerPrefix(prefix, onSuccess,
-                        onFailure, signingInfo, flags);
+  return registerPrefix(prefix, onSuccess, onFailure, signingInfo, flags);
 }
 #endif // NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
 
 void
 Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
 {
-  m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId,
-                                                       UnregisterPrefixSuccessCallback(),
-                                                       UnregisterPrefixFailureCallback()); });
+  m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId, nullptr, nullptr); });
 }
 
 void
@@ -428,12 +395,11 @@
                        const UnregisterPrefixSuccessCallback& onSuccess,
                        const UnregisterPrefixFailureCallback& onFailure)
 {
-  m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId,onSuccess, onFailure); });
+  m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId, onSuccess, onFailure); });
 }
 
 void
-Face::processEvents(const time::milliseconds& timeout/* = time::milliseconds::zero()*/,
-                    bool keepThread/* = false*/)
+Face::processEvents(const time::milliseconds& timeout, bool keepThread)
 {
   if (m_ioService.stopped()) {
     m_ioService.reset(); // ensure that run()/poll() will do some work
@@ -441,19 +407,19 @@
 
   try {
     if (timeout < time::milliseconds::zero()) {
-        // do not block if timeout is negative, but process pending events
-        m_ioService.poll();
-        return;
-      }
+      // do not block if timeout is negative, but process pending events
+      m_ioService.poll();
+      return;
+    }
 
     if (timeout > time::milliseconds::zero()) {
       boost::asio::io_service& ioService = m_ioService;
       unique_ptr<boost::asio::io_service::work>& work = m_impl->m_ioServiceWork;
-      m_impl->m_processEventsTimeoutEvent =
-        m_impl->m_scheduler.scheduleEvent(timeout, [&ioService, &work] {
-            ioService.stop();
-            work.reset();
-          });
+      m_impl->m_processEventsTimeoutEvent = m_impl->m_scheduler.scheduleEvent(timeout,
+        [&ioService, &work] {
+          ioService.stop();
+          work.reset();
+        });
     }
 
     if (keepThread) {
@@ -512,7 +478,7 @@
   Block netPacket(&*begin, std::distance(begin, end));
   switch (netPacket.type()) {
     case tlv::Interest: {
-      shared_ptr<Interest> interest = make_shared<Interest>(netPacket);
+      auto interest = make_shared<Interest>(netPacket);
       if (lpPacket.has<lp::NackField>()) {
         auto nack = make_shared<lp::Nack>(std::move(*interest));
         nack->setHeader(lpPacket.get<lp::NackField>());
@@ -526,7 +492,7 @@
       break;
     }
     case tlv::Data: {
-      shared_ptr<Data> data = make_shared<Data>(netPacket);
+      auto data = make_shared<Data>(netPacket);
       extractLpLocalFields(*data, lpPacket);
       m_impl->satisfyPendingInterests(*data);
       break;
diff --git a/src/face.hpp b/src/face.hpp
index fe6af03..c83a9ae 100644
--- a/src/face.hpp
+++ b/src/face.hpp
@@ -62,59 +62,65 @@
 } // namespace nfd
 
 /**
- * @brief Callback called when expressed Interest gets satisfied with a Data packet
+ * @brief Callback invoked when expressed Interest gets satisfied with a Data packet
  */
 typedef function<void(const Interest&, const Data&)> DataCallback;
 
 /**
- * @brief Callback called when Nack is sent in response to expressed Interest
+ * @brief Callback invoked when Nack is sent in response to expressed Interest
  */
 typedef function<void(const Interest&, const lp::Nack&)> NackCallback;
 
 /**
- * @brief Callback called when expressed Interest times out
+ * @brief Callback invoked when expressed Interest times out
  */
 typedef function<void(const Interest&)> TimeoutCallback;
 
 /**
- * @brief Callback called when expressed Interest gets satisfied with Data packet
+ * @brief Callback invoked when expressed Interest gets satisfied with Data packet
  * @deprecated use DataCallback
  */
 typedef function<void(const Interest&, Data&)> OnData;
 
 /**
- * @brief Callback called when expressed Interest times out
+ * @brief Callback invoked when expressed Interest times out
  * @deprecated use TimeoutCallback
  */
 typedef function<void(const Interest&)> OnTimeout;
 
 /**
- * @brief Callback called when incoming Interest matches the specified InterestFilter
+ * @brief Callback invoked when incoming Interest matches the specified InterestFilter
+ */
+typedef function<void(const InterestFilter&, const Interest&)> InterestCallback;
+
+/**
+ * @brief Callback invoked when incoming Interest matches the specified InterestFilter
+ * @deprecated use InterestCallback
  */
 typedef function<void (const InterestFilter&, const Interest&)> OnInterest;
 
 /**
- * @brief Callback called when registerPrefix or setInterestFilter command succeeds
+ * @brief Callback invoked when registerPrefix or setInterestFilter command succeeds
  */
 typedef function<void(const Name&)> RegisterPrefixSuccessCallback;
 
 /**
- * @brief Callback called when registerPrefix or setInterestFilter command fails
+ * @brief Callback invoked when registerPrefix or setInterestFilter command fails
  */
 typedef function<void(const Name&, const std::string&)> RegisterPrefixFailureCallback;
 
 /**
- * @brief Callback called when unregisterPrefix or unsetInterestFilter command succeeds
+ * @brief Callback invoked when unregisterPrefix or unsetInterestFilter command succeeds
  */
 typedef function<void()> UnregisterPrefixSuccessCallback;
 
 /**
- * @brief Callback called when unregisterPrefix or unsetInterestFilter command fails
+ * @brief Callback invoked when unregisterPrefix or unsetInterestFilter command fails
  */
 typedef function<void(const std::string&)> UnregisterPrefixFailureCallback;
 
 /**
- * @brief Abstraction to communicate with local or remote NDN forwarder
+ * @brief Provide a communication channel with local or remote NDN forwarder
  */
 class Face : noncopyable
 {
@@ -131,101 +137,99 @@
 
 public: // constructors
   /**
-   * @brief Create a new Face using the default transport (UnixTransport)
+   * @brief Create Face using given transport (or default transport if omitted)
+   * @param transport the transport for lower layer communication. If nullptr,
+   *                  a default transport will be used. The default transport is
+   *                  determined from a FaceUri in NDN_CLIENT_TRANSPORT environ,
+   *                  a FaceUri in configuration file 'transport' key, or UnixTransport.
    *
-   * @throws ConfigFile::Error on configuration file parse failure
-   * @throws ConfigFile::Error if configuration file specifies an unsupported protocol
+   * @throw ConfigFile::Error if @p transport is nullptr, and the configuration file cannot be
+   *                          parsed or specifies an unsupported protocol
+   * @note shared_ptr is passed by value because ownership is shared with this class
    */
-  Face();
+  explicit
+  Face(shared_ptr<Transport> transport = nullptr);
 
   /**
-   * @brief Create a new Face using the default transport (UnixTransport)
+   * @brief Create Face using default transport and given io_service
    *
-   * @par Usage examples:
+   * Usage examples:
    *
-   *     Face face1;
-   *     Face face2(face1.getIoService());
+   * @code
+   * Face face1;
+   * Face face2(face1.getIoService());
    *
-   *     // Now the following ensures that events on both faces are processed
-   *     face1.processEvents();
-   *     // or face1.getIoService().run();
+   * // Now the following ensures that events on both faces are processed
+   * face1.processEvents();
+   * // or face1.getIoService().run();
+   * @endcode
    *
-   * @par or
+   * or
    *
-   *     boost::asio::io_service ioService;
-   *     Face face1(ioService);
-   *     Face face2(ioService);
-   *     ...
+   * @code
+   * boost::asio::io_service ioService;
+   * Face face1(ioService);
+   * Face face2(ioService);
    *
-   *     ioService.run();
+   * ioService.run();
+   * @endcode
    *
    * @param ioService A reference to boost::io_service object that should control all
    *                  IO operations.
-   * @throws ConfigFile::Error on configuration file parse failure
-   * @throws ConfigFile::Error if configuration file specifies an unsupported protocol
+   * @throw ConfigFile::Error the configuration file cannot be parsed or specifies an unsupported protocol
    */
   explicit
   Face(boost::asio::io_service& ioService);
 
   /**
-   * @brief Create a new Face using TcpTransport
+   * @brief Create Face using TcpTransport
    *
-   * @param host The host of the NDN forwarder
-   * @param port (optional) The port or service name of the NDN forwarder (**default**: "6363")
+   * @param host IP address or hostname of the NDN forwarder
+   * @param port port number or service name of the NDN forwarder (**default**: "6363")
    */
   Face(const std::string& host, const std::string& port = "6363");
 
   /**
-   * @brief Create a new Face using the given Transport
-   * @param transport the Transport used for communication. If nullptr, then the default
-   *                  transport will be used.
-   *
-   * @throws ConfigFile::Error if @p transport is nullptr on configuration file parse failure
-   * @throws ConfigFile::Error if @p transport is nullptr and the configuration file
-   *         specifies an unsupported protocol
-   * @note shared_ptr is passed by value because ownership is shared with this class
-   */
-  explicit
-  Face(shared_ptr<Transport> transport);
-
-  /**
-   * @brief Create a new Face using the given Transport and KeyChain instance
-   * @param transport the Transport used for communication. If nullptr, then the default
-   *                  transport will be used.
+   * @brief Create Face using given transport and KeyChain
+   * @param transport the transport for lower layer communication. If nullptr,
+   *                  a default transport will be used.
    * @param keyChain the KeyChain to sign commands
    *
-   * @throws ConfigFile::Error if @p transport is nullptr on configuration file parse failure
-   * @throws ConfigFile::Error if @p transport is nullptr and the configuration file
-   *         specifies an unsupported protocol
+   * @sa Face(shared_ptr<Transport>)
+   *
+   * @throw ConfigFile::Error if @p transport is nullptr, and the configuration file cannot be
+   *                          parsed or specifies an unsupported protocol
    * @note shared_ptr is passed by value because ownership is shared with this class
    */
   Face(shared_ptr<Transport> transport, KeyChain& keyChain);
 
   /**
-   * @brief Create a new Face using the given Transport and IO service object
-   * @param transport the Transport used for communication. If nullptr, then the default
-   *                  transport will be used.
+   * @brief Create Face using given transport and IO service
+   * @param transport the transport for lower layer communication. If nullptr,
+   *                  a default transport will be used.
    * @param ioService the io_service that controls all IO operations
    *
    * @sa Face(boost::asio::io_service&)
+   * @sa Face(shared_ptr<Transport>)
    *
-   * @throws ConfigFile::Error if @p transport is nullptr on configuration file parse failure
-   * @throws ConfigFile::Error if @p transport is nullptr and the configuration file
-   *         specifies an unsupported protocol
+   * @throw ConfigFile::Error if @p transport is nullptr, and the configuration file cannot be
+   *                          parsed or specifies an unsupported protocol
    * @note shared_ptr is passed by value because ownership is shared with this class
    */
   Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService);
 
   /**
-   * @brief Create a new Face using the given Transport and IO service object
-   * @param transport the Transport used for communication. If nullptr, then the default
-   *                  transport will be used.
+   * @brief Create a new Face using given Transport and IO service
+   * @param transport the transport for lower layer communication. If nullptr,
+   *                  a default transport will be used.
    * @param ioService the io_service that controls all IO operations
    * @param keyChain the KeyChain to sign commands
    *
-   * @throws ConfigFile::Error if @p transport is nullptr on configuration file parse failure
-   * @throws ConfigFile::Error if @p transport is nullptr and the configuration file
-   *         specifies an unsupported protocol
+   * @sa Face(boost::asio::io_service&)
+   * @sa Face(shared_ptr<Transport>, KeyChain&)
+   *
+   * @throw ConfigFile::Error if @p transport is nullptr, and the configuration file cannot be
+   *                          parsed or specifies an unsupported protocol
    * @note shared_ptr is passed by value because ownership is shared with this class
    */
   Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain);
@@ -257,7 +261,7 @@
    *
    * @return The pending interest ID which can be used with removePendingInterest
    *
-   * @throws Error when Interest size exceeds maximum limit (MAX_NDN_PACKET_SIZE)
+   * @throw Error when Interest size exceeds maximum limit (MAX_NDN_PACKET_SIZE)
    *
    * @deprecated use expressInterest(Interest, DataCallback, NackCallback, TimeoutCallback)
    */
@@ -276,7 +280,7 @@
    *
    * @return Opaque pending interest ID which can be used with removePendingInterest
    *
-   * @throws Error when Interest size exceeds maximum limit (MAX_NDN_PACKET_SIZE)
+   * @throw Error when Interest size exceeds maximum limit (MAX_NDN_PACKET_SIZE)
    *
    * @deprecated use expressInterest(Interest, DataCallback, NackCallback, TimeoutCallback)
    */
@@ -329,7 +333,7 @@
    */
   const RegisteredPrefixId*
   setInterestFilter(const InterestFilter& interestFilter,
-                    const OnInterest& onInterest,
+                    const InterestCallback& onInterest,
                     const RegisterPrefixFailureCallback& onFailure,
                     const security::SigningInfo& signingInfo = security::SigningInfo(),
                     uint64_t flags = nfd::ROUTE_FLAG_CHILD_INHERIT);
@@ -357,7 +361,7 @@
    */
   const RegisteredPrefixId*
   setInterestFilter(const InterestFilter& interestFilter,
-                    const OnInterest& onInterest,
+                    const InterestCallback& onInterest,
                     const RegisterPrefixSuccessCallback& onSuccess,
                     const RegisterPrefixFailureCallback& onFailure,
                     const security::SigningInfo& signingInfo = security::SigningInfo(),
@@ -377,7 +381,7 @@
    */
   const InterestFilterId*
   setInterestFilter(const InterestFilter& interestFilter,
-                    const OnInterest& onInterest);
+                    const InterestCallback& onInterest);
 
 #ifdef NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
   /**
@@ -634,7 +638,7 @@
    *             extra copy of the Data packet to ensure validity of published Data until
    *             asynchronous put() operation finishes.
    *
-   * @throws Error when Data size exceeds maximum limit (MAX_NDN_PACKET_SIZE)
+   * @throw Error when Data size exceeds maximum limit (MAX_NDN_PACKET_SIZE)
    */
   void
   put(const Data& data);
@@ -685,7 +689,7 @@
   shutdown();
 
   /**
-   * @brief Get reference to IO service object
+   * @return reference to IO service object
    */
   boost::asio::io_service&
   getIoService()
@@ -695,21 +699,20 @@
 
 NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
   /**
-   * @brief Get the underlying transport of the face
+   * @return underlying transport
    */
   shared_ptr<Transport>
   getTransport();
 
 private:
-
   /**
-   * @throws ConfigFile::Error on parse error and unsupported protocols
+   * @throw ConfigFile::Error on parse error and unsupported protocols
    */
   shared_ptr<Transport>
   makeDefaultTransport();
 
   /**
-   * @throws Face::Error on unsupported protocol
+   * @throw Face::Error on unsupported protocol
    * @note shared_ptr is passed by value because ownership is transferred to this function
    */
   void
@@ -729,11 +732,12 @@
 
   shared_ptr<Transport> m_transport;
 
-  /** @brief if not null, a pointer to an internal KeyChain owned by Face
-   *  @note if a KeyChain is supplied to constructor, this pointer will be null,
-   *        and the passed KeyChain is given to nfdController;
-   *        currently Face does not keep the KeyChain passed in constructor
-   *        because it's not needed, but this may change in the future
+  /**
+   * @brief if not null, a pointer to an internal KeyChain owned by Face
+   * @note if a KeyChain is supplied to constructor, this pointer will be null,
+   *       and the passed KeyChain is given to nfdController;
+   *       currently Face does not keep the KeyChain passed in constructor
+   *       because it's not needed, but this may change in the future
    */
   unique_ptr<KeyChain> m_internalKeyChain;
 
diff --git a/src/interest-filter.cpp b/src/interest-filter.cpp
index c360a41..36e08f1 100644
--- a/src/interest-filter.cpp
+++ b/src/interest-filter.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2014 Regents of the University of California.
+ * Copyright (c) 2013-2016 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -20,38 +20,46 @@
  */
 
 #include "interest-filter.hpp"
-
 #include "util/regex/regex-pattern-list-matcher.hpp"
 
 namespace ndn {
 
+InterestFilter::InterestFilter(const Name& prefix)
+  : m_prefix(prefix)
+{
+}
+
+InterestFilter::InterestFilter(const char* prefixUri)
+  : m_prefix(prefixUri)
+{
+}
+
+InterestFilter::InterestFilter(const std::string& prefixUri)
+  : m_prefix(prefixUri)
+{
+}
+
 InterestFilter::InterestFilter(const Name& prefix, const std::string& regexFilter)
   : m_prefix(prefix)
-  , m_regexFilter(ndn::make_shared<RegexPatternListMatcher>(regexFilter,
-                                                            shared_ptr<RegexBackrefManager>()))
+  , m_regexFilter(make_shared<RegexPatternListMatcher>(regexFilter, nullptr))
 {
 }
 
+InterestFilter::operator const Name&() const
+{
+  if (hasRegexFilter()) {
+    BOOST_THROW_EXCEPTION(Error("Please update InterestCallback to accept const InterestFilter&"
+                                " (non-trivial InterestFilter is being used)"));
+  }
+  return m_prefix;
+}
+
 bool
 InterestFilter::doesMatch(const Name& name) const
 {
-  if (name.size() < m_prefix.size())
-    return false;
-
-  if (hasRegexFilter()) {
-    // perform prefix match and regular expression match for the remaining components
-    bool isMatch = m_prefix.isPrefixOf(name);
-
-    if (!isMatch)
-      return false;
-
-    return m_regexFilter->match(name, m_prefix.size(), name.size() - m_prefix.size());
-  }
-  else {
-    // perform just prefix match
-
-    return m_prefix.isPrefixOf(name);
-  }
+  return m_prefix.isPrefixOf(name) &&
+         (!hasRegexFilter() ||
+          m_regexFilter->match(name, m_prefix.size(), name.size() - m_prefix.size()));
 }
 
 std::ostream&
diff --git a/src/interest-filter.hpp b/src/interest-filter.hpp
index 074f527..d6241a1 100644
--- a/src/interest-filter.hpp
+++ b/src/interest-filter.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2016 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -28,6 +28,10 @@
 
 class RegexPatternListMatcher;
 
+/**
+ * @brief declares the set of Interests a producer can serve,
+ *        which starts with a name prefix, plus an optional regular expression
+ */
 class InterestFilter
 {
 public:
@@ -42,66 +46,63 @@
   };
 
   /**
-   * @brief Create an Interest filter to match Interests by prefix
+   * @brief Construct an InterestFilter to match Interests by prefix
    *
-   * This filter will match all Interests, whose name start with the given prefix
+   * This filter matches Interests whose name start with the given prefix.
    *
-   * Any Name can be implicitly converted to the InterestFilter.
+   * @note InterestFilter is implicitly convertible from Name.
    */
   InterestFilter(const Name& prefix);
 
   /**
-   * @brief Create an Interest filter to match Interests by prefix URI
+   * @brief Construct an InterestFilter to match Interests by prefix
    *
-   * This filter will match all Interests, whose name start with the given prefix
+   * This filter matches Interests whose name start with the given prefix.
    *
-   * Any const char* can be implicitly converted to the InterestFilter.
+   * @param prefixUri name prefix, interpreted as ndn URI
+   * @note InterestFilter is implicitly convertible from null-terminated byte string.
    */
   InterestFilter(const char* prefixUri);
 
   /**
-   * @brief Create an Interest filter to match Interests by prefix URI
+   * @brief Construct an InterestFilter to match Interests by prefix
    *
-   * This filter will match all Interests, whose name start with the given prefix
+   * This filter matches Interests whose name start with the given prefix.
    *
-   * Any std::string can be implicitly converted to the InterestFilter.
+   * @param prefixUri name prefix, interpreted as ndn URI
+   * @note InterestFilter is implicitly convertible from std::string.
    */
   InterestFilter(const std::string& prefixUri);
 
   /**
-   * @brief Create an Interest filter to match Interest by prefix and regular expression
+   * @brief Construct an InterestFilter to match Interests by prefix and regular expression
    *
-   * This filter will match all Interests, whose name start with the given prefix and
-   * other components of the Interest name match the given regular expression.
+   * This filter matches Interests whose name start with the given prefix and
+   * the remaining components match the given regular expression.
    * For example, the following InterestFilter:
    *
    *    InterestFilter("/hello", "<world><>+")
    *
-   * will match all Interests, whose name has prefix `/hello`, which is followed by
-   * component `world` and has at least one more component after it.  Examples:
+   * matches Interests whose name has prefix `/hello` followed by component `world`
+   * and has at least one more component after it, such as:
    *
-   *    /hello/world/!
+   *    /hello/world/%21
    *    /hello/world/x/y/z
    *
-   * Note that regular expression will need to match all components (e.g., there is
-   * an implicit heading `^` and trailing `$` symbols in the regular expression).
+   * Note that regular expression will need to match all components (e.g., there are
+   * implicit heading `^` and trailing `$` symbols in the regular expression).
    */
   InterestFilter(const Name& prefix, const std::string& regexFilter);
 
   /**
-   * @brief Implicit conversion to Name (to provide backwards compatibility for onInterest callback)
+   * @brief Implicit conversion to Name
+   * @note This allows InterestCallback to be declared with `Name` rather than `InterestFilter`,
+   *       but this does not work if InterestFilter has regular expression.
    */
-  operator const Name&() const
-  {
-    if (static_cast<bool>(m_regexFilter)) {
-      BOOST_THROW_EXCEPTION(Error("Please update OnInterest callback to accept const "
-                                  "InterestFilter& (non-trivial Interest filter is being used)"));
-    }
-    return m_prefix;
-  }
+  operator const Name&() const;
 
   /**
-   * @brief Check if specified name matches the filter
+   * @brief Check if specified Interest name matches the filter
    */
   bool
   doesMatch(const Name& name) const;
@@ -115,7 +116,7 @@
   bool
   hasRegexFilter() const
   {
-    return static_cast<bool>(m_regexFilter);
+    return m_regexFilter != nullptr;
   }
 
   const RegexPatternListMatcher&
@@ -132,25 +133,6 @@
 std::ostream&
 operator<<(std::ostream& os, const InterestFilter& filter);
 
-
-inline
-InterestFilter::InterestFilter(const Name& prefix)
-  : m_prefix(prefix)
-{
-}
-
-inline
-InterestFilter::InterestFilter(const char* prefixUri)
-  : m_prefix(prefixUri)
-{
-}
-
-inline
-InterestFilter::InterestFilter(const std::string& prefixUri)
-  : m_prefix(prefixUri)
-{
-}
-
 } // namespace ndn
 
 #endif // NDN_INTEREST_FILTER_HPP