face+mgmt: simplify factories and FaceManager using C++11 features

Change-Id: I113a4c15ef82bff705f61f31b170f49727bc3794
Refs: #3258
diff --git a/core/config-file.cpp b/core/config-file.cpp
index d989455..19bf1cb 100644
--- a/core/config-file.cpp
+++ b/core/config-file.cpp
@@ -1,11 +1,12 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014  Regents of the University of California,
- *                     Arizona Board of Regents,
- *                     Colorado State University,
- *                     University Pierre & Marie Curie, Sorbonne University,
- *                     Washington University in St. Louis,
- *                     Beijing Institute of Technology
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
  *
  * This file is part of NFD (Named Data Networking Forwarding Daemon).
  * See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,7 +21,7 @@
  *
  * You should have received a copy of the GNU General Public License along with
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
 
 #include "config-file.hpp"
 #include "logger.hpp"
@@ -30,6 +31,11 @@
 
 namespace nfd {
 
+ConfigFile::ConfigFile(UnknownConfigSectionHandler unknownSectionCallback)
+  : m_unknownSectionCallback(unknownSectionCallback)
+{
+}
+
 void
 ConfigFile::throwErrorOnUnknownSection(const std::string& filename,
                                        const std::string& sectionName,
@@ -53,27 +59,20 @@
 }
 
 bool
-ConfigFile::parseYesNo(const ConfigSection::const_iterator& i,
-                        const std::string& optionName,
-                        const std::string& sectionName)
+ConfigFile::parseYesNo(const ConfigSection::value_type& option,
+                       const std::string& sectionName)
 {
-  const std::string value = i->second.get_value<std::string>();
+  auto value = option.second.get_value<std::string>();
+
   if (value == "yes") {
     return true;
   }
-
-  if (value == "no") {
+  else if (value == "no") {
     return false;
   }
 
-  BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
-                                          optionName + "\" in \"" +
-                                          sectionName + "\" section"));
-}
-
-ConfigFile::ConfigFile(UnknownConfigSectionHandler unknownSectionCallback)
-  : m_unknownSectionCallback(unknownSectionCallback)
-{
+  BOOST_THROW_EXCEPTION(Error("Invalid value \"" + value + "\" for option \"" +
+                              option.first + "\" in \"" + sectionName + "\" section"));
 }
 
 void
@@ -105,7 +104,6 @@
   parse(inputStream, isDryRun, filename);
 }
 
-
 void
 ConfigFile::parse(std::istream& input, bool isDryRun, const std::string& filename)
 {
@@ -133,35 +131,26 @@
 }
 
 void
-ConfigFile::process(bool isDryRun, const std::string& filename)
+ConfigFile::process(bool isDryRun, const std::string& filename) const
 {
   BOOST_ASSERT(!filename.empty());
-  // NFD_LOG_DEBUG("processing..." << ((isDryRun)?("dry run"):("")));
 
-  if (m_global.begin() == m_global.end())
-    {
-      std::string msg = "Error processing configuration file: ";
-      msg += filename;
-      msg += " no data";
-      BOOST_THROW_EXCEPTION(Error(msg));
+  if (m_global.begin() == m_global.end()) {
+    std::string msg = "Error processing configuration file: ";
+    msg += filename;
+    msg += " no data";
+    BOOST_THROW_EXCEPTION(Error(msg));
+  }
+
+  for (const auto& i : m_global) {
+    try {
+      ConfigSectionHandler subscriber = m_subscriptions.at(i.first);
+      subscriber(i.second, isDryRun, filename);
     }
-
-  for (ConfigSection::const_iterator i = m_global.begin(); i != m_global.end(); ++i)
-    {
-      const std::string& sectionName = i->first;
-      const ConfigSection& section = i->second;
-
-      SubscriptionTable::iterator subscriberIt = m_subscriptions.find(sectionName);
-      if (subscriberIt != m_subscriptions.end())
-        {
-          ConfigSectionHandler subscriber = subscriberIt->second;
-          subscriber(section, isDryRun, filename);
-        }
-      else
-        {
-          m_unknownSectionCallback(filename, sectionName, section, isDryRun);
-        }
+    catch (const std::out_of_range&) {
+      m_unknownSectionCallback(filename, i.first, i.second, isDryRun);
     }
+  }
 }
 
 }
diff --git a/core/config-file.hpp b/core/config-file.hpp
index ae9102e..f6e4aaf 100644
--- a/core/config-file.hpp
+++ b/core/config-file.hpp
@@ -1,11 +1,12 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014  Regents of the University of California,
- *                     Arizona Board of Regents,
- *                     Colorado State University,
- *                     University Pierre & Marie Curie, Sorbonne University,
- *                     Washington University in St. Louis,
- *                     Beijing Institute of Technology
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
  *
  * This file is part of NFD (Named Data Networking Forwarding Daemon).
  * See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,7 +21,7 @@
  *
  * You should have received a copy of the GNU General Public License along with
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
 
 #ifndef NFD_CORE_CONFIG_FILE_HPP
 #define NFD_CORE_CONFIG_FILE_HPP
@@ -47,7 +48,6 @@
 class ConfigFile : noncopyable
 {
 public:
-
   class Error : public std::runtime_error
   {
   public:
@@ -55,10 +55,10 @@
     Error(const std::string& what)
       : std::runtime_error(what)
     {
-
     }
   };
 
+  explicit
   ConfigFile(UnknownConfigSectionHandler unknownSectionCallback = throwErrorOnUnknownSection);
 
   static void
@@ -73,22 +73,32 @@
                        const ConfigSection& section,
                        bool isDryRun);
 
-  /** @brief parse a config option that can be either "yes" or "no"
+  /**
+   * \brief parse a config option that can be either "yes" or "no"
    *
-   *  @throw ConfigFile::Error value is neither "yes" nor "no"
-   *  @return true if "yes", false if "no"
+   * \return true if "yes", false if "no"
+   * \throw Error the value is neither "yes" nor "no"
    */
   static bool
-  parseYesNo(const ConfigSection::const_iterator& i,
-             const std::string& optionName,
+  parseYesNo(const ConfigSection::value_type& option,
              const std::string& sectionName);
 
+  /**
+   * \brief parse a numeric (integral or floating point) config option
+   *
+   * \return the numeric value of the parsed option
+   * \throw Error the value cannot be converted to the specified type
+   */
+  template <typename T>
+  static typename std::enable_if<std::is_arithmetic<T>::value, T>::type
+  parseNumber(const ConfigSection::value_type& option,
+              const std::string& sectionName);
+
   /// \brief setup notification of configuration file sections
   void
   addSectionHandler(const std::string& sectionName,
                     ConfigSectionHandler subscriber);
 
-
   /**
    * \param filename file to parse
    * \param isDryRun true if performing a dry run of configuration, false otherwise
@@ -127,21 +137,31 @@
   parse(const ConfigSection& config, bool isDryRun, const std::string& filename);
 
 private:
-
   void
-  process(bool isDryRun, const std::string& filename);
+  process(bool isDryRun, const std::string& filename) const;
 
 private:
   UnknownConfigSectionHandler m_unknownSectionCallback;
-
-  typedef std::map<std::string, ConfigSectionHandler> SubscriptionTable;
-
-  SubscriptionTable m_subscriptions;
-
+  std::map<std::string, ConfigSectionHandler> m_subscriptions;
   ConfigSection m_global;
 };
 
-} // namespace nfd
+template <typename T>
+inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type
+ConfigFile::parseNumber(const ConfigSection::value_type& option,
+                        const std::string& sectionName)
+{
+  auto value = option.second.get_value<std::string>();
 
+  try {
+    return boost::lexical_cast<T>(value);
+  }
+  catch (const boost::bad_lexical_cast&) {
+    BOOST_THROW_EXCEPTION(Error("Invalid value \"" + value + "\" for option \"" +
+                                option.first + "\" in \"" + sectionName + "\" section"));
+  }
+}
+
+} // namespace nfd
 
 #endif // NFD_CORE_CONFIG_FILE_HPP
diff --git a/daemon/face/ethernet-factory.cpp b/daemon/face/ethernet-factory.cpp
index 63f428c..3d88590 100644
--- a/daemon/face/ethernet-factory.cpp
+++ b/daemon/face/ethernet-factory.cpp
@@ -38,7 +38,7 @@
   if (!address.isMulticast())
     BOOST_THROW_EXCEPTION(Error(address.toString() + " is not a multicast address"));
 
-  shared_ptr<EthernetFace> face = findMulticastFace(interface.name, address);
+  auto face = findMulticastFace(interface.name, address);
   if (face)
     return face;
 
@@ -49,35 +49,35 @@
   face->onFail.connectSingleShot([this, key] (const std::string& reason) {
     m_multicastFaces.erase(key);
   });
-  m_multicastFaces.insert({key, face});
+  m_multicastFaces[key] = face;
 
   return face;
 }
 
-shared_ptr<EthernetFace>
-EthernetFactory::findMulticastFace(const std::string& interfaceName,
-                                   const ethernet::Address& address) const
-{
-  auto it = m_multicastFaces.find({interfaceName, address});
-  if (it != m_multicastFaces.end())
-    return it->second;
-  else
-    return {};
-}
-
 void
 EthernetFactory::createFace(const FaceUri& uri,
                             ndn::nfd::FacePersistency persistency,
                             const FaceCreatedCallback& onCreated,
-                            const FaceConnectFailedCallback& onConnectFailed)
+                            const FaceCreationFailedCallback& onConnectFailed)
 {
   BOOST_THROW_EXCEPTION(Error("EthernetFactory does not support 'createFace' operation"));
 }
 
-std::list<shared_ptr<const Channel>>
+std::vector<shared_ptr<const Channel>>
 EthernetFactory::getChannels() const
 {
   return {};
 }
 
+shared_ptr<EthernetFace>
+EthernetFactory::findMulticastFace(const std::string& interfaceName,
+                                   const ethernet::Address& address) const
+{
+  auto i = m_multicastFaces.find({interfaceName, address});
+  if (i != m_multicastFaces.end())
+    return i->second;
+  else
+    return nullptr;
+}
+
 } // namespace nfd
diff --git a/daemon/face/ethernet-factory.hpp b/daemon/face/ethernet-factory.hpp
index 5b1666c..c14e093 100644
--- a/daemon/face/ethernet-factory.hpp
+++ b/daemon/face/ethernet-factory.hpp
@@ -52,13 +52,6 @@
   typedef std::map<std::pair<std::string, ethernet::Address>,
                    shared_ptr<EthernetFace>> MulticastFaceMap;
 
-  // from ProtocolFactory
-  virtual void
-  createFace(const FaceUri& uri,
-             ndn::nfd::FacePersistency persistency,
-             const FaceCreatedCallback& onCreated,
-             const FaceConnectFailedCallback& onConnectFailed) DECL_OVERRIDE;
-
   /**
    * \brief Create an EthernetFace to communicate with the given multicast group
    *
@@ -84,17 +77,22 @@
   const MulticastFaceMap&
   getMulticastFaces() const;
 
-  virtual std::list<shared_ptr<const Channel>>
+public: // from ProtocolFactory
+  virtual void
+  createFace(const FaceUri& uri,
+             ndn::nfd::FacePersistency persistency,
+             const FaceCreatedCallback& onCreated,
+             const FaceCreationFailedCallback& onConnectFailed) DECL_OVERRIDE;
+
+  virtual std::vector<shared_ptr<const Channel>>
   getChannels() const DECL_OVERRIDE;
 
 private:
   /**
    * \brief Look up EthernetFace using specified interface and address
    *
-   * \returns shared pointer to the existing EthernetFace object or
-   *          empty shared pointer when such face does not exist
-   *
-   * \throws never
+   * \returns shared pointer to the existing EthernetFace object
+   *          or nullptr when such face does not exist
    */
   shared_ptr<EthernetFace>
   findMulticastFace(const std::string& interfaceName,
diff --git a/daemon/face/protocol-factory.hpp b/daemon/face/protocol-factory.hpp
index 49e1a31..e2491ef 100644
--- a/daemon/face/protocol-factory.hpp
+++ b/daemon/face/protocol-factory.hpp
@@ -1,12 +1,12 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014,  Regents of the University of California,
- *                      Arizona Board of Regents,
- *                      Colorado State University,
- *                      University Pierre & Marie Curie, Sorbonne University,
- *                      Washington University in St. Louis,
- *                      Beijing Institute of Technology,
- *                      The University of Memphis
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
  *
  * This file is part of NFD (Named Data Networking Forwarding Daemon).
  * See AUTHORS.md for complete list of NFD authors and contributors.
@@ -34,28 +34,36 @@
 class Face;
 
 /**
- * \brief Prototype for the callback called when face is created
- *        (as a response to incoming connection or after connection
- *        is established)
+ * \brief Prototype for the callback that is invoked when the face
+ *        is created (as a response to incoming connection or after
+ *        connection is established)
  */
 typedef function<void(const shared_ptr<Face>& newFace)> FaceCreatedCallback;
 
 /**
- * \brief Prototype for the callback that is called when face is failed to
- *        get created
+ * \brief Prototype for the callback that is invoked when the face
+ *        fails to be created
  */
-typedef function<void(const std::string& reason)> FaceConnectFailedCallback;
+typedef function<void(const std::string& reason)> FaceCreationFailedCallback;
 
 
+/**
+ * \brief Abstract base class for all protocol factories
+ */
 class ProtocolFactory
 {
 public:
   /**
-   * \brief Base class for all exceptions thrown by channel factories
+   * \brief Base class for all exceptions thrown by protocol factories
    */
-  struct Error : public std::runtime_error
+  class Error : public std::runtime_error
   {
-    Error(const std::string& what) : std::runtime_error(what) {}
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
   };
 
   /** \brief Try to create Face using the supplied FaceUri
@@ -70,9 +78,9 @@
   createFace(const FaceUri& uri,
              ndn::nfd::FacePersistency persistency,
              const FaceCreatedCallback& onCreated,
-             const FaceConnectFailedCallback& onConnectFailed) = 0;
+             const FaceCreationFailedCallback& onConnectFailed) = 0;
 
-  virtual std::list<shared_ptr<const Channel>>
+  virtual std::vector<shared_ptr<const Channel>>
   getChannels() const = 0;
 };
 
diff --git a/daemon/face/tcp-factory.cpp b/daemon/face/tcp-factory.cpp
index 4fb6059..a0fad93 100644
--- a/daemon/face/tcp-factory.cpp
+++ b/daemon/face/tcp-factory.cpp
@@ -26,52 +26,35 @@
 #include "tcp-factory.hpp"
 #include "core/logger.hpp"
 #include "core/network-interface.hpp"
-#include "core/global-io.hpp"
-
-NFD_LOG_INIT("TcpFactory");
 
 namespace nfd {
 
-static const boost::asio::ip::address_v4 ALL_V4_ENDPOINT(
-  boost::asio::ip::address_v4::from_string("0.0.0.0"));
+namespace ip = boost::asio::ip;
 
-static const boost::asio::ip::address_v6 ALL_V6_ENDPOINT(
-  boost::asio::ip::address_v6::from_string("::"));
-
-TcpFactory::TcpFactory(const std::string& defaultPort/* = "6363"*/)
-  : m_defaultPort(defaultPort)
-{
-}
+NFD_LOG_INIT("TcpFactory");
 
 void
 TcpFactory::prohibitEndpoint(const tcp::Endpoint& endpoint)
 {
-  using namespace boost::asio::ip;
-
-  const address& address = endpoint.address();
-
-  if (address.is_v4() && address == ALL_V4_ENDPOINT)
-    {
-      prohibitAllIpv4Endpoints(endpoint.port());
-    }
-  else if (endpoint.address().is_v6() && address == ALL_V6_ENDPOINT)
-    {
-      prohibitAllIpv6Endpoints(endpoint.port());
-    }
+  if (endpoint.address().is_v4() &&
+      endpoint.address() == ip::address_v4::any()) {
+    prohibitAllIpv4Endpoints(endpoint.port());
+  }
+  else if (endpoint.address().is_v6() &&
+           endpoint.address() == ip::address_v6::any()) {
+    prohibitAllIpv6Endpoints(endpoint.port());
+  }
 
   NFD_LOG_TRACE("prohibiting TCP " << endpoint);
-
   m_prohibitedEndpoints.insert(endpoint);
 }
 
 void
-TcpFactory::prohibitAllIpv4Endpoints(const uint16_t port)
+TcpFactory::prohibitAllIpv4Endpoints(uint16_t port)
 {
-  using namespace boost::asio::ip;
-
   for (const NetworkInterfaceInfo& nic : listNetworkInterfaces()) {
-    for (const address_v4& addr : nic.ipv4Addresses) {
-      if (addr != ALL_V4_ENDPOINT) {
+    for (const auto& addr : nic.ipv4Addresses) {
+      if (addr != ip::address_v4::any()) {
         prohibitEndpoint(tcp::Endpoint(addr, port));
       }
     }
@@ -79,13 +62,11 @@
 }
 
 void
-TcpFactory::prohibitAllIpv6Endpoints(const uint16_t port)
+TcpFactory::prohibitAllIpv6Endpoints(uint16_t port)
 {
-  using namespace boost::asio::ip;
-
   for (const NetworkInterfaceInfo& nic : listNetworkInterfaces()) {
-    for (const address_v6& addr : nic.ipv6Addresses) {
-      if (addr != ALL_V6_ENDPOINT) {
+    for (const auto& addr : nic.ipv6Addresses) {
+      if (addr != ip::address_v6::any()) {
         prohibitEndpoint(tcp::Endpoint(addr, port));
       }
     }
@@ -95,8 +76,8 @@
 shared_ptr<TcpChannel>
 TcpFactory::createChannel(const tcp::Endpoint& endpoint)
 {
-  shared_ptr<TcpChannel> channel = findChannel(endpoint);
-  if (static_cast<bool>(channel))
+  auto channel = findChannel(endpoint);
+  if (channel)
     return channel;
 
   channel = make_shared<TcpChannel>(endpoint);
@@ -110,68 +91,64 @@
 shared_ptr<TcpChannel>
 TcpFactory::createChannel(const std::string& localIp, const std::string& localPort)
 {
-  using namespace boost::asio::ip;
-  tcp::Endpoint endpoint(address::from_string(localIp), boost::lexical_cast<uint16_t>(localPort));
+  tcp::Endpoint endpoint(ip::address::from_string(localIp),
+                         boost::lexical_cast<uint16_t>(localPort));
   return createChannel(endpoint);
 }
 
-shared_ptr<TcpChannel>
-TcpFactory::findChannel(const tcp::Endpoint& localEndpoint)
-{
-  ChannelMap::iterator i = m_channels.find(localEndpoint);
-  if (i != m_channels.end())
-    return i->second;
-  else
-    return shared_ptr<TcpChannel>();
-}
-
 void
 TcpFactory::createFace(const FaceUri& uri,
                        ndn::nfd::FacePersistency persistency,
                        const FaceCreatedCallback& onCreated,
-                       const FaceConnectFailedCallback& onConnectFailed)
+                       const FaceCreationFailedCallback& onConnectFailed)
 {
+  BOOST_ASSERT(uri.isCanonical());
+
   if (persistency != ndn::nfd::FACE_PERSISTENCY_PERSISTENT) {
-    BOOST_THROW_EXCEPTION(Error("TcpFactory only supports persistent face"));
+    BOOST_THROW_EXCEPTION(Error("TcpFactory::createFace supports only FACE_PERSISTENCY_PERSISTENT"));
   }
 
-  BOOST_ASSERT(uri.isCanonical());
-  boost::asio::ip::address ipAddress = boost::asio::ip::address::from_string(uri.getHost());
-  tcp::Endpoint endpoint(ipAddress, boost::lexical_cast<uint16_t>(uri.getPort()));
+  tcp::Endpoint endpoint(ip::address::from_string(uri.getHost()),
+                         boost::lexical_cast<uint16_t>(uri.getPort()));
 
-  if (m_prohibitedEndpoints.find(endpoint) != m_prohibitedEndpoints.end())
-    {
-      onConnectFailed("Requested endpoint is prohibited "
-                      "(reserved by this NFD or disallowed by face management protocol)");
-      return;
-    }
+  if (m_prohibitedEndpoints.find(endpoint) != m_prohibitedEndpoints.end()) {
+    onConnectFailed("Requested endpoint is prohibited "
+                    "(reserved by this NFD or disallowed by face management protocol)");
+    return;
+  }
 
   // very simple logic for now
-  for (ChannelMap::iterator channel = m_channels.begin();
-       channel != m_channels.end();
-       ++channel)
-    {
-      if ((channel->first.address().is_v4() && endpoint.address().is_v4()) ||
-          (channel->first.address().is_v6() && endpoint.address().is_v6()))
-        {
-          channel->second->connect(endpoint, onCreated, onConnectFailed);
-          return;
-        }
+  for (const auto& i : m_channels) {
+    if ((i.first.address().is_v4() && endpoint.address().is_v4()) ||
+        (i.first.address().is_v6() && endpoint.address().is_v6())) {
+      i.second->connect(endpoint, onCreated, onConnectFailed);
+      return;
     }
-  onConnectFailed("No channels available to connect to "
-                  + boost::lexical_cast<std::string>(endpoint));
+  }
+
+  onConnectFailed("No channels available to connect to " + boost::lexical_cast<std::string>(endpoint));
 }
 
-std::list<shared_ptr<const Channel> >
+std::vector<shared_ptr<const Channel>>
 TcpFactory::getChannels() const
 {
-  std::list<shared_ptr<const Channel> > channels;
-  for (ChannelMap::const_iterator i = m_channels.begin(); i != m_channels.end(); ++i)
-    {
-      channels.push_back(i->second);
-    }
+  std::vector<shared_ptr<const Channel>> channels;
+  channels.reserve(m_channels.size());
+
+  for (const auto& i : m_channels)
+    channels.push_back(i.second);
 
   return channels;
 }
 
+shared_ptr<TcpChannel>
+TcpFactory::findChannel(const tcp::Endpoint& localEndpoint) const
+{
+  auto i = m_channels.find(localEndpoint);
+  if (i != m_channels.end())
+    return i->second;
+  else
+    return nullptr;
+}
+
 } // namespace nfd
diff --git a/daemon/face/tcp-factory.hpp b/daemon/face/tcp-factory.hpp
index 315bacd..5bf3694 100644
--- a/daemon/face/tcp-factory.hpp
+++ b/daemon/face/tcp-factory.hpp
@@ -29,7 +29,6 @@
 #include "protocol-factory.hpp"
 #include "tcp-channel.hpp"
 
-
 namespace nfd {
 
 class TcpFactory : public ProtocolFactory
@@ -38,14 +37,16 @@
   /**
    * \brief Exception of TcpFactory
    */
-  struct Error : public ProtocolFactory::Error
+  class Error : public ProtocolFactory::Error
   {
-    Error(const std::string& what) : ProtocolFactory::Error(what) {}
+  public:
+    explicit
+    Error(const std::string& what)
+      : ProtocolFactory::Error(what)
+    {
+    }
   };
 
-  explicit
-  TcpFactory(const std::string& defaultPort = "6363");
-
   /**
    * \brief Create TCP-based channel using tcp::Endpoint
    *
@@ -77,45 +78,40 @@
   shared_ptr<TcpChannel>
   createChannel(const std::string& localIp, const std::string& localPort);
 
-  // from ProtocolFactory
-
+public: // from ProtocolFactory
   virtual void
   createFace(const FaceUri& uri,
              ndn::nfd::FacePersistency persistency,
              const FaceCreatedCallback& onCreated,
-             const FaceConnectFailedCallback& onConnectFailed) DECL_OVERRIDE;
+             const FaceCreationFailedCallback& onConnectFailed) DECL_OVERRIDE;
 
-  virtual std::list<shared_ptr<const Channel> >
+  virtual std::vector<shared_ptr<const Channel>>
   getChannels() const DECL_OVERRIDE;
 
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-
   void
   prohibitEndpoint(const tcp::Endpoint& endpoint);
 
   void
-  prohibitAllIpv4Endpoints(const uint16_t port);
+  prohibitAllIpv4Endpoints(uint16_t port);
 
   void
-  prohibitAllIpv6Endpoints(const uint16_t port);
+  prohibitAllIpv6Endpoints(uint16_t port);
 
+private:
   /**
    * \brief Look up TcpChannel using specified local endpoint
    *
    * \returns shared pointer to the existing TcpChannel object
    *          or empty shared pointer when such channel does not exist
-   *
-   * \throws never
    */
   shared_ptr<TcpChannel>
-  findChannel(const tcp::Endpoint& localEndpoint);
+  findChannel(const tcp::Endpoint& localEndpoint) const;
+
+private:
+  std::map<tcp::Endpoint, shared_ptr<TcpChannel>> m_channels;
 
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  typedef std::map< tcp::Endpoint, shared_ptr<TcpChannel> > ChannelMap;
-  ChannelMap m_channels;
-
-  std::string m_defaultPort;
-
   std::set<tcp::Endpoint> m_prohibitedEndpoints;
 };
 
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index 74636d8..2a39e36 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -38,72 +38,51 @@
 
 namespace nfd {
 
-using namespace boost::asio;
+namespace ip = boost::asio::ip;
 
 NFD_LOG_INIT("UdpFactory");
 
-static const boost::asio::ip::address_v4 ALL_V4_ENDPOINT(
-  boost::asio::ip::address_v4::from_string("0.0.0.0"));
-
-static const boost::asio::ip::address_v6 ALL_V6_ENDPOINT(
-  boost::asio::ip::address_v6::from_string("::"));
-
-UdpFactory::UdpFactory(const std::string& defaultPort/* = "6363"*/)
-  : m_defaultPort(defaultPort)
-{
-}
-
 void
 UdpFactory::prohibitEndpoint(const udp::Endpoint& endpoint)
 {
-  using namespace boost::asio::ip;
-
-  const address& address = endpoint.address();
-
-  if (address.is_v4() && address == ALL_V4_ENDPOINT)
-    {
-      prohibitAllIpv4Endpoints(endpoint.port());
-    }
-  else if (endpoint.address().is_v6() && address == ALL_V6_ENDPOINT)
-    {
-      prohibitAllIpv6Endpoints(endpoint.port());
-    }
+  if (endpoint.address().is_v4() &&
+      endpoint.address() == ip::address_v4::any()) {
+    prohibitAllIpv4Endpoints(endpoint.port());
+  }
+  else if (endpoint.address().is_v6() &&
+           endpoint.address() == ip::address_v6::any()) {
+    prohibitAllIpv6Endpoints(endpoint.port());
+  }
 
   NFD_LOG_TRACE("prohibiting UDP " << endpoint);
-
   m_prohibitedEndpoints.insert(endpoint);
 }
 
 void
-UdpFactory::prohibitAllIpv4Endpoints(const uint16_t port)
+UdpFactory::prohibitAllIpv4Endpoints(uint16_t port)
 {
-  using namespace boost::asio::ip;
-
   for (const NetworkInterfaceInfo& nic : listNetworkInterfaces()) {
-    for (const address_v4& addr : nic.ipv4Addresses) {
-      if (addr != ALL_V4_ENDPOINT) {
+    for (const auto& addr : nic.ipv4Addresses) {
+      if (addr != ip::address_v4::any()) {
         prohibitEndpoint(udp::Endpoint(addr, port));
       }
     }
 
-    if (nic.isBroadcastCapable() && nic.broadcastAddress != ALL_V4_ENDPOINT)
-    {
-      NFD_LOG_TRACE("prohibiting broadcast address: " << nic.broadcastAddress.to_string());
+    if (nic.isBroadcastCapable() &&
+        nic.broadcastAddress != ip::address_v4::any()) {
       prohibitEndpoint(udp::Endpoint(nic.broadcastAddress, port));
     }
   }
 
-  prohibitEndpoint(udp::Endpoint(address::from_string("255.255.255.255"), port));
+  prohibitEndpoint(udp::Endpoint(ip::address_v4::broadcast(), port));
 }
 
 void
-UdpFactory::prohibitAllIpv6Endpoints(const uint16_t port)
+UdpFactory::prohibitAllIpv6Endpoints(uint16_t port)
 {
-  using namespace boost::asio::ip;
-
   for (const NetworkInterfaceInfo& nic : listNetworkInterfaces()) {
-    for (const address_v6& addr : nic.ipv6Addresses) {
-      if (addr != ALL_V6_ENDPOINT) {
+    for (const auto& addr : nic.ipv6Addresses) {
+      if (addr != ip::address_v6::any()) {
         prohibitEndpoint(udp::Endpoint(addr, port));
       }
     }
@@ -116,10 +95,15 @@
 {
   NFD_LOG_DEBUG("Creating unicast channel " << endpoint);
 
-  shared_ptr<UdpChannel> channel = findChannel(endpoint);
-  if (static_cast<bool>(channel))
+  auto channel = findChannel(endpoint);
+  if (channel)
     return channel;
 
+  if (endpoint.address().is_multicast()) {
+    BOOST_THROW_EXCEPTION(Error("createChannel is only for unicast channels. The provided endpoint "
+                                "is multicast. Use createMulticastFace to create a multicast face"));
+  }
+
   // check if the endpoint is already used by a multicast face
   auto face = findMulticastFace(endpoint);
   if (face) {
@@ -127,12 +111,6 @@
                                 "endpoint is already allocated for a UDP multicast face"));
   }
 
-  if (endpoint.address().is_multicast()) {
-    BOOST_THROW_EXCEPTION(Error("This method is only for unicast channel. The provided "
-                                "endpoint is multicast. Use createMulticastFace to "
-                                "create a multicast face"));
-  }
-
   channel = make_shared<UdpChannel>(endpoint, timeout);
   m_channels[endpoint] = channel;
   prohibitEndpoint(endpoint);
@@ -141,12 +119,11 @@
 }
 
 shared_ptr<UdpChannel>
-UdpFactory::createChannel(const std::string& localIp,
-                          const std::string& localPort,
+UdpFactory::createChannel(const std::string& localIp, const std::string& localPort,
                           const time::seconds& timeout)
 {
-  using namespace boost::asio::ip;
-  udp::Endpoint endpoint(address::from_string(localIp), boost::lexical_cast<uint16_t>(localPort));
+  udp::Endpoint endpoint(ip::address::from_string(localIp),
+                         boost::lexical_cast<uint16_t>(localPort));
   return createChannel(endpoint, timeout);
 }
 
@@ -167,8 +144,8 @@
   }
 
   // checking if the local endpoint is already in use for a unicast channel
-  shared_ptr<UdpChannel> unicast = findChannel(localEndpoint);
-  if (static_cast<bool>(unicast)) {
+  auto unicastCh = findChannel(localEndpoint);
+  if (unicastCh) {
     BOOST_THROW_EXCEPTION(Error("Cannot create the requested UDP multicast face, local "
                                 "endpoint is already allocated for a UDP unicast channel"));
   }
@@ -203,7 +180,7 @@
   sendSocket.set_option(ip::udp::socket::reuse_address(true));
   sendSocket.set_option(ip::multicast::enable_loopback(false));
   sendSocket.bind(udp::Endpoint(ip::address_v4::any(), multicastEndpoint.port()));
-  if (localEndpoint.address() != ALL_V4_ENDPOINT)
+  if (localEndpoint.address() != ip::address_v4::any())
     sendSocket.set_option(ip::multicast::outbound_interface(localEndpoint.address().to_v4()));
 
   sendSocket.set_option(ip::multicast::join_group(multicastEndpoint.address().to_v4(),
@@ -261,16 +238,16 @@
 UdpFactory::createFace(const FaceUri& uri,
                        ndn::nfd::FacePersistency persistency,
                        const FaceCreatedCallback& onCreated,
-                       const FaceConnectFailedCallback& onConnectFailed)
+                       const FaceCreationFailedCallback& onConnectFailed)
 {
-  if (persistency == ndn::nfd::FacePersistency::FACE_PERSISTENCY_ON_DEMAND) {
-    BOOST_THROW_EXCEPTION(Error("UdpFactory::createFace does not support creating on-demand face"));
-  }
-
   BOOST_ASSERT(uri.isCanonical());
 
-  boost::asio::ip::address ipAddress = boost::asio::ip::address::from_string(uri.getHost());
-  udp::Endpoint endpoint(ipAddress, boost::lexical_cast<uint16_t>(uri.getPort()));
+  if (persistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
+    BOOST_THROW_EXCEPTION(Error("UdpFactory::createFace does not support FACE_PERSISTENCY_ON_DEMAND"));
+  }
+
+  udp::Endpoint endpoint(ip::address::from_string(uri.getHost()),
+                         boost::lexical_cast<uint16_t>(uri.getPort()));
 
   if (endpoint.address().is_multicast()) {
     onConnectFailed("The provided address is multicast. Please use createMulticastFace method");
@@ -284,52 +261,47 @@
   }
 
   // very simple logic for now
-  for (ChannelMap::iterator channel = m_channels.begin();
-       channel != m_channels.end();
-       ++channel)
-  {
-    if ((channel->first.address().is_v4() && endpoint.address().is_v4()) ||
-        (channel->first.address().is_v6() && endpoint.address().is_v6()))
-    {
-      channel->second->connect(endpoint, persistency, onCreated, onConnectFailed);
+  for (const auto& i : m_channels) {
+    if ((i.first.address().is_v4() && endpoint.address().is_v4()) ||
+        (i.first.address().is_v6() && endpoint.address().is_v6())) {
+      i.second->connect(endpoint, persistency, onCreated, onConnectFailed);
       return;
     }
   }
 
-  onConnectFailed("No channels available to connect to " +
-                  boost::lexical_cast<std::string>(endpoint));
+  onConnectFailed("No channels available to connect to " + boost::lexical_cast<std::string>(endpoint));
+}
+
+std::vector<shared_ptr<const Channel>>
+UdpFactory::getChannels() const
+{
+  std::vector<shared_ptr<const Channel>> channels;
+  channels.reserve(m_channels.size());
+
+  for (const auto& i : m_channels)
+    channels.push_back(i.second);
+
+  return channels;
 }
 
 shared_ptr<UdpChannel>
-UdpFactory::findChannel(const udp::Endpoint& localEndpoint)
+UdpFactory::findChannel(const udp::Endpoint& localEndpoint) const
 {
-  ChannelMap::iterator i = m_channels.find(localEndpoint);
+  auto i = m_channels.find(localEndpoint);
   if (i != m_channels.end())
     return i->second;
   else
-    return shared_ptr<UdpChannel>();
-}
-
-shared_ptr<face::LpFaceWrapper>
-UdpFactory::findMulticastFace(const udp::Endpoint& localEndpoint)
-{
-  MulticastFaceMap::iterator i = m_multicastFaces.find(localEndpoint);
-  if (i != m_multicastFaces.end())
-    return i->second;
-  else
     return nullptr;
 }
 
-std::list<shared_ptr<const Channel>>
-UdpFactory::getChannels() const
+shared_ptr<face::LpFaceWrapper>
+UdpFactory::findMulticastFace(const udp::Endpoint& localEndpoint) const
 {
-  std::list<shared_ptr<const Channel>> channels;
-  for (ChannelMap::const_iterator i = m_channels.begin(); i != m_channels.end(); ++i)
-    {
-      channels.push_back(i->second);
-    }
-
-  return channels;
+  auto i = m_multicastFaces.find(localEndpoint);
+  if (i != m_multicastFaces.end())
+    return i->second;
+  else
+    return nullptr;
 }
 
 } // namespace nfd
diff --git a/daemon/face/udp-factory.hpp b/daemon/face/udp-factory.hpp
index 0465ca5..1c8f90f 100644
--- a/daemon/face/udp-factory.hpp
+++ b/daemon/face/udp-factory.hpp
@@ -51,9 +51,6 @@
 
   typedef std::map<udp::Endpoint, shared_ptr<face::LpFaceWrapper>> MulticastFaceMap;
 
-  explicit
-  UdpFactory(const std::string& defaultPort = "6363");
-
   /**
    * \brief Create UDP-based channel using udp::Endpoint
    *
@@ -97,8 +94,7 @@
    * \throws UdpFactory::Error
    */
   shared_ptr<UdpChannel>
-  createChannel(const std::string& localIp,
-                const std::string& localPort,
+  createChannel(const std::string& localIp, const std::string& localPort,
                 const time::seconds& timeout = time::seconds(600));
 
   /**
@@ -141,62 +137,56 @@
                       const std::string& multicastPort,
                       const std::string& networkInterfaceName = "");
 
-  // from ProtocolFactory
-  virtual void
-  createFace(const FaceUri& uri,
-             ndn::nfd::FacePersistency persistency,
-             const FaceCreatedCallback& onCreated,
-             const FaceConnectFailedCallback& onConnectFailed) DECL_OVERRIDE;
-
-  virtual std::list<shared_ptr<const Channel>>
-  getChannels() const DECL_OVERRIDE;
-
   /**
    * \brief Get map of configured multicast faces
    */
   const MulticastFaceMap&
   getMulticastFaces() const;
 
+public: // from ProtocolFactory
+  virtual void
+  createFace(const FaceUri& uri,
+             ndn::nfd::FacePersistency persistency,
+             const FaceCreatedCallback& onCreated,
+             const FaceCreationFailedCallback& onConnectFailed) DECL_OVERRIDE;
+
+  virtual std::vector<shared_ptr<const Channel>>
+  getChannels() const DECL_OVERRIDE;
+
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   void
   prohibitEndpoint(const udp::Endpoint& endpoint);
 
   void
-  prohibitAllIpv4Endpoints(const uint16_t port);
+  prohibitAllIpv4Endpoints(uint16_t port);
 
   void
-  prohibitAllIpv6Endpoints(const uint16_t port);
+  prohibitAllIpv6Endpoints(uint16_t port);
 
-  void
-  afterFaceFailed(udp::Endpoint& endpoint);
-
+private:
   /**
    * \brief Look up UdpChannel using specified local endpoint
    *
    * \returns shared pointer to the existing UdpChannel object
-   *          or empty shared pointer when such channel does not exist
-   *
-   * \throws never
+   *          or nullptr when such channel does not exist
    */
   shared_ptr<UdpChannel>
-  findChannel(const udp::Endpoint& localEndpoint);
+  findChannel(const udp::Endpoint& localEndpoint) const;
 
   /**
    * \brief Look up multicast UdpFace using specified local endpoint
    *
-   * \returns shared pointer to the existing multicast MulticastUdpFace object
+   * \returns shared pointer to the existing multicast UdpFace object
    *          or nullptr when such face does not exist
    */
   shared_ptr<face::LpFaceWrapper>
-  findMulticastFace(const udp::Endpoint& localEndpoint);
+  findMulticastFace(const udp::Endpoint& localEndpoint) const;
 
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  typedef std::map<udp::Endpoint, shared_ptr<UdpChannel>> ChannelMap;
-
-  ChannelMap m_channels;
+private:
+  std::map<udp::Endpoint, shared_ptr<UdpChannel>> m_channels;
   MulticastFaceMap m_multicastFaces;
 
-  std::string m_defaultPort;
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   std::set<udp::Endpoint> m_prohibitedEndpoints;
 };
 
diff --git a/daemon/face/unix-stream-factory.cpp b/daemon/face/unix-stream-factory.cpp
index 717f7b6..3de85b4 100644
--- a/daemon/face/unix-stream-factory.cpp
+++ b/daemon/face/unix-stream-factory.cpp
@@ -1,12 +1,12 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014,  Regents of the University of California,
- *                      Arizona Board of Regents,
- *                      Colorado State University,
- *                      University Pierre & Marie Curie, Sorbonne University,
- *                      Washington University in St. Louis,
- *                      Beijing Institute of Technology,
- *                      The University of Memphis
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
  *
  * This file is part of NFD (Named Data Networking Forwarding Daemon).
  * See AUTHORS.md for complete list of NFD authors and contributors.
@@ -36,7 +36,7 @@
   p = boost::filesystem::canonical(p.parent_path()) / p.filename();
   unix_stream::Endpoint endpoint(p.string());
 
-  shared_ptr<UnixStreamChannel> channel = findChannel(endpoint);
+  auto channel = findChannel(endpoint);
   if (channel)
     return channel;
 
@@ -45,35 +45,35 @@
   return channel;
 }
 
-shared_ptr<UnixStreamChannel>
-UnixStreamFactory::findChannel(const unix_stream::Endpoint& endpoint)
-{
-  ChannelMap::iterator i = m_channels.find(endpoint);
-  if (i != m_channels.end())
-    return i->second;
-  else
-    return shared_ptr<UnixStreamChannel>();
-}
-
 void
 UnixStreamFactory::createFace(const FaceUri& uri,
                               ndn::nfd::FacePersistency persistency,
                               const FaceCreatedCallback& onCreated,
-                              const FaceConnectFailedCallback& onConnectFailed)
+                              const FaceCreationFailedCallback& onConnectFailed)
 {
   BOOST_THROW_EXCEPTION(Error("UnixStreamFactory does not support 'createFace' operation"));
 }
 
-std::list<shared_ptr<const Channel> >
+std::vector<shared_ptr<const Channel>>
 UnixStreamFactory::getChannels() const
 {
-  std::list<shared_ptr<const Channel> > channels;
-  for (ChannelMap::const_iterator i = m_channels.begin(); i != m_channels.end(); ++i)
-    {
-      channels.push_back(i->second);
-    }
+  std::vector<shared_ptr<const Channel>> channels;
+  channels.reserve(m_channels.size());
+
+  for (const auto& i : m_channels)
+    channels.push_back(i.second);
 
   return channels;
 }
 
+shared_ptr<UnixStreamChannel>
+UnixStreamFactory::findChannel(const unix_stream::Endpoint& endpoint) const
+{
+  auto i = m_channels.find(endpoint);
+  if (i != m_channels.end())
+    return i->second;
+  else
+    return nullptr;
+}
+
 } // namespace nfd
diff --git a/daemon/face/unix-stream-factory.hpp b/daemon/face/unix-stream-factory.hpp
index 61ef3de..43fe553 100644
--- a/daemon/face/unix-stream-factory.hpp
+++ b/daemon/face/unix-stream-factory.hpp
@@ -1,12 +1,12 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014,  Regents of the University of California,
- *                      Arizona Board of Regents,
- *                      Colorado State University,
- *                      University Pierre & Marie Curie, Sorbonne University,
- *                      Washington University in St. Louis,
- *                      Beijing Institute of Technology,
- *                      The University of Memphis
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
  *
  * This file is part of NFD (Named Data Networking Forwarding Daemon).
  * See AUTHORS.md for complete list of NFD authors and contributors.
@@ -37,9 +37,14 @@
   /**
    * \brief Exception of UnixStreamFactory
    */
-  struct Error : public ProtocolFactory::Error
+  class Error : public ProtocolFactory::Error
   {
-    Error(const std::string& what) : ProtocolFactory::Error(what) {}
+  public:
+    explicit
+    Error(const std::string& what)
+      : ProtocolFactory::Error(what)
+    {
+    }
   };
 
   /**
@@ -57,15 +62,14 @@
   shared_ptr<UnixStreamChannel>
   createChannel(const std::string& unixSocketPath);
 
-  // from Factory
-
+public: // from ProtocolFactory
   virtual void
   createFace(const FaceUri& uri,
              ndn::nfd::FacePersistency persistency,
              const FaceCreatedCallback& onCreated,
-             const FaceConnectFailedCallback& onConnectFailed) DECL_OVERRIDE;
+             const FaceCreationFailedCallback& onConnectFailed) DECL_OVERRIDE;
 
-  virtual std::list<shared_ptr<const Channel> >
+  virtual std::vector<shared_ptr<const Channel>>
   getChannels() const DECL_OVERRIDE;
 
 private:
@@ -74,15 +78,12 @@
    *
    * \returns shared pointer to the existing UnixStreamChannel object
    *          or empty shared pointer when such channel does not exist
-   *
-   * \throws never
    */
   shared_ptr<UnixStreamChannel>
-  findChannel(const unix_stream::Endpoint& endpoint);
+  findChannel(const unix_stream::Endpoint& endpoint) const;
 
 private:
-  typedef std::map< unix_stream::Endpoint, shared_ptr<UnixStreamChannel> > ChannelMap;
-  ChannelMap m_channels;
+  std::map<unix_stream::Endpoint, shared_ptr<UnixStreamChannel>> m_channels;
 };
 
 } // namespace nfd
diff --git a/daemon/face/websocket-channel.hpp b/daemon/face/websocket-channel.hpp
index f560ab3..027085c 100644
--- a/daemon/face/websocket-channel.hpp
+++ b/daemon/face/websocket-channel.hpp
@@ -31,6 +31,10 @@
 
 namespace nfd {
 
+namespace websocket {
+typedef boost::asio::ip::tcp::endpoint Endpoint;
+} // namespace websocket
+
 /**
  * \brief Class implementing WebSocket-based channel to create faces
  */
diff --git a/daemon/face/websocket-face.hpp b/daemon/face/websocket-face.hpp
index 7838572..3c7fbf1 100644
--- a/daemon/face/websocket-face.hpp
+++ b/daemon/face/websocket-face.hpp
@@ -38,11 +38,9 @@
 namespace nfd {
 
 namespace websocket {
-typedef boost::asio::ip::tcp::endpoint Endpoint;
 typedef websocketpp::server<websocketpp::config::asio> Server;
 } // namespace websocket
 
-
 /**
  * \brief Implementation of Face abstraction that uses WebSocket
  *        as underlying transport mechanism
diff --git a/daemon/face/websocket-factory.cpp b/daemon/face/websocket-factory.cpp
index 80e8efa..bcb3970 100644
--- a/daemon/face/websocket-factory.cpp
+++ b/daemon/face/websocket-factory.cpp
@@ -27,18 +27,13 @@
 
 namespace nfd {
 
-using namespace boost::asio;
-
-WebSocketFactory::WebSocketFactory(const std::string& defaultPort)
-  : m_defaultPort(defaultPort)
-{
-}
+namespace ip = boost::asio::ip;
 
 shared_ptr<WebSocketChannel>
 WebSocketFactory::createChannel(const websocket::Endpoint& endpoint)
 {
-  shared_ptr<WebSocketChannel> channel = findChannel(endpoint);
-  if (static_cast<bool>(channel))
+  auto channel = findChannel(endpoint);
+  if (channel)
     return channel;
 
   channel = make_shared<WebSocketChannel>(endpoint);
@@ -48,42 +43,42 @@
 }
 
 shared_ptr<WebSocketChannel>
-WebSocketFactory::createChannel(const std::string& localIp, const std::string& port)
+WebSocketFactory::createChannel(const std::string& localIp, const std::string& localPort)
 {
-  using namespace boost::asio::ip;
-  websocket::Endpoint endpoint(address::from_string(localIp), boost::lexical_cast<uint16_t>(port));
+  websocket::Endpoint endpoint(ip::address::from_string(localIp),
+                               boost::lexical_cast<uint16_t>(localPort));
   return createChannel(endpoint);
 }
 
-shared_ptr<WebSocketChannel>
-WebSocketFactory::findChannel(const websocket::Endpoint& localEndpoint)
-{
-  ChannelMap::iterator i = m_channels.find(localEndpoint);
-  if (i != m_channels.end())
-    return i->second;
-  else
-    return shared_ptr<WebSocketChannel>();
-}
-
 void
 WebSocketFactory::createFace(const FaceUri& uri,
                              ndn::nfd::FacePersistency persistency,
                              const FaceCreatedCallback& onCreated,
-                             const FaceConnectFailedCallback& onConnectFailed)
+                             const FaceCreationFailedCallback& onConnectFailed)
 {
   BOOST_THROW_EXCEPTION(Error("WebSocketFactory does not support 'createFace' operation"));
 }
 
-std::list<shared_ptr<const Channel> >
+std::vector<shared_ptr<const Channel>>
 WebSocketFactory::getChannels() const
 {
-  std::list<shared_ptr<const Channel> > channels;
-  for (ChannelMap::const_iterator i = m_channels.begin(); i != m_channels.end(); ++i)
-    {
-      channels.push_back(i->second);
-    }
+  std::vector<shared_ptr<const Channel>> channels;
+  channels.reserve(m_channels.size());
+
+  for (const auto& i : m_channels)
+    channels.push_back(i.second);
 
   return channels;
 }
 
+shared_ptr<WebSocketChannel>
+WebSocketFactory::findChannel(const websocket::Endpoint& endpoint) const
+{
+  auto i = m_channels.find(endpoint);
+  if (i != m_channels.end())
+    return i->second;
+  else
+    return nullptr;
+}
+
 } // namespace nfd
diff --git a/daemon/face/websocket-factory.hpp b/daemon/face/websocket-factory.hpp
index 7271b0a..87947ba 100644
--- a/daemon/face/websocket-factory.hpp
+++ b/daemon/face/websocket-factory.hpp
@@ -47,9 +47,6 @@
     }
   };
 
-  explicit
-  WebSocketFactory(const std::string& defaultPort);
-
   /**
    * \brief Create WebSocket-based channel using websocket::Endpoint
    *
@@ -76,16 +73,16 @@
    * \throws WebSocketFactory::Error
    */
   shared_ptr<WebSocketChannel>
-  createChannel(const std::string& localIp, const std::string& port);
+  createChannel(const std::string& localIp, const std::string& localPort);
 
-  // from ProtocolFactory
+public: // from ProtocolFactory
   virtual void
   createFace(const FaceUri& uri,
              ndn::nfd::FacePersistency persistency,
              const FaceCreatedCallback& onCreated,
-             const FaceConnectFailedCallback& onConnectFailed) DECL_OVERRIDE;
+             const FaceCreationFailedCallback& onConnectFailed) DECL_OVERRIDE;
 
-  virtual std::list<shared_ptr<const Channel> >
+  virtual std::vector<shared_ptr<const Channel>>
   getChannels() const DECL_OVERRIDE;
 
 private:
@@ -94,16 +91,12 @@
    *
    * \returns shared pointer to the existing WebSocketChannel object
    *          or empty shared pointer when such channel does not exist
-   *
-   * \throws never
    */
   shared_ptr<WebSocketChannel>
-  findChannel(const websocket::Endpoint& localEndpoint);
+  findChannel(const websocket::Endpoint& endpoint) const;
 
-  typedef std::map< websocket::Endpoint, shared_ptr<WebSocketChannel> > ChannelMap;
-  ChannelMap m_channels;
-
-  std::string m_defaultPort;
+private:
+  std::map<websocket::Endpoint, shared_ptr<WebSocketChannel>> m_channels;
 };
 
 } // namespace nfd
diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
index 29cac39..6413334 100644
--- a/daemon/mgmt/face-manager.cpp
+++ b/daemon/mgmt/face-manager.cpp
@@ -32,8 +32,8 @@
 #include "face/udp-factory.hpp"
 #include "fw/face-table.hpp"
 
-#include <ndn-cxx/management/nfd-face-status.hpp>
 #include <ndn-cxx/management/nfd-channel-status.hpp>
+#include <ndn-cxx/management/nfd-face-status.hpp>
 #include <ndn-cxx/management/nfd-face-event-notification.hpp>
 
 #ifdef HAVE_UNIX_SOCKETS
@@ -104,7 +104,7 @@
     return done(ControlResponse(400, "Non-canonical URI"));
   }
 
-  FactoryMap::iterator factory = m_factories.find(uri.getScheme());
+  auto factory = m_factories.find(uri.getScheme());
   if (factory == m_factories.end()) {
     return done(ControlResponse(501, "Unsupported protocol"));
   }
@@ -138,7 +138,7 @@
                                     const shared_ptr<Face>& newFace,
                                     const ndn::mgmt::CommandContinuation& done)
 {
-  addCreatedFaceToForwarder(newFace);
+  m_faceTable.add(newFace);
   parameters.setFaceId(newFace->getId());
   parameters.setUri(newFace->getRemoteUri().toString());
   parameters.setFacePersistency(newFace->getPersistency());
@@ -240,15 +240,14 @@
   result.lpFace = nullptr;
 
   auto face = m_faceTable.get(request.getIncomingFaceId());
-  if (!static_cast<bool>(face)) {
-    NFD_LOG_DEBUG("command result: faceid " << request.getIncomingFaceId() << " not found");
+  if (face == nullptr) {
+    NFD_LOG_DEBUG("FaceId " << request.getIncomingFaceId() << " not found");
     done(ControlResponse(410, "Face not found"));
     return result;
   }
 
   if (!face->isLocal()) {
-    NFD_LOG_DEBUG("command result: cannot enable local control on non-local faceid " <<
-                  face->getId());
+    NFD_LOG_DEBUG("Cannot enable local control on non-local FaceId " << face->getId());
     done(ControlResponse(412, "Face is non-local"));
     return result;
   }
@@ -260,7 +259,7 @@
     BOOST_ASSERT(lpFaceW != nullptr);
     result.lpFace = lpFaceW->getLpFace();
   }
-  result.feature = static_cast<LocalControlFeature>(parameters.getLocalControlFeature());
+  result.feature = parameters.getLocalControlFeature();
 
   return result;
 }
@@ -279,22 +278,19 @@
 FaceManager::listChannels(const Name& topPrefix, const Interest& interest,
                           ndn::mgmt::StatusDatasetContext& context)
 {
-  std::set<shared_ptr<ProtocolFactory>> seenFactories;
+  std::set<const ProtocolFactory*> seenFactories;
 
-  for (auto i = m_factories.begin(); i != m_factories.end(); ++i) {
-    const shared_ptr<ProtocolFactory>& factory = i->second;
+  for (const auto& kv : m_factories) {
+    const ProtocolFactory* factory = kv.second.get();
+    bool inserted;
+    std::tie(std::ignore, inserted) = seenFactories.insert(factory);
 
-    if (seenFactories.find(factory) != seenFactories.end()) {
-      continue;
-    }
-    seenFactories.insert(factory);
-
-    std::list<shared_ptr<const Channel>> channels = factory->getChannels();
-
-    for (auto j = channels.begin(); j != channels.end(); ++j) {
-      ndn::nfd::ChannelStatus entry;
-      entry.setLocalUri((*j)->getUri().toString());
-      context.append(entry.wireEncode());
+    if (inserted) {
+      for (const auto& channel : factory->getChannels()) {
+        ndn::nfd::ChannelStatus entry;
+        entry.setLocalUri(channel->getUri().toString());
+        context.append(entry.wireEncode());
+      }
     }
   }
 
@@ -310,9 +306,9 @@
   try {
     faceFilter.wireDecode(query[-1].blockFromValue());
   }
-  catch (const tlv::Error&) {
-    NFD_LOG_DEBUG("query result: malformed filter");
-    return context.reject(ControlResponse(400, "malformed filter"));
+  catch (const tlv::Error& e) {
+    NFD_LOG_DEBUG("Malformed query filter: " << e.what());
+    return context.reject(ControlResponse(400, "Malformed filter"));
   }
 
   for (const auto& face : m_faceTable) {
@@ -320,6 +316,7 @@
       context.append(face->getFaceStatus().wireEncode());
     }
   }
+
   context.end();
 }
 
@@ -397,8 +394,7 @@
   bool hasSeenUdp = false;
   bool hasSeenEther = false;
   bool hasSeenWebSocket = false;
-
-  const std::vector<NetworkInterfaceInfo> nicList(listNetworkInterfaces());
+  auto nicList = listNetworkInterfaces();
 
   for (const auto& item : configSection) {
     if (item.first == "unix") {
@@ -457,16 +453,15 @@
   // }
 
 #if defined(HAVE_UNIX_SOCKETS)
-
   std::string path = "/var/run/nfd.sock";
 
-  for (auto i = configSection.begin(); i != configSection.end(); ++i) {
-    if (i->first == "path") {
-      path = i->second.get_value<std::string>();
+  for (const auto& i : configSection) {
+    if (i.first == "path") {
+      path = i.second.get_value<std::string>();
     }
     else {
       BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
-                                              i->first + "\" in \"unix\" section"));
+                                              i.first + "\" in \"unix\" section"));
     }
   }
 
@@ -475,14 +470,11 @@
       return;
     }
 
-    shared_ptr<UnixStreamFactory> factory = make_shared<UnixStreamFactory>();
-    shared_ptr<UnixStreamChannel> unixChannel = factory->createChannel(path);
-
-    // Should acceptFailed callback be used somehow?
-    unixChannel->listen(bind(&FaceTable::add, &m_faceTable, _1),
-                        UnixStreamChannel::ConnectFailedCallback());
-
+    auto factory = make_shared<UnixStreamFactory>();
     m_factories.insert(std::make_pair("unix", factory));
+
+    auto channel = factory->createChannel(path);
+    channel->listen(bind(&FaceTable::add, &m_faceTable, _1), nullptr);
   }
 #else
   BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD was compiled without Unix sockets support, "
@@ -500,40 +492,33 @@
   //   port 6363 ; TCP listener port number
   // }
 
-  std::string port = "6363";
+  uint16_t port = 6363;
   bool needToListen = true;
   bool enableV4 = true;
   bool enableV6 = true;
 
-  for (auto i = configSection.begin(); i != configSection.end(); ++i) {
-    if (i->first == "port") {
-      port = i->second.get_value<std::string>();
-      try {
-        uint16_t portNo = boost::lexical_cast<uint16_t>(port);
-        NFD_LOG_TRACE("TCP port set to " << portNo);
-      }
-      catch (const std::bad_cast& error) {
-        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
-                                                i->first + "\" in \"tcp\" section"));
-      }
+  for (const auto& i : configSection) {
+    if (i.first == "port") {
+      port = ConfigFile::parseNumber<uint16_t>(i, "tcp");
+      NFD_LOG_TRACE("TCP port set to " << port);
     }
-    else if (i->first == "listen") {
-      needToListen = ConfigFile::parseYesNo(i, i->first, "tcp");
+    else if (i.first == "listen") {
+      needToListen = ConfigFile::parseYesNo(i, "tcp");
     }
-    else if (i->first == "enable_v4") {
-      enableV4 = ConfigFile::parseYesNo(i, i->first, "tcp");
+    else if (i.first == "enable_v4") {
+      enableV4 = ConfigFile::parseYesNo(i, "tcp");
     }
-    else if (i->first == "enable_v6") {
-      enableV6 = ConfigFile::parseYesNo(i, i->first, "tcp");
+    else if (i.first == "enable_v6") {
+      enableV6 = ConfigFile::parseYesNo(i, "tcp");
     }
     else {
       BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
-                                              i->first + "\" in \"tcp\" section"));
+                                              i.first + "\" in \"tcp\" section"));
     }
   }
 
   if (!enableV4 && !enableV6) {
-    BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
+    BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 TCP channels have been disabled."
                                             " Remove \"tcp\" section to disable TCP channels or"
                                             " re-enable at least one channel type."));
   }
@@ -543,26 +528,24 @@
       return;
     }
 
-    shared_ptr<TcpFactory> factory = make_shared<TcpFactory>(port);
+    auto factory = make_shared<TcpFactory>();
     m_factories.insert(std::make_pair("tcp", factory));
 
     if (enableV4) {
-      shared_ptr<TcpChannel> ipv4Channel = factory->createChannel("0.0.0.0", port);
+      tcp::Endpoint endpoint(boost::asio::ip::tcp::v4(), port);
+      shared_ptr<TcpChannel> v4Channel = factory->createChannel(endpoint);
       if (needToListen) {
-        // Should acceptFailed callback be used somehow?
-        ipv4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
-                            TcpChannel::ConnectFailedCallback());
+        v4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1), nullptr);
       }
 
       m_factories.insert(std::make_pair("tcp4", factory));
     }
 
     if (enableV6) {
-      shared_ptr<TcpChannel> ipv6Channel = factory->createChannel("::", port);
+      tcp::Endpoint endpoint(boost::asio::ip::tcp::v6(), port);
+      shared_ptr<TcpChannel> v6Channel = factory->createChannel(endpoint);
       if (needToListen) {
-        // Should acceptFailed callback be used somehow?
-        ipv6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
-                            TcpChannel::ConnectFailedCallback());
+        v6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1), nullptr);
       }
 
       m_factories.insert(std::make_pair("tcp6", factory));
@@ -571,8 +554,7 @@
 }
 
 void
-FaceManager::processSectionUdp(const ConfigSection& configSection,
-                               bool isDryRun,
+FaceManager::processSectionUdp(const ConfigSection& configSection, bool isDryRun,
                                const std::vector<NetworkInterfaceInfo>& nicList)
 {
   // ; the udp section contains settings of UDP faces and channels
@@ -588,93 +570,70 @@
   //   mcast_group 224.0.23.170 ; UDP multicast group (IPv4 only)
   // }
 
-  std::string port = "6363";
+  uint16_t port = 6363;
   bool enableV4 = true;
   bool enableV6 = true;
   size_t timeout = 600;
   size_t keepAliveInterval = 25;
   bool useMcast = true;
-  std::string mcastGroup = "224.0.23.170";
-  std::string mcastPort = "56363";
+  auto mcastGroup = boost::asio::ip::address_v4::from_string("224.0.23.170");
+  uint16_t mcastPort = 56363;
 
-
-  for (auto i = configSection.begin(); i != configSection.end(); ++i) {
-    if (i->first == "port") {
-      port = i->second.get_value<std::string>();
+  for (const auto& i : configSection) {
+    if (i.first == "port") {
+      port = ConfigFile::parseNumber<uint16_t>(i, "udp");
+      NFD_LOG_TRACE("UDP unicast port set to " << port);
+    }
+    else if (i.first == "enable_v4") {
+      enableV4 = ConfigFile::parseYesNo(i, "udp");
+    }
+    else if (i.first == "enable_v6") {
+      enableV6 = ConfigFile::parseYesNo(i, "udp");
+    }
+    else if (i.first == "idle_timeout") {
       try {
-        uint16_t portNo = boost::lexical_cast<uint16_t>(port);
-        NFD_LOG_TRACE("UDP port set to " << portNo);
+        timeout = i.second.get_value<size_t>();
       }
-      catch (const std::bad_cast& error) {
-        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
-                                                i->first + "\" in \"udp\" section"));
-      }
-    }
-    else if (i->first == "enable_v4") {
-      enableV4 = ConfigFile::parseYesNo(i, i->first, "udp");
-    }
-    else if (i->first == "enable_v6") {
-      enableV6 = ConfigFile::parseYesNo(i, i->first, "udp");
-    }
-    else if (i->first == "idle_timeout") {
-      try {
-        timeout = i->second.get_value<size_t>();
-      }
-      catch (const std::exception& e) {
+      catch (const boost::property_tree::ptree_bad_data&) {
         BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
-                                                i->first + "\" in \"udp\" section"));
+                                                i.first + "\" in \"udp\" section"));
       }
     }
-    else if (i->first == "keep_alive_interval") {
+    else if (i.first == "keep_alive_interval") {
       try {
-        keepAliveInterval = i->second.get_value<size_t>();
-
+        keepAliveInterval = i.second.get_value<size_t>();
         /// \todo Make use of keepAliveInterval
-        /// \todo what is keep alive interval used for?
         (void)(keepAliveInterval);
       }
-      catch (const std::exception& e) {
+      catch (const boost::property_tree::ptree_bad_data&) {
         BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
-                                                i->first + "\" in \"udp\" section"));
+                                                i.first + "\" in \"udp\" section"));
       }
     }
-    else if (i->first == "mcast") {
-      useMcast = ConfigFile::parseYesNo(i, i->first, "udp");
+    else if (i.first == "mcast") {
+      useMcast = ConfigFile::parseYesNo(i, "udp");
     }
-    else if (i->first == "mcast_port") {
-      mcastPort = i->second.get_value<std::string>();
-      try {
-        uint16_t portNo = boost::lexical_cast<uint16_t>(mcastPort);
-        NFD_LOG_TRACE("UDP multicast port set to " << portNo);
-      }
-      catch (const std::bad_cast& error) {
-        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
-                                                i->first + "\" in \"udp\" section"));
-      }
+    else if (i.first == "mcast_port") {
+      mcastPort = ConfigFile::parseNumber<uint16_t>(i, "udp");
+      NFD_LOG_TRACE("UDP multicast port set to " << mcastPort);
     }
-    else if (i->first == "mcast_group") {
-      using namespace boost::asio::ip;
-      mcastGroup = i->second.get_value<std::string>();
-      try {
-        address mcastGroupTest = address::from_string(mcastGroup);
-        if (!mcastGroupTest.is_v4()) {
-          BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
-                                                  i->first + "\" in \"udp\" section"));
-        }
-      }
-      catch(const std::runtime_error& e) {
+    else if (i.first == "mcast_group") {
+      boost::system::error_code ec;
+      mcastGroup = boost::asio::ip::address_v4::from_string(i.second.get_value<std::string>(), ec);
+      if (ec) {
         BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
-                                                i->first + "\" in \"udp\" section"));
+                                                i.first + "\" in \"udp\" section"));
       }
+      NFD_LOG_TRACE("UDP multicast group set to " << mcastGroup);
     }
     else {
       BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
-                                              i->first + "\" in \"udp\" section"));
+                                              i.first + "\" in \"udp\" section"));
     }
   }
 
   if (!enableV4 && !enableV6) {
-    BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
+    BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 UDP channels have been disabled."
                                             " Remove \"udp\" section to disable UDP channels or"
                                             " re-enable at least one channel type."));
   }
@@ -691,29 +650,31 @@
       factory = static_pointer_cast<UdpFactory>(m_factories["udp"]);
     }
     else {
-      factory = make_shared<UdpFactory>(port);
+      factory = make_shared<UdpFactory>();
       m_factories.insert(std::make_pair("udp", factory));
     }
 
     if (!isReload && enableV4) {
-      shared_ptr<UdpChannel> v4Channel =
-        factory->createChannel("0.0.0.0", port, time::seconds(timeout));
-
-      v4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
-                        UdpChannel::ConnectFailedCallback());
+      udp::Endpoint endpoint(boost::asio::ip::udp::v4(), port);
+      shared_ptr<UdpChannel> v4Channel = factory->createChannel(endpoint, time::seconds(timeout));
+      v4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1), nullptr);
 
       m_factories.insert(std::make_pair("udp4", factory));
     }
 
     if (!isReload && enableV6) {
-      shared_ptr<UdpChannel> v6Channel =
-        factory->createChannel("::", port, time::seconds(timeout));
+      udp::Endpoint endpoint(boost::asio::ip::udp::v6(), port);
+      shared_ptr<UdpChannel> v6Channel = factory->createChannel(endpoint, time::seconds(timeout));
+      v6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1), nullptr);
 
-      v6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
-                        UdpChannel::ConnectFailedCallback());
       m_factories.insert(std::make_pair("udp6", factory));
     }
 
+    std::set<shared_ptr<face::LpFaceWrapper>> multicastFacesToRemove;
+    for (const auto& i : factory->getMulticastFaces()) {
+      multicastFacesToRemove.insert(i.second);
+    }
+
     if (useMcast && enableV4) {
       std::vector<NetworkInterfaceInfo> ipv4MulticastInterfaces;
       for (const auto& nic : nicList) {
@@ -731,43 +692,24 @@
       }
 #endif
 
-      std::list<shared_ptr<face::LpFaceWrapper>> multicastFacesToRemove;
-      for (auto i = factory->getMulticastFaces().begin();
-           i != factory->getMulticastFaces().end();
-           ++i) {
-        multicastFacesToRemove.push_back(i->second);
-      }
-
+      udp::Endpoint mcastEndpoint(mcastGroup, mcastPort);
       for (const auto& nic : ipv4MulticastInterfaces) {
-        auto newFace = factory->createMulticastFace(nic.ipv4Addresses[0].to_string(),
-                                                    mcastGroup, mcastPort,
+        udp::Endpoint localEndpoint(nic.ipv4Addresses[0], mcastPort);
+        auto newFace = factory->createMulticastFace(localEndpoint, mcastEndpoint,
                                                     isNicNameNecessary ? nic.name : "");
-        addCreatedFaceToForwarder(newFace);
-        multicastFacesToRemove.remove(newFace);
-      }
-
-      for (const auto& face : multicastFacesToRemove) {
-        face->close();
+        m_faceTable.add(newFace);
+        multicastFacesToRemove.erase(newFace);
       }
     }
-    else {
-      std::list<shared_ptr<face::LpFaceWrapper>> multicastFacesToRemove;
-      for (auto i = factory->getMulticastFaces().begin();
-           i != factory->getMulticastFaces().end();
-           ++i) {
-        multicastFacesToRemove.push_back(i->second);
-      }
 
-      for (const auto& face : multicastFacesToRemove) {
-        face->close();
-      }
+    for (const auto& face : multicastFacesToRemove) {
+      face->close();
     }
   }
 }
 
 void
-FaceManager::processSectionEther(const ConfigSection& configSection,
-                                 bool isDryRun,
+FaceManager::processSectionEther(const ConfigSection& configSection, bool isDryRun,
                                  const std::vector<NetworkInterfaceInfo>& nicList)
 {
   // ; the ether section contains settings of Ethernet faces and channels
@@ -782,20 +724,21 @@
   bool useMcast = true;
   ethernet::Address mcastGroup(ethernet::getDefaultMulticastAddress());
 
-  for (auto i = configSection.begin(); i != configSection.end(); ++i) {
-    if (i->first == "mcast") {
-      useMcast = ConfigFile::parseYesNo(i, i->first, "ether");
+  for (const auto& i : configSection) {
+    if (i.first == "mcast") {
+      useMcast = ConfigFile::parseYesNo(i, "ether");
     }
-    else if (i->first == "mcast_group") {
-      mcastGroup = ethernet::Address::fromString(i->second.get_value<std::string>());
+    else if (i.first == "mcast_group") {
+      mcastGroup = ethernet::Address::fromString(i.second.get_value<std::string>());
       if (mcastGroup.isNull()) {
         BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
-                                                i->first + "\" in \"ether\" section"));
+                                                i.first + "\" in \"ether\" section"));
       }
+      NFD_LOG_TRACE("Ethernet multicast group set to " << mcastGroup);
     }
     else {
       BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
-                                              i->first + "\" in \"ether\" section"));
+                                              i.first + "\" in \"ether\" section"));
     }
   }
 
@@ -809,22 +752,18 @@
       m_factories.insert(std::make_pair("ether", factory));
     }
 
-    if (useMcast) {
-      std::list<shared_ptr<EthernetFace> > multicastFacesToRemove;
-      for (auto i = factory->getMulticastFaces().begin();
-           i != factory->getMulticastFaces().end();
-           ++i) {
-        multicastFacesToRemove.push_back(i->second);
-      }
+    std::set<shared_ptr<EthernetFace>> multicastFacesToRemove;
+    for (const auto& i : factory->getMulticastFaces()) {
+      multicastFacesToRemove.insert(i.second);
+    }
 
+    if (useMcast) {
       for (const auto& nic : nicList) {
         if (nic.isUp() && nic.isMulticastCapable()) {
           try {
-            shared_ptr<EthernetFace> newFace =
-            factory->createMulticastFace(nic, mcastGroup);
-
-            addCreatedFaceToForwarder(newFace);
-            multicastFacesToRemove.remove(newFace);
+            auto newFace = factory->createMulticastFace(nic, mcastGroup);
+            m_faceTable.add(newFace);
+            multicastFacesToRemove.erase(newFace);
           }
           catch (const EthernetFactory::Error& factoryError) {
             NFD_LOG_ERROR(factoryError.what() << ", continuing");
@@ -834,26 +773,10 @@
           }
         }
       }
-
-      for (auto i = multicastFacesToRemove.begin();
-           i != multicastFacesToRemove.end();
-           ++i) {
-        (*i)->close();
-      }
     }
-    else {
-      std::list<shared_ptr<EthernetFace> > multicastFacesToRemove;
-      for (auto i = factory->getMulticastFaces().begin();
-           i != factory->getMulticastFaces().end();
-           ++i) {
-        multicastFacesToRemove.push_back(i->second);
-      }
 
-      for (auto i = multicastFacesToRemove.begin();
-           i != multicastFacesToRemove.end();
-           ++i) {
-        (*i)->close();
-      }
+    for (const auto& face : multicastFacesToRemove) {
+      face->close();
     }
   }
 #else
@@ -874,41 +797,33 @@
   // }
 
 #if defined(HAVE_WEBSOCKET)
-
-  std::string port = "9696";
+  uint16_t port = 9696;
   bool needToListen = true;
   bool enableV4 = true;
   bool enableV6 = true;
 
-  for (auto i = configSection.begin(); i != configSection.end(); ++i) {
-    if (i->first == "port") {
-      port = i->second.get_value<std::string>();
-      try {
-        uint16_t portNo = boost::lexical_cast<uint16_t>(port);
-        NFD_LOG_TRACE("WebSocket port set to " << portNo);
-      }
-      catch (const std::bad_cast& error) {
-        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
-                                                i->first + "\" in \"websocket\" section"));
-      }
+  for (const auto& i : configSection) {
+    if (i.first == "port") {
+      port = ConfigFile::parseNumber<uint16_t>(i, "websocket");
+      NFD_LOG_TRACE("WebSocket port set to " << port);
     }
-    else if (i->first == "listen") {
-      needToListen = ConfigFile::parseYesNo(i, i->first, "websocket");
+    else if (i.first == "listen") {
+      needToListen = ConfigFile::parseYesNo(i, "websocket");
     }
-    else if (i->first == "enable_v4") {
-      enableV4 = ConfigFile::parseYesNo(i, i->first, "websocket");
+    else if (i.first == "enable_v4") {
+      enableV4 = ConfigFile::parseYesNo(i, "websocket");
     }
-    else if (i->first == "enable_v6") {
-      enableV6 = ConfigFile::parseYesNo(i, i->first, "websocket");
+    else if (i.first == "enable_v6") {
+      enableV6 = ConfigFile::parseYesNo(i, "websocket");
     }
     else {
       BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
-                                              i->first + "\" in \"websocket\" section"));
+                                              i.first + "\" in \"websocket\" section"));
     }
   }
 
   if (!enableV4 && !enableV6) {
-    BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
+    BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 WebSocket channels have been disabled."
                                             " Remove \"websocket\" section to disable WebSocket channels or"
                                             " re-enable at least one channel type."));
   }
@@ -922,25 +837,27 @@
       return;
     }
 
-    shared_ptr<WebSocketFactory> factory = make_shared<WebSocketFactory>(port);
+    auto factory = make_shared<WebSocketFactory>();
     m_factories.insert(std::make_pair("websocket", factory));
 
+    shared_ptr<WebSocketChannel> channel;
+
     if (enableV6 && enableV4) {
-      shared_ptr<WebSocketChannel> ip46Channel = factory->createChannel("::", port);
-      if (needToListen) {
-        ip46Channel->listen(bind(&FaceTable::add, &m_faceTable, _1));
-      }
+      websocket::Endpoint endpoint(boost::asio::ip::address_v6::any(), port);
+      channel = factory->createChannel(endpoint);
 
       m_factories.insert(std::make_pair("websocket46", factory));
     }
     else if (enableV4) {
-      shared_ptr<WebSocketChannel> ipv4Channel = factory->createChannel("0.0.0.0", port);
-      if (needToListen) {
-        ipv4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1));
-      }
+      websocket::Endpoint endpoint(boost::asio::ip::address_v4::any(), port);
+      channel = factory->createChannel(endpoint);
 
       m_factories.insert(std::make_pair("websocket4", factory));
     }
+
+    if (channel && needToListen) {
+      channel->listen(bind(&FaceTable::add, &m_faceTable, _1));
+    }
   }
 #else
   BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD was compiled without WebSocket, "
@@ -948,10 +865,4 @@
 #endif // HAVE_WEBSOCKET
 }
 
-void
-FaceManager::addCreatedFaceToForwarder(shared_ptr<Face> newFace)
-{
-  m_faceTable.add(newFace);
-}
-
-} // namespace
+} // namespace nfd
diff --git a/daemon/mgmt/face-manager.hpp b/daemon/mgmt/face-manager.hpp
index e3c955f..57788b7 100644
--- a/daemon/mgmt/face-manager.hpp
+++ b/daemon/mgmt/face-manager.hpp
@@ -129,7 +129,8 @@
 
 private: // configuration
   void
-  processConfig(const ConfigSection& configSection, bool isDryRun, const std::string& filename);
+  processConfig(const ConfigSection& configSection, bool isDryRun,
+                const std::string& filename);
 
   void
   processSectionUnix(const ConfigSection& configSection, bool isDryRun);
@@ -138,25 +139,18 @@
   processSectionTcp(const ConfigSection& configSection, bool isDryRun);
 
   void
-  processSectionUdp(const ConfigSection& configSection,
-                    bool isDryRun,
+  processSectionUdp(const ConfigSection& configSection, bool isDryRun,
                     const std::vector<NetworkInterfaceInfo>& nicList);
 
   void
-  processSectionEther(const ConfigSection& configSection,
-                      bool isDryRun,
+  processSectionEther(const ConfigSection& configSection, bool isDryRun,
                       const std::vector<NetworkInterfaceInfo>& nicList);
 
   void
   processSectionWebSocket(const ConfigSection& configSection, bool isDryRun);
 
-private: // helpers for configuration
-  void
-  addCreatedFaceToForwarder(shared_ptr<Face> newFace);
-
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  typedef std::map<std::string/*protocol*/, shared_ptr<ProtocolFactory>> FactoryMap;
-  FactoryMap m_factories;
+  std::map<std::string /*protocol*/, shared_ptr<ProtocolFactory>> m_factories;
 
 private:
   FaceTable& m_faceTable;
diff --git a/tests/daemon/face/udp.t.cpp b/tests/daemon/face/udp.t.cpp
index 6869176..86c9bfe 100644
--- a/tests/daemon/face/udp.t.cpp
+++ b/tests/daemon/face/udp.t.cpp
@@ -44,22 +44,16 @@
   UdpFactory factory;
   BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
 
-  std::vector<shared_ptr<const Channel> > expectedChannels;
-
+  std::vector<shared_ptr<const Channel>> expectedChannels;
   expectedChannels.push_back(factory.createChannel("127.0.0.1", "20070"));
   expectedChannels.push_back(factory.createChannel("127.0.0.1", "20071"));
   expectedChannels.push_back(factory.createChannel("::1", "20071"));
 
-  std::list<shared_ptr<const Channel> > channels = factory.getChannels();
-  for (std::list<shared_ptr<const Channel> >::const_iterator i = channels.begin();
-       i != channels.end(); ++i)
-    {
-      std::vector<shared_ptr<const Channel> >::iterator pos =
-        std::find(expectedChannels.begin(), expectedChannels.end(), *i);
-
-      BOOST_REQUIRE(pos != expectedChannels.end());
-      expectedChannels.erase(pos);
-    }
+  for (const auto& i : factory.getChannels()) {
+    auto pos = std::find(expectedChannels.begin(), expectedChannels.end(), i);
+    BOOST_REQUIRE(pos != expectedChannels.end());
+    expectedChannels.erase(pos);
+  }
 
   BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
 }
diff --git a/tests/daemon/face/websocket.t.cpp b/tests/daemon/face/websocket.t.cpp
index d3da744..a1d8a52 100644
--- a/tests/daemon/face/websocket.t.cpp
+++ b/tests/daemon/face/websocket.t.cpp
@@ -42,32 +42,26 @@
 
 BOOST_AUTO_TEST_CASE(GetChannels)
 {
-  WebSocketFactory factory("19596");
+  WebSocketFactory factory;
   BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
 
-  std::vector<shared_ptr<const Channel> > expectedChannels;
-
+  std::vector<shared_ptr<const Channel>> expectedChannels;
   expectedChannels.push_back(factory.createChannel("127.0.0.1", "20070"));
   expectedChannels.push_back(factory.createChannel("127.0.0.1", "20071"));
   expectedChannels.push_back(factory.createChannel("::1", "20071"));
 
-  std::list<shared_ptr<const Channel> > channels = factory.getChannels();
-  for (std::list<shared_ptr<const Channel> >::const_iterator i = channels.begin();
-       i != channels.end(); ++i)
-    {
-      std::vector<shared_ptr<const Channel> >::iterator pos =
-        std::find(expectedChannels.begin(), expectedChannels.end(), *i);
-
-      BOOST_REQUIRE(pos != expectedChannels.end());
-      expectedChannels.erase(pos);
-    }
+  for (const auto& i : factory.getChannels()) {
+    auto pos = std::find(expectedChannels.begin(), expectedChannels.end(), i);
+    BOOST_REQUIRE(pos != expectedChannels.end());
+    expectedChannels.erase(pos);
+  }
 
   BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
 }
 
 BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
 {
-  WebSocketFactory factory("19596");
+  WebSocketFactory factory;
 
   BOOST_CHECK_THROW(factory.createFace(FaceUri("ws://127.0.0.1:20070"),
                                        ndn::nfd::FACE_PERSISTENCY_PERMANENT,
@@ -226,7 +220,7 @@
 
 BOOST_FIXTURE_TEST_CASE(EndToEnd4, EndToEndFixture)
 {
-  WebSocketFactory factory1("9696");
+  WebSocketFactory factory1;
 
   shared_ptr<WebSocketChannel> channel1 = factory1.createChannel("127.0.0.1", "20070");
   channel1->setPingInterval(time::milliseconds(3000));
diff --git a/tests/daemon/mgmt/face-manager.t.cpp b/tests/daemon/mgmt/face-manager.t.cpp
index db24029..b8944b4 100644
--- a/tests/daemon/mgmt/face-manager.t.cpp
+++ b/tests/daemon/mgmt/face-manager.t.cpp
@@ -370,7 +370,7 @@
   BOOST_CHECK_NO_THROW(status.wireDecode(content.elements()[1]));
   BOOST_CHECK_EQUAL(face3->getId(), status.getFaceId());
 
-  ControlResponse expectedResponse(400, "malformed filter"); // nack, 400, malformed filter
+  ControlResponse expectedResponse(400, "Malformed filter"); // nack, 400, malformed filter
   BOOST_CHECK_EQUAL(checkResponse(3, invalidQueryName, expectedResponse, tlv::ContentType_Nack),
                     CheckResponseResult::OK);
 }
@@ -391,11 +391,11 @@
   createFace(const FaceUri& uri,
              ndn::nfd::FacePersistency persistency,
              const FaceCreatedCallback& onCreated,
-             const FaceConnectFailedCallback& onConnectFailed) DECL_OVERRIDE
+             const FaceCreationFailedCallback& onConnectFailed) DECL_OVERRIDE
   {
   }
 
-  virtual std::list<shared_ptr<const Channel>>
+  virtual std::vector<shared_ptr<const Channel>>
   getChannels() const DECL_OVERRIDE
   {
     return m_channels;
@@ -411,7 +411,7 @@
   }
 
 private:
-  std::list<shared_ptr<const Channel> > m_channels;
+  std::vector<shared_ptr<const Channel>> m_channels;
 };
 
 BOOST_AUTO_TEST_CASE(ChannelDataset)