diff --git a/NFD/AUTHORS.md b/NFD/AUTHORS.md
deleted file mode 100644
index 6538fcb..0000000
--- a/NFD/AUTHORS.md
+++ /dev/null
@@ -1,73 +0,0 @@
-NFD Authors
-===========
-
-NFD is an open source project started in late 2013, includes contributions
-from many people around the world, and open for new contributions from new
-volunteers.
-
-
-## Project technical leads:
-
-* Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
-* Junxiao Shi         <http://www.cs.arizona.edu/people/shijunxiao/>
-
-
-## Technical advisors:
-
-* Beichuan Zhang      <http://www.cs.arizona.edu/~bzhang/>
-* Lixia Zhang         <http://www.cs.ucla.edu/~lixia/>
-
-
-## Main project authors and their affiliations:
-
-* University of California, Los Angeles
-
-    * Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
-    * Ilya Moiseenko      <http://ilyamoiseenko.com/>
-    * Yingdi Yu           <http://irl.cs.ucla.edu/~yingdi/web/index.html>
-    * Wentao Shang        <http://irl.cs.ucla.edu/~wentao/>
-    * Lixia Zhang         <http://www.cs.ucla.edu/~lixia/>
-
-* The University of Arizona
-
-    * Junxiao Shi         <http://www.cs.arizona.edu/people/shijunxiao/>
-    * Yi Huang            <ethanhuang1991@gmail.com>
-    * Jerald Paul Abraham <http://www.cs.arizona.edu/people/jeraldabraham/>
-    * Beichuan Zhang      <http://www.cs.arizona.edu/~bzhang/>
-
-* Colorado State University
-
-    * Steve DiBenedetto     <http://www.cs.colostate.edu/~dibenede/>
-    * Chengyu Fan           <chengyu@cs.colostate.edu>
-    * Christos Papadopoulos <http://www.cs.colostate.edu/~christos/>
-
-* University Pierre & Marie Curie, Sorbonne University
-
-    * Davide Pesavento    <http://www.lip6.fr/actualite/personnes-fiche.php?ident=D1469>
-    * Giulio Grassi       <http://www.lip6.fr/actualite/personnes-fiche.php?ident=D1461>
-    * Giovanni Pau        <http://www.cs.ucla.edu/~gpau/Giovanni_Paus_Home_Page/Home.html>
-
-* Beijing Institute of Technology
-
-    * Hang Zhang          <http://netlab.bit.edu.cn/z_hang>
-    * Tian Song           <http://cs.bit.edu.cn/songtian>
-
-* Washington University in St. Louis
-
-    * Haowei Yuan         <http://www.cse.wustl.edu/~yuanh/>
-    * Hila Ben Abraham    <http://research.engineering.wustl.edu/~abrahamh/>
-    * Patrick Crowley     <http://www.arl.wustl.edu/~pcrowley/>
-
-* The University of Memphis
-
-    * Syed Obaid Amin     <http://obaidamin.weebly.com/>
-    * Vince Lehman        <vslehman@memphis.edu>
-    * Lan Wang            <http://www.cs.memphis.edu/~lanwang/>
-
-## Project contributors
-
-The following is an inevitably incomplete list of MUCH-APPRECIATED CONTRIBUTORS,
-people who have reported bugs, submitted patches, and implemented new features
-in the library:
-
-* Tai-Lin Chu             <https://www.linkedin.com/pub/tai-lin-chu/55/5b2/669>
diff --git a/NFD/COPYING.md b/NFD/COPYING.md
deleted file mode 100644
index d799430..0000000
--- a/NFD/COPYING.md
+++ /dev/null
@@ -1,677 +0,0 @@
-GNU GENERAL PUBLIC LICENSE
-==========================
-Version 3, 29 June 2007
-=======================
-
-> Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
-  Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
-
-# Preamble
-
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-# TERMS AND CONDITIONS
-
-## 0. Definitions.
-
-  _"This License"_ refers to version 3 of the GNU General Public License.
-
-  _"Copyright"_ also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  _"The Program"_ refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as _"you"_.  _"Licensees"_ and
-"recipients" may be individuals or organizations.
-
-  To _"modify"_ a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a _"modified version"_ of the
-earlier work or a work _"based on"_ the earlier work.
-
-  A _"covered work"_ means either the unmodified Program or a work based
-on the Program.
-
-  To _"propagate"_ a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To _"convey"_ a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-## 1. Source Code.
-
-  The _"source code"_ for a work means the preferred form of the work
-for making modifications to it. _"Object code"_ means any non-source
-form of a work.
-
-  A _"Standard Interface"_ means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The _"System Libraries"_ of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The _"Corresponding Source"_ for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-## 2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-## 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-## 4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-## 5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-## 6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A _"User Product"_ is either (1) a _"consumer product"_, which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  _"Installation Information"_ for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-## 7. Additional Terms.
-
-  _"Additional permissions"_ are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-## 8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-## 9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-## 10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An _"entity transaction"_ is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-## 11. Patents.
-
-  A _"contributor"_ is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's _"essential patent claims"_ are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-## 12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-## 13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-## 14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-## 15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-## 16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-## 17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-# END OF TERMS AND CONDITIONS
---------------------------------------------------------------------------
-
-
-# How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    <program>  Copyright (C) <year>  <name of author>
-    This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type 'show c' for details.
-
-  The hypothetical commands _'show w'_ and _'show c'_ should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/NFD/README.md b/NFD/README.md
deleted file mode 100644
index 40af61e..0000000
--- a/NFD/README.md
+++ /dev/null
@@ -1,29 +0,0 @@
-NFD - Named Data Networking Forwarding Daemon
-=============================================
-
-Files in this directory are imported from NFD (Named Data Networking Forwarding Daemon)
-project (http://named-data.net/doc/NFD/).
-
-The codebase can be merged with the upstream with the following command:
-
-    git subtree pull --prefix=NFD https://github.com/named-data/NFD master
-
-There are several ndnSIM-specific changes to NFD codebase and manual conflict resolution
-may be required.
-
-Changes in NFD codebase
------------------------
-
-The following commits introduced changes to NFD codebase:
-
-- `e98f2e8` NFD: Removing parts irrelevant for the simulator
-- `7245d5d` NFD: Adding readme and auto-generated headers
-- `dc88971` NFD: Disabling all "standard" face types in Face manager
-- `0fb253e` NFD: Enable metric parameter on a face
-- `1de5da6` NFD: Redirecting nfd::scheduler to ns3::Simulator and getting rid of GlobalIo
-- `dbc7794` NFD: Replace NFD logger with NS3 logging facility
-- `de1f773` NFD: Keep both the CS of NFD and ndnSIM
-- `542a623` NFD: Extending ConfigFile to support passing of a parsed ConfigSection instead of
-  raw config file
-- `9bcf39e` NFD: Extend forwarding pipelines with beforeSatisfyInterest and
-  beforeExpirePendingInterest signals
diff --git a/NFD/common.hpp b/NFD/common.hpp
deleted file mode 100644
index 8316184..0000000
--- a/NFD/common.hpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_COMMON_HPP
-#define NFD_COMMON_HPP
-
-#include "config.hpp"
-
-#ifdef WITH_TESTS
-#define VIRTUAL_WITH_TESTS virtual
-#define PUBLIC_WITH_TESTS_ELSE_PROTECTED public
-#define PUBLIC_WITH_TESTS_ELSE_PRIVATE public
-#define PROTECTED_WITH_TESTS_ELSE_PRIVATE protected
-#else
-#define VIRTUAL_WITH_TESTS
-#define PUBLIC_WITH_TESTS_ELSE_PROTECTED protected
-#define PUBLIC_WITH_TESTS_ELSE_PRIVATE private
-#define PROTECTED_WITH_TESTS_ELSE_PRIVATE private
-#endif
-
-/** \def DECL_OVERRIDE
- *  \brief expands to 'override' if compiler supports this feature, otherwise expands to nothing
- */
-#ifdef HAVE_CXX_OVERRIDE
-#define DECL_OVERRIDE override
-#else
-#define DECL_OVERRIDE
-#endif
-
-#include <cstddef>
-#include <list>
-#include <set>
-#include <queue>
-#include <vector>
-
-#include <ndn-cxx/common.hpp>
-#include <ndn-cxx/interest.hpp>
-#include <ndn-cxx/data.hpp>
-#include <ndn-cxx/util/event-emitter.hpp> // deprecated
-#include <ndn-cxx/util/signal.hpp>
-
-#include <boost/algorithm/string.hpp>
-#include <boost/asio.hpp>
-#include <boost/assert.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/noncopyable.hpp>
-#include <boost/property_tree/ptree.hpp>
-
-namespace nfd {
-
-using std::size_t;
-
-using boost::noncopyable;
-
-using std::shared_ptr;
-using std::unique_ptr;
-using std::weak_ptr;
-using std::bad_weak_ptr;
-using std::make_shared;
-using std::enable_shared_from_this;
-
-using std::static_pointer_cast;
-using std::dynamic_pointer_cast;
-using std::const_pointer_cast;
-
-using std::function;
-using std::bind;
-using std::ref;
-using std::cref;
-
-using ndn::Interest;
-using ndn::Data;
-using ndn::Name;
-using ndn::Exclude;
-using ndn::Block;
-using ndn::util::EventEmitter; // deprecated
-
-namespace tlv {
-// Don't write "namespace tlv = ndn::tlv", because NFD can add other members into this namespace.
-using namespace ndn::tlv;
-} // namespace tlv
-
-namespace name = ndn::name;
-namespace time = ndn::time;
-namespace signal = ndn::util::signal;
-
-} // namespace nfd
-
-#endif // NFD_COMMON_HPP
diff --git a/NFD/config.hpp b/NFD/config.hpp
deleted file mode 100644
index 2aca644..0000000
--- a/NFD/config.hpp
+++ /dev/null
@@ -1,6 +0,0 @@
-/* WARNING! All changes made to this file will be lost! */
-
-#ifndef W_CONFIG_HPP_WAF
-#define W_CONFIG_HPP_WAF
-
-#endif /* W_CONFIG_HPP_WAF */
diff --git a/NFD/core/city-hash.cpp b/NFD/core/city-hash.cpp
deleted file mode 100644
index b8a7791..0000000
--- a/NFD/core/city-hash.cpp
+++ /dev/null
@@ -1,650 +0,0 @@
-// Copyright (c) 2011 Google, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-// CityHash, by Geoff Pike and Jyrki Alakuijala
-//
-// This file provides CityHash64() and related functions.
-//
-// It's probably possible to create even faster hash functions by
-// writing a program that systematically explores some of the space of
-// possible hash functions, by using SIMD instructions, or by
-// compromising on hash quality.
-
-//#include "config.h"
-#include "city-hash.hpp"
-#include <algorithm>
-#include <string.h>  // for memcpy and memset
-
-using namespace std;
-
-
-static uint64 UNALIGNED_LOAD64(const char *p) {
-  uint64 result;
-  memcpy(&result, p, sizeof(result));
-  return result;
-}
-
-static uint32 UNALIGNED_LOAD32(const char *p) {
-  uint32 result;
-  memcpy(&result, p, sizeof(result));
-  return result;
-}
-
-#ifdef _MSC_VER
-
-#include <stdlib.h>
-#define bswap_32(x) _byteswap_ulong(x)
-#define bswap_64(x) _byteswap_uint64(x)
-
-#elif defined(__APPLE__)
-
-// Mac OS X / Darwin features
-#include <libkern/OSByteOrder.h>
-#define bswap_32(x) OSSwapInt32(x)
-#define bswap_64(x) OSSwapInt64(x)
-
-#elif defined(__NetBSD__)
-
-#include <sys/types.h>
-#include <machine/bswap.h>
-#if defined(__BSWAP_RENAME) && !defined(__bswap_32)
-#define bswap_32(x) bswap32(x)
-#define bswap_64(x) bswap64(x)
-#endif
-
-
-#elif defined(__FreeBSD__)
-
-// Based on https://code.google.com/p/freebsd/source/browse/sys/ofed/include/byteswap.h?spec=svn38a8350a629d959c8c5509221cd07ffb891b5a77&r=38a8350a629d959c8c5509221cd07ffb891b5a77
-
-#include <sys/types.h>
-#include <sys/endian.h>
-#define bswap_16(x) bswap16(x)
-#define bswap_32(x) bswap32(x)
-#define bswap_64(x) bswap64(x)
-
-#else
-
-#include <byteswap.h>
-
-#endif
-
-#ifdef WORDS_BIGENDIAN
-#define uint32_in_expected_order(x) (bswap_32(x))
-#define uint64_in_expected_order(x) (bswap_64(x))
-#else
-#define uint32_in_expected_order(x) (x)
-#define uint64_in_expected_order(x) (x)
-#endif
-
-#if !defined(LIKELY)
-#if HAVE_BUILTIN_EXPECT
-#define LIKELY(x) (__builtin_expect(!!(x), 1))
-#else
-#define LIKELY(x) (x)
-#endif
-#endif
-
-static uint64 Fetch64(const char *p) {
-  return uint64_in_expected_order(UNALIGNED_LOAD64(p));
-}
-
-static uint32 Fetch32(const char *p) {
-  return uint32_in_expected_order(UNALIGNED_LOAD32(p));
-}
-
-// Some primes between 2^63 and 2^64 for various uses.
-static const uint64 k0 = 0xc3a5c85c97cb3127ULL;
-static const uint64 k1 = 0xb492b66fbe98f273ULL;
-static const uint64 k2 = 0x9ae16a3b2f90404fULL;
-
-// Magic numbers for 32-bit hashing.  Copied from Murmur3.
-static const uint32_t c1 = 0xcc9e2d51;
-static const uint32_t c2 = 0x1b873593;
-
-// A 32-bit to 32-bit integer hash copied from Murmur3.
-static uint32 fmix(uint32 h)
-{
-  h ^= h >> 16;
-  h *= 0x85ebca6b;
-  h ^= h >> 13;
-  h *= 0xc2b2ae35;
-  h ^= h >> 16;
-  return h;
-}
-
-static uint32 Rotate32(uint32 val, int shift) {
-  // Avoid shifting by 32: doing so yields an undefined result.
-  return shift == 0 ? val : ((val >> shift) | (val << (32 - shift)));
-}
-
-#undef PERMUTE3
-#define PERMUTE3(a, b, c) do { std::swap(a, b); std::swap(a, c); } while (0)
-
-static uint32 Mur(uint32 a, uint32 h) {
-  // Helper from Murmur3 for combining two 32-bit values.
-  a *= c1;
-  a = Rotate32(a, 17);
-  a *= c2;
-  h ^= a;
-  h = Rotate32(h, 19);
-  return h * 5 + 0xe6546b64;
-}
-
-static uint32 Hash32Len13to24(const char *s, size_t len) {
-  uint32 a = Fetch32(s - 4 + (len >> 1));
-  uint32 b = Fetch32(s + 4);
-  uint32 c = Fetch32(s + len - 8);
-  uint32 d = Fetch32(s + (len >> 1));
-  uint32 e = Fetch32(s);
-  uint32 f = Fetch32(s + len - 4);
-  uint32 h = len;
-
-  return fmix(Mur(f, Mur(e, Mur(d, Mur(c, Mur(b, Mur(a, h)))))));
-}
-
-static uint32 Hash32Len0to4(const char *s, size_t len) {
-  uint32 b = 0;
-  uint32 c = 9;
-  for (size_t i = 0; i < len; i++) {
-    signed char v = s[i];
-    b = b * c1 + v;
-    c ^= b;
-  }
-  return fmix(Mur(b, Mur(len, c)));
-}
-
-static uint32 Hash32Len5to12(const char *s, size_t len) {
-  uint32 a = len, b = len * 5, c = 9, d = b;
-  a += Fetch32(s);
-  b += Fetch32(s + len - 4);
-  c += Fetch32(s + ((len >> 1) & 4));
-  return fmix(Mur(c, Mur(b, Mur(a, d))));
-}
-
-uint32 CityHash32(const char *s, size_t len) {
-  if (len <= 24) {
-    return len <= 12 ?
-        (len <= 4 ? Hash32Len0to4(s, len) : Hash32Len5to12(s, len)) :
-        Hash32Len13to24(s, len);
-  }
-
-  // len > 24
-  uint32 h = len, g = c1 * len, f = g;
-  uint32 a0 = Rotate32(Fetch32(s + len - 4) * c1, 17) * c2;
-  uint32 a1 = Rotate32(Fetch32(s + len - 8) * c1, 17) * c2;
-  uint32 a2 = Rotate32(Fetch32(s + len - 16) * c1, 17) * c2;
-  uint32 a3 = Rotate32(Fetch32(s + len - 12) * c1, 17) * c2;
-  uint32 a4 = Rotate32(Fetch32(s + len - 20) * c1, 17) * c2;
-  h ^= a0;
-  h = Rotate32(h, 19);
-  h = h * 5 + 0xe6546b64;
-  h ^= a2;
-  h = Rotate32(h, 19);
-  h = h * 5 + 0xe6546b64;
-  g ^= a1;
-  g = Rotate32(g, 19);
-  g = g * 5 + 0xe6546b64;
-  g ^= a3;
-  g = Rotate32(g, 19);
-  g = g * 5 + 0xe6546b64;
-  f += a4;
-  f = Rotate32(f, 19);
-  f = f * 5 + 0xe6546b64;
-  size_t iters = (len - 1) / 20;
-  do {
-    uint32 a0 = Rotate32(Fetch32(s) * c1, 17) * c2;
-    uint32 a1 = Fetch32(s + 4);
-    uint32 a2 = Rotate32(Fetch32(s + 8) * c1, 17) * c2;
-    uint32 a3 = Rotate32(Fetch32(s + 12) * c1, 17) * c2;
-    uint32 a4 = Fetch32(s + 16);
-    h ^= a0;
-    h = Rotate32(h, 18);
-    h = h * 5 + 0xe6546b64;
-    f += a1;
-    f = Rotate32(f, 19);
-    f = f * c1;
-    g += a2;
-    g = Rotate32(g, 18);
-    g = g * 5 + 0xe6546b64;
-    h ^= a3 + a1;
-    h = Rotate32(h, 19);
-    h = h * 5 + 0xe6546b64;
-    g ^= a4;
-    g = bswap_32(g) * 5;
-    h += a4 * 5;
-    h = bswap_32(h);
-    f += a0;
-    PERMUTE3(f, h, g);
-    s += 20;
-  } while (--iters != 0);
-  g = Rotate32(g, 11) * c1;
-  g = Rotate32(g, 17) * c1;
-  f = Rotate32(f, 11) * c1;
-  f = Rotate32(f, 17) * c1;
-  h = Rotate32(h + g, 19);
-  h = h * 5 + 0xe6546b64;
-  h = Rotate32(h, 17) * c1;
-  h = Rotate32(h + f, 19);
-  h = h * 5 + 0xe6546b64;
-  h = Rotate32(h, 17) * c1;
-  return h;
-}
-
-// Bitwise right rotate.  Normally this will compile to a single
-// instruction, especially if the shift is a manifest constant.
-static uint64 Rotate(uint64 val, int shift) {
-  // Avoid shifting by 64: doing so yields an undefined result.
-  return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
-}
-
-static uint64 ShiftMix(uint64 val) {
-  return val ^ (val >> 47);
-}
-
-static uint64 HashLen16(uint64 u, uint64 v) {
-  return Hash128to64(uint128(u, v));
-}
-
-static uint64 HashLen16(uint64 u, uint64 v, uint64 mul) {
-  // Murmur-inspired hashing.
-  uint64 a = (u ^ v) * mul;
-  a ^= (a >> 47);
-  uint64 b = (v ^ a) * mul;
-  b ^= (b >> 47);
-  b *= mul;
-  return b;
-}
-
-static uint64 HashLen0to16(const char *s, size_t len) {
-  if (len >= 8) {
-    uint64 mul = k2 + len * 2;
-    uint64 a = Fetch64(s) + k2;
-    uint64 b = Fetch64(s + len - 8);
-    uint64 c = Rotate(b, 37) * mul + a;
-    uint64 d = (Rotate(a, 25) + b) * mul;
-    return HashLen16(c, d, mul);
-  }
-  if (len >= 4) {
-    uint64 mul = k2 + len * 2;
-    uint64 a = Fetch32(s);
-    return HashLen16(len + (a << 3), Fetch32(s + len - 4), mul);
-  }
-  if (len > 0) {
-    uint8 a = s[0];
-    uint8 b = s[len >> 1];
-    uint8 c = s[len - 1];
-    uint32 y = static_cast<uint32>(a) + (static_cast<uint32>(b) << 8);
-    uint32 z = len + (static_cast<uint32>(c) << 2);
-    return ShiftMix(y * k2 ^ z * k0) * k2;
-  }
-  return k2;
-}
-
-// This probably works well for 16-byte strings as well, but it may be overkill
-// in that case.
-static uint64 HashLen17to32(const char *s, size_t len) {
-  uint64 mul = k2 + len * 2;
-  uint64 a = Fetch64(s) * k1;
-  uint64 b = Fetch64(s + 8);
-  uint64 c = Fetch64(s + len - 8) * mul;
-  uint64 d = Fetch64(s + len - 16) * k2;
-  return HashLen16(Rotate(a + b, 43) + Rotate(c, 30) + d,
-                   a + Rotate(b + k2, 18) + c, mul);
-}
-
-// Return a 16-byte hash for 48 bytes.  Quick and dirty.
-// Callers do best to use "random-looking" values for a and b.
-static pair<uint64, uint64> WeakHashLen32WithSeeds(
-    uint64 w, uint64 x, uint64 y, uint64 z, uint64 a, uint64 b) {
-  a += w;
-  b = Rotate(b + a + z, 21);
-  uint64 c = a;
-  a += x;
-  a += y;
-  b += Rotate(a, 44);
-  return make_pair(a + z, b + c);
-}
-
-// Return a 16-byte hash for s[0] ... s[31], a, and b.  Quick and dirty.
-static pair<uint64, uint64> WeakHashLen32WithSeeds(
-    const char* s, uint64 a, uint64 b) {
-  return WeakHashLen32WithSeeds(Fetch64(s),
-                                Fetch64(s + 8),
-                                Fetch64(s + 16),
-                                Fetch64(s + 24),
-                                a,
-                                b);
-}
-
-// Return an 8-byte hash for 33 to 64 bytes.
-static uint64 HashLen33to64(const char *s, size_t len) {
-  uint64 mul = k2 + len * 2;
-  uint64 a = Fetch64(s) * k2;
-  uint64 b = Fetch64(s + 8);
-  uint64 c = Fetch64(s + len - 24);
-  uint64 d = Fetch64(s + len - 32);
-  uint64 e = Fetch64(s + 16) * k2;
-  uint64 f = Fetch64(s + 24) * 9;
-  uint64 g = Fetch64(s + len - 8);
-  uint64 h = Fetch64(s + len - 16) * mul;
-  uint64 u = Rotate(a + g, 43) + (Rotate(b, 30) + c) * 9;
-  uint64 v = ((a + g) ^ d) + f + 1;
-  uint64 w = bswap_64((u + v) * mul) + h;
-  uint64 x = Rotate(e + f, 42) + c;
-  uint64 y = (bswap_64((v + w) * mul) + g) * mul;
-  uint64 z = e + f + c;
-  a = bswap_64((x + z) * mul + y) + b;
-  b = ShiftMix((z + a) * mul + d + h) * mul;
-  return b + x;
-}
-
-uint64 CityHash64(const char *s, size_t len) {
-  if (len <= 32) {
-    if (len <= 16) {
-      return HashLen0to16(s, len);
-    } else {
-      return HashLen17to32(s, len);
-    }
-  } else if (len <= 64) {
-    return HashLen33to64(s, len);
-  }
-
-  // For strings over 64 bytes we hash the end first, and then as we
-  // loop we keep 56 bytes of state: v, w, x, y, and z.
-  uint64 x = Fetch64(s + len - 40);
-  uint64 y = Fetch64(s + len - 16) + Fetch64(s + len - 56);
-  uint64 z = HashLen16(Fetch64(s + len - 48) + len, Fetch64(s + len - 24));
-  pair<uint64, uint64> v = WeakHashLen32WithSeeds(s + len - 64, len, z);
-  pair<uint64, uint64> w = WeakHashLen32WithSeeds(s + len - 32, y + k1, x);
-  x = x * k1 + Fetch64(s);
-
-  // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
-  len = (len - 1) & ~static_cast<size_t>(63);
-  do {
-    x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
-    y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
-    x ^= w.second;
-    y += v.first + Fetch64(s + 40);
-    z = Rotate(z + w.first, 33) * k1;
-    v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
-    w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16));
-    std::swap(z, x);
-    s += 64;
-    len -= 64;
-  } while (len != 0);
-  return HashLen16(HashLen16(v.first, w.first) + ShiftMix(y) * k1 + z,
-                   HashLen16(v.second, w.second) + x);
-}
-
-uint64 CityHash64WithSeed(const char *s, size_t len, uint64 seed) {
-  return CityHash64WithSeeds(s, len, k2, seed);
-}
-
-uint64 CityHash64WithSeeds(const char *s, size_t len,
-                           uint64 seed0, uint64 seed1) {
-  return HashLen16(CityHash64(s, len) - seed0, seed1);
-}
-
-// A subroutine for CityHash128().  Returns a decent 128-bit hash for strings
-// of any length representable in signed long.  Based on City and Murmur.
-static uint128 CityMurmur(const char *s, size_t len, uint128 seed) {
-  uint64 a = Uint128Low64(seed);
-  uint64 b = Uint128High64(seed);
-  uint64 c = 0;
-  uint64 d = 0;
-  signed long l = len - 16;
-  if (l <= 0) {  // len <= 16
-    a = ShiftMix(a * k1) * k1;
-    c = b * k1 + HashLen0to16(s, len);
-    d = ShiftMix(a + (len >= 8 ? Fetch64(s) : c));
-  } else {  // len > 16
-    c = HashLen16(Fetch64(s + len - 8) + k1, a);
-    d = HashLen16(b + len, c + Fetch64(s + len - 16));
-    a += d;
-    do {
-      a ^= ShiftMix(Fetch64(s) * k1) * k1;
-      a *= k1;
-      b ^= a;
-      c ^= ShiftMix(Fetch64(s + 8) * k1) * k1;
-      c *= k1;
-      d ^= c;
-      s += 16;
-      l -= 16;
-    } while (l > 0);
-  }
-  a = HashLen16(a, c);
-  b = HashLen16(d, b);
-  return uint128(a ^ b, HashLen16(b, a));
-}
-
-uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed) {
-  if (len < 128) {
-    return CityMurmur(s, len, seed);
-  }
-
-  // We expect len >= 128 to be the common case.  Keep 56 bytes of state:
-  // v, w, x, y, and z.
-  pair<uint64, uint64> v, w;
-  uint64 x = Uint128Low64(seed);
-  uint64 y = Uint128High64(seed);
-  uint64 z = len * k1;
-  v.first = Rotate(y ^ k1, 49) * k1 + Fetch64(s);
-  v.second = Rotate(v.first, 42) * k1 + Fetch64(s + 8);
-  w.first = Rotate(y + z, 35) * k1 + x;
-  w.second = Rotate(x + Fetch64(s + 88), 53) * k1;
-
-  // This is the same inner loop as CityHash64(), manually unrolled.
-  do {
-    x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
-    y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
-    x ^= w.second;
-    y += v.first + Fetch64(s + 40);
-    z = Rotate(z + w.first, 33) * k1;
-    v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
-    w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16));
-    std::swap(z, x);
-    s += 64;
-    x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
-    y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
-    x ^= w.second;
-    y += v.first + Fetch64(s + 40);
-    z = Rotate(z + w.first, 33) * k1;
-    v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
-    w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16));
-    std::swap(z, x);
-    s += 64;
-    len -= 128;
-  } while (LIKELY(len >= 128));
-  x += Rotate(v.first + z, 49) * k0;
-  y = y * k0 + Rotate(w.second, 37);
-  z = z * k0 + Rotate(w.first, 27);
-  w.first *= 9;
-  v.first *= k0;
-  // If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s.
-  for (size_t tail_done = 0; tail_done < len; ) {
-    tail_done += 32;
-    y = Rotate(x + y, 42) * k0 + v.second;
-    w.first += Fetch64(s + len - tail_done + 16);
-    x = x * k0 + w.first;
-    z += w.second + Fetch64(s + len - tail_done);
-    w.second += v.first;
-    v = WeakHashLen32WithSeeds(s + len - tail_done, v.first + z, v.second);
-    v.first *= k0;
-  }
-  // At this point our 56 bytes of state should contain more than
-  // enough information for a strong 128-bit hash.  We use two
-  // different 56-byte-to-8-byte hashes to get a 16-byte final result.
-  x = HashLen16(x, v.first);
-  y = HashLen16(y + z, w.first);
-  return uint128(HashLen16(x + v.second, w.second) + y,
-                 HashLen16(x + w.second, y + v.second));
-}
-
-uint128 CityHash128(const char *s, size_t len) {
-  return len >= 16 ?
-      CityHash128WithSeed(s + 16, len - 16,
-                          uint128(Fetch64(s), Fetch64(s + 8) + k0)) :
-      CityHash128WithSeed(s, len, uint128(k0, k1));
-}
-
-// NFD NOTE
-// The following code block is commented out due to the following reasons.
-// - It requires the "citycrc.h" header file, which is not included in the
-//   NFD code base.
-// - The functions defined below are not used by the current NFD
-//   implementation.
-// The header file "citycrc.h" is available at
-// https://code.google.com/p/cityhash/source/browse/trunk/src/citycrc.h
-
-/*
-#ifdef __SSE4_2__
-#include <citycrc.h>
-#include <nmmintrin.h>
-
-// Requires len >= 240.
-static void CityHashCrc256Long(const char *s, size_t len,
-                               uint32 seed, uint64 *result) {
-  uint64 a = Fetch64(s + 56) + k0;
-  uint64 b = Fetch64(s + 96) + k0;
-  uint64 c = result[0] = HashLen16(b, len);
-  uint64 d = result[1] = Fetch64(s + 120) * k0 + len;
-  uint64 e = Fetch64(s + 184) + seed;
-  uint64 f = 0;
-  uint64 g = 0;
-  uint64 h = c + d;
-  uint64 x = seed;
-  uint64 y = 0;
-  uint64 z = 0;
-
-  // 240 bytes of input per iter.
-  size_t iters = len / 240;
-  len -= iters * 240;
-  do {
-#undef CHUNK
-#define CHUNK(r)                                \
-    PERMUTE3(x, z, y);                          \
-    b += Fetch64(s);                            \
-    c += Fetch64(s + 8);                        \
-    d += Fetch64(s + 16);                       \
-    e += Fetch64(s + 24);                       \
-    f += Fetch64(s + 32);                       \
-    a += b;                                     \
-    h += f;                                     \
-    b += c;                                     \
-    f += d;                                     \
-    g += e;                                     \
-    e += z;                                     \
-    g += x;                                     \
-    z = _mm_crc32_u64(z, b + g);                \
-    y = _mm_crc32_u64(y, e + h);                \
-    x = _mm_crc32_u64(x, f + a);                \
-    e = Rotate(e, r);                           \
-    c += e;                                     \
-    s += 40
-
-    CHUNK(0); PERMUTE3(a, h, c);
-    CHUNK(33); PERMUTE3(a, h, f);
-    CHUNK(0); PERMUTE3(b, h, f);
-    CHUNK(42); PERMUTE3(b, h, d);
-    CHUNK(0); PERMUTE3(b, h, e);
-    CHUNK(33); PERMUTE3(a, h, e);
-  } while (--iters > 0);
-
-  while (len >= 40) {
-    CHUNK(29);
-    e ^= Rotate(a, 20);
-    h += Rotate(b, 30);
-    g ^= Rotate(c, 40);
-    f += Rotate(d, 34);
-    PERMUTE3(c, h, g);
-    len -= 40;
-  }
-  if (len > 0) {
-    s = s + len - 40;
-    CHUNK(33);
-    e ^= Rotate(a, 43);
-    h += Rotate(b, 42);
-    g ^= Rotate(c, 41);
-    f += Rotate(d, 40);
-  }
-  result[0] ^= h;
-  result[1] ^= g;
-  g += h;
-  a = HashLen16(a, g + z);
-  x += y << 32;
-  b += x;
-  c = HashLen16(c, z) + h;
-  d = HashLen16(d, e + result[0]);
-  g += e;
-  h += HashLen16(x, f);
-  e = HashLen16(a, d) + g;
-  z = HashLen16(b, c) + a;
-  y = HashLen16(g, h) + c;
-  result[0] = e + z + y + x;
-  a = ShiftMix((a + y) * k0) * k0 + b;
-  result[1] += a + result[0];
-  a = ShiftMix(a * k0) * k0 + c;
-  result[2] = a + result[1];
-  a = ShiftMix((a + e) * k0) * k0;
-  result[3] = a + result[2];
-}
-
-// Requires len < 240.
-static void CityHashCrc256Short(const char *s, size_t len, uint64 *result) {
-  char buf[240];
-  memcpy(buf, s, len);
-  memset(buf + len, 0, 240 - len);
-  CityHashCrc256Long(buf, 240, ~static_cast<uint32>(len), result);
-}
-
-void CityHashCrc256(const char *s, size_t len, uint64 *result) {
-  if (LIKELY(len >= 240)) {
-    CityHashCrc256Long(s, len, 0, result);
-  } else {
-    CityHashCrc256Short(s, len, result);
-  }
-}
-
-uint128 CityHashCrc128WithSeed(const char *s, size_t len, uint128 seed) {
-  if (len <= 900) {
-    return CityHash128WithSeed(s, len, seed);
-  } else {
-    uint64 result[4];
-    CityHashCrc256(s, len, result);
-    uint64 u = Uint128High64(seed) + result[0];
-    uint64 v = Uint128Low64(seed) + result[1];
-    return uint128(HashLen16(u, v + result[2]),
-                   HashLen16(Rotate(v, 32), u * k0 + result[3]));
-  }
-}
-
-uint128 CityHashCrc128(const char *s, size_t len) {
-  if (len <= 900) {
-    return CityHash128(s, len);
-  } else {
-    uint64 result[4];
-    CityHashCrc256(s, len, result);
-    return uint128(result[2], result[3]);
-  }
-}
-
-#endif
-*/
diff --git a/NFD/core/city-hash.hpp b/NFD/core/city-hash.hpp
deleted file mode 100644
index 54a90cb..0000000
--- a/NFD/core/city-hash.hpp
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2011 Google, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-// CityHash, by Geoff Pike and Jyrki Alakuijala
-//
-// http://code.google.com/p/cityhash/
-//
-// This file provides a few functions for hashing strings.  All of them are
-// high-quality functions in the sense that they pass standard tests such
-// as Austin Appleby's SMHasher.  They are also fast.
-//
-// For 64-bit x86 code, on short strings, we don't know of anything faster than
-// CityHash64 that is of comparable quality.  We believe our nearest competitor
-// is Murmur3.  For 64-bit x86 code, CityHash64 is an excellent choice for hash
-// tables and most other hashing (excluding cryptography).
-//
-// For 64-bit x86 code, on long strings, the picture is more complicated.
-// On many recent Intel CPUs, such as Nehalem, Westmere, Sandy Bridge, etc.,
-// CityHashCrc128 appears to be faster than all competitors of comparable
-// quality.  CityHash128 is also good but not quite as fast.  We believe our
-// nearest competitor is Bob Jenkins' Spooky.  We don't have great data for
-// other 64-bit CPUs, but for long strings we know that Spooky is slightly
-// faster than CityHash on some relatively recent AMD x86-64 CPUs, for example.
-// Note that CityHashCrc128 is declared in citycrc.h.
-//
-// For 32-bit x86 code, we don't know of anything faster than CityHash32 that
-// is of comparable quality.  We believe our nearest competitor is Murmur3A.
-// (On 64-bit CPUs, it is typically faster to use the other CityHash variants.)
-//
-// Functions in the CityHash family are not suitable for cryptography.
-//
-// Please see CityHash's README file for more details on our performance
-// measurements and so on.
-//
-// WARNING: This code has been only lightly tested on big-endian platforms!
-// It is known to work well on little-endian platforms that have a small penalty
-// for unaligned reads, such as current Intel and AMD moderate-to-high-end CPUs.
-// It should work on all 32-bit and 64-bit platforms that allow unaligned reads;
-// bug reports are welcome.
-//
-// By the way, for some hash functions, given strings a and b, the hash
-// of a+b is easily derived from the hashes of a and b.  This property
-// doesn't hold for any hash functions in this file.
-
-#ifndef CITY_HASH_HPP
-#define CITY_HASH_HPP
-
-#include <stdlib.h>  // for size_t.
-#include <stdint.h>
-#include <utility>
-
-typedef uint8_t uint8;
-typedef uint32_t uint32;
-typedef uint64_t uint64;
-typedef std::pair<uint64, uint64> uint128;
-
-inline uint64 Uint128Low64(const uint128& x) { return x.first; }
-inline uint64 Uint128High64(const uint128& x) { return x.second; }
-
-// Hash function for a byte array.
-uint64 CityHash64(const char *buf, size_t len);
-
-// Hash function for a byte array.  For convenience, a 64-bit seed is also
-// hashed into the result.
-uint64 CityHash64WithSeed(const char *buf, size_t len, uint64 seed);
-
-// Hash function for a byte array.  For convenience, two seeds are also
-// hashed into the result.
-uint64 CityHash64WithSeeds(const char *buf, size_t len,
-                           uint64 seed0, uint64 seed1);
-
-// Hash function for a byte array.
-uint128 CityHash128(const char *s, size_t len);
-
-// Hash function for a byte array.  For convenience, a 128-bit seed is also
-// hashed into the result.
-uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed);
-
-// Hash function for a byte array.  Most useful in 32-bit binaries.
-uint32 CityHash32(const char *buf, size_t len);
-
-// Hash 128 input bits down to 64 bits of output.
-// This is intended to be a reasonably good hash function.
-inline uint64 Hash128to64(const uint128& x) {
-  // Murmur-inspired hashing.
-  const uint64 kMul = 0x9ddfea08eb382d69ULL;
-  uint64 a = (Uint128Low64(x) ^ Uint128High64(x)) * kMul;
-  a ^= (a >> 47);
-  uint64 b = (Uint128High64(x) ^ a) * kMul;
-  b ^= (b >> 47);
-  b *= kMul;
-  return b;
-}
-
-#endif  // CITY_HASH_H_
diff --git a/NFD/core/config-file.cpp b/NFD/core/config-file.cpp
deleted file mode 100644
index 1079666..0000000
--- a/NFD/core/config-file.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "config-file.hpp"
-#include "logger.hpp"
-
-#include <boost/property_tree/info_parser.hpp>
-#include <fstream>
-
-namespace nfd {
-
-NFD_LOG_INIT("ConfigFile");
-
-void
-ConfigFile::throwErrorOnUnknownSection(const std::string& filename,
-                                       const std::string& sectionName,
-                                       const ConfigSection& section,
-                                       bool isDryRun)
-{
-  std::string msg = "Error processing configuration file ";
-  msg += filename;
-  msg += ": no module subscribed for section \"" + sectionName + "\"";
-
-  throw ConfigFile::Error(msg);
-}
-
-void
-ConfigFile::ignoreUnknownSection(const std::string& filename,
-                                 const std::string& sectionName,
-                                 const ConfigSection& section,
-                                 bool isDryRun)
-{
-  // do nothing
-}
-
-ConfigFile::ConfigFile(UnknownConfigSectionHandler unknownSectionCallback)
-  : m_unknownSectionCallback(unknownSectionCallback)
-{
-}
-
-void
-ConfigFile::addSectionHandler(const std::string& sectionName,
-                              ConfigSectionHandler subscriber)
-{
-  m_subscriptions[sectionName] = subscriber;
-}
-
-void
-ConfigFile::parse(const std::string& filename, bool isDryRun)
-{
-  std::ifstream inputFile;
-  inputFile.open(filename.c_str());
-  if (!inputFile.good() || !inputFile.is_open())
-    {
-      std::string msg = "Failed to read configuration file: ";
-      msg += filename;
-      throw Error(msg);
-    }
-  parse(inputFile, isDryRun, filename);
-  inputFile.close();
-}
-
-void
-ConfigFile::parse(const std::string& input, bool isDryRun, const std::string& filename)
-{
-  std::istringstream inputStream(input);
-  parse(inputStream, isDryRun, filename);
-}
-
-
-void
-ConfigFile::parse(std::istream& input, bool isDryRun, const std::string& filename)
-{
-  try
-    {
-      boost::property_tree::read_info(input, m_global);
-    }
-  catch (const boost::property_tree::info_parser_error& error)
-    {
-      std::stringstream msg;
-      msg << "Failed to parse configuration file";
-      msg << " " << filename;
-      msg << " " << error.message() << " line " << error.line();
-      throw Error(msg.str());
-    }
-
-  process(isDryRun, filename);
-}
-
-void
-ConfigFile::parse(const ConfigSection& config, bool isDryRun, const std::string& filename)
-{
-  m_global = config;
-  process(isDryRun, filename);
-}
-
-void
-ConfigFile::process(bool isDryRun, const std::string& filename)
-{
-  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";
-      throw Error(msg);
-    }
-
-  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);
-        }
-    }
-}
-
-}
diff --git a/NFD/core/config-file.hpp b/NFD/core/config-file.hpp
deleted file mode 100644
index 6e974dd..0000000
--- a/NFD/core/config-file.hpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * 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
-
-#include "common.hpp"
-
-#include <boost/property_tree/ptree.hpp>
-
-namespace nfd {
-
-typedef boost::property_tree::ptree ConfigSection;
-
-/// \brief callback for config file sections
-typedef function<void(const ConfigSection& /*section*/,
-                      bool /*isDryRun*/,
-                      const std::string& /*filename*/)> ConfigSectionHandler;
-
-/// \brief callback for config file sections without a subscribed handler
-typedef function<void(const std::string& /*filename*/,
-                      const std::string& /*sectionName*/,
-                      const ConfigSection& /*section*/,
-                      bool /*isDryRun*/)> UnknownConfigSectionHandler;
-
-class ConfigFile : noncopyable
-{
-public:
-
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-
-    }
-  };
-
-  ConfigFile(UnknownConfigSectionHandler unknownSectionCallback = throwErrorOnUnknownSection);
-
-  static void
-  throwErrorOnUnknownSection(const std::string& filename,
-                             const std::string& sectionName,
-                             const ConfigSection& section,
-                             bool isDryRun);
-
-  static void
-  ignoreUnknownSection(const std::string& filename,
-                       const std::string& sectionName,
-                       const ConfigSection& section,
-                       bool isDryRun);
-
-  /// \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
-   * \throws ConfigFile::Error if file not found
-   * \throws ConfigFile::Error if parse error
-   */
-  void
-  parse(const std::string& filename, bool isDryRun);
-
-  /**
-   * \param input configuration (as a string) to parse
-   * \param isDryRun true if performing a dry run of configuration, false otherwise
-   * \param filename optional convenience argument to provide more detailed error messages
-   * \throws ConfigFile::Error if file not found
-   * \throws ConfigFile::Error if parse error
-   */
-  void
-  parse(const std::string& input, bool isDryRun, const std::string& filename);
-
-  /**
-   * \param input stream to parse
-   * \param isDryRun true if performing a dry run of configuration, false otherwise
-   * \param filename optional convenience argument to provide more detailed error messages
-   * \throws ConfigFile::Error if parse error
-   */
-  void
-  parse(std::istream& input, bool isDryRun, const std::string& filename);
-
-  /**
-   * \param config ConfigSection that needs to be processed
-   * \param isDryRun true if performing a dry run of configuration, false otherwise
-   * \param filename optional convenience argument to provide more detailed error messages
-   * \throws ConfigFile::Error if parse error
-   */
-  void
-  parse(const ConfigSection& config, bool isDryRun, const std::string& filename);
-
-private:
-
-  void
-  process(bool isDryRun, const std::string& filename);
-
-private:
-  UnknownConfigSectionHandler m_unknownSectionCallback;
-
-  typedef std::map<std::string, ConfigSectionHandler> SubscriptionTable;
-
-  SubscriptionTable m_subscriptions;
-
-  ConfigSection m_global;
-};
-
-} // namespace nfd
-
-
-#endif // NFD_CORE_CONFIG_FILE_HPP
diff --git a/NFD/core/logger.hpp b/NFD/core/logger.hpp
deleted file mode 100644
index d5345af..0000000
--- a/NFD/core/logger.hpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_CORE_LOGGER_HPP
-#define NFD_CORE_LOGGER_HPP
-
-#include "ns3/log.h"
-
-namespace nfd {
-
-#define NFD_LOG_INIT(name) NS_LOG_COMPONENT_DEFINE("nfd." name);
-
-#define NFD_LOG_TRACE(expression) NS_LOG_LOGIC(expression)
-#define NFD_LOG_DEBUG(expression) NS_LOG_DEBUG(expression)
-#define NFD_LOG_INFO(expression) NS_LOG_INFO(expression)
-#define NFD_LOG_ERROR(expression) NS_LOG_ERROR(expression)
-#define NFD_LOG_WARN(expression) NS_LOG_WARN(expression)
-#define NFD_LOG_FATAL(expression) NS_LOG_FATAL(expression)
-
-} // namespace nfd
-
-#endif // NFD_CORE_LOGGER_HPP
diff --git a/NFD/core/network.cpp b/NFD/core/network.cpp
deleted file mode 100644
index b9a6c36..0000000
--- a/NFD/core/network.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "network.hpp"
-
-namespace nfd {
-
-void
-Network::print(std::ostream& os) const
-{
-  os << m_minAddress << " <-> " << m_maxAddress;
-}
-
-const Network&
-Network::getMaxRangeV4()
-{
-  using boost::asio::ip::address_v4;
-  static Network range = Network(address_v4(0), address_v4(0xFFFFFFFF));
-  return range;
-}
-
-const Network&
-Network::getMaxRangeV6()
-{
-  using boost::asio::ip::address_v6;
-  static address_v6::bytes_type maxV6 = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-                                          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
-  static Network range = Network(address_v6(), address_v6(maxV6));
-  return range;
-}
-
-//////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////
-
-std::ostream&
-operator<<(std::ostream& os, const Network& network)
-{
-  network.print(os);
-  return os;
-}
-
-std::istream&
-operator>>(std::istream& is, Network& network)
-{
-  using namespace boost::asio;
-
-  std::string networkStr;
-  is >> networkStr;
-
-  size_t position = networkStr.find('/');
-  if (position == std::string::npos)
-    {
-      network.m_minAddress = ip::address::from_string(networkStr);
-      network.m_maxAddress = ip::address::from_string(networkStr);
-    }
-  else
-    {
-      ip::address address = ip::address::from_string(networkStr.substr(0, position));
-      size_t mask = boost::lexical_cast<size_t>(networkStr.substr(position+1));
-
-      if (address.is_v4())
-        {
-          ip::address_v4::bytes_type maskBytes = boost::initialized_value;
-          for (size_t i = 0; i < mask; i++)
-            {
-              size_t byteId = i / 8;
-              size_t bitIndex = 7 - i % 8;
-              maskBytes[byteId] |= (1 << bitIndex);
-            }
-
-          ip::address_v4::bytes_type addressBytes = address.to_v4().to_bytes();
-          ip::address_v4::bytes_type min;
-          ip::address_v4::bytes_type max;
-
-          for (size_t i = 0; i < addressBytes.size(); i++)
-            {
-              min[i] = addressBytes[i] & maskBytes[i];
-              max[i] = addressBytes[i] | ~(maskBytes[i]);
-            }
-
-          network.m_minAddress = ip::address_v4(min);
-          network.m_maxAddress = ip::address_v4(max);
-        }
-      else
-        {
-          ip::address_v6::bytes_type maskBytes = boost::initialized_value;
-          for (size_t i = 0; i < mask; i++)
-            {
-              size_t byteId = i / 8;
-              size_t bitIndex = 7 - i % 8;
-              maskBytes[byteId] |= (1 << bitIndex);
-            }
-
-          ip::address_v6::bytes_type addressBytes = address.to_v6().to_bytes();
-          ip::address_v6::bytes_type min;
-          ip::address_v6::bytes_type max;
-
-          for (size_t i = 0; i < addressBytes.size(); i++)
-            {
-              min[i] = addressBytes[i] & maskBytes[i];
-              max[i] = addressBytes[i] | ~(maskBytes[i]);
-            }
-
-          network.m_minAddress = ip::address_v6(min);
-          network.m_maxAddress = ip::address_v6(max);
-        }
-    }
-  return is;
-}
-
-} // namespace nfd
diff --git a/NFD/core/network.hpp b/NFD/core/network.hpp
deleted file mode 100644
index 1c0f6d3..0000000
--- a/NFD/core/network.hpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#ifndef NFD_CORE_NETWORK_HPP
-#define NFD_CORE_NETWORK_HPP
-
-#include <boost/asio.hpp>
-#include <boost/utility/value_init.hpp>
-#include <boost/lexical_cast.hpp>
-
-namespace nfd {
-
-class Network
-{
-public:
-  Network()
-  {
-  }
-
-  Network(const boost::asio::ip::address& minAddress,
-          const boost::asio::ip::address& maxAddress)
-    : m_minAddress(minAddress)
-    , m_maxAddress(maxAddress)
-  {
-  }
-
-  void
-  print(std::ostream& os) const;
-
-  bool
-  doesContain(const boost::asio::ip::address& address) const
-  {
-    return (m_minAddress <= address && address <= m_maxAddress);
-  }
-
-  static const Network&
-  getMaxRangeV4();
-
-  static const Network&
-  getMaxRangeV6();
-
-  bool
-  operator==(const Network& rhs) const
-  {
-    return m_minAddress == rhs.m_minAddress && m_maxAddress == rhs.m_maxAddress;
-  }
-
-  bool
-  operator!=(const Network& rhs) const
-  {
-    return !(*this == rhs);
-  }
-
-private:
-  boost::asio::ip::address m_minAddress;
-  boost::asio::ip::address m_maxAddress;
-
-  friend std::istream&
-  operator>>(std::istream& is, Network& network);
-
-  friend std::ostream&
-  operator<<(std::ostream& os, const Network& network);
-};
-
-std::ostream&
-operator<<(std::ostream& os, const Network& network);
-
-std::istream&
-operator>>(std::istream& is, Network& network);
-
-} // namespace nfd
-
-#endif // NFD_CORE_NETWORK_HPP
diff --git a/NFD/core/notification-stream.hpp b/NFD/core/notification-stream.hpp
deleted file mode 100644
index 9a89b4c..0000000
--- a/NFD/core/notification-stream.hpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_CORE_NOTIFICATION_STREAM_HPP
-#define NFD_CORE_NOTIFICATION_STREAM_HPP
-
-#include "common.hpp"
-
-#include <ndn-cxx/encoding/encoding-buffer.hpp>
-#include <ndn-cxx/security/key-chain.hpp>
-
-namespace nfd {
-
-/** \brief provides a publisher of Notification Stream
- *  \sa http://redmine.named-data.net/projects/nfd/wiki/Notification
- */
-template <class FaceBase>
-class NotificationStream : noncopyable
-{
-public:
-  NotificationStream(FaceBase& face, const Name& prefix, ndn::KeyChain& keyChain)
-    : m_face(face)
-    , m_prefix(prefix)
-    , m_keyChain(keyChain)
-    , m_sequenceNo(0)
-  {
-  }
-
-  virtual
-  ~NotificationStream()
-  {
-  }
-
-  template<typename T> void
-  postNotification(const T& notification)
-  {
-    Name dataName = m_prefix;
-    dataName.appendSequenceNumber(m_sequenceNo);
-
-    shared_ptr<Data> data = make_shared<Data>(dataName);
-    data->setContent(notification.wireEncode());
-    data->setFreshnessPeriod(time::seconds(1));
-
-    m_keyChain.sign(*data);
-    m_face.put(*data);
-
-    ++m_sequenceNo;
-  }
-
-private:
-  FaceBase& m_face;
-  const Name m_prefix;
-  ndn::KeyChain& m_keyChain;
-  uint64_t m_sequenceNo;
-};
-
-} // namespace nfd
-
-#endif // NFD_CORE_NOTIFICATION_STREAM_HPP
diff --git a/NFD/core/privilege-helper.cpp b/NFD/core/privilege-helper.cpp
deleted file mode 100644
index 6f87f43..0000000
--- a/NFD/core/privilege-helper.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "privilege-helper.hpp"
-#include "core/logger.hpp"
-
-#include <pwd.h>
-#include <grp.h>
-
-namespace nfd {
-
-NFD_LOG_INIT("PrivilegeHelper");
-
-uid_t PrivilegeHelper::s_normalUid = ::geteuid();
-gid_t PrivilegeHelper::s_normalGid = ::getegid();
-
-uid_t PrivilegeHelper::s_privilegedUid = ::geteuid();
-gid_t PrivilegeHelper::s_privilegedGid = ::getegid();
-
-void
-PrivilegeHelper::initialize(const std::string& userName, const std::string& groupName)
-{
-  static const size_t MAX_GROUP_BUFFER_SIZE = 16384; // 16kB
-  static const size_t MAX_PASSWD_BUFFER_SIZE = 16384;
-
-  static const size_t FALLBACK_GROUP_BUFFER_SIZE = 1024;
-  static const size_t FALLBACK_PASSWD_BUFFER_SIZE = 1024;
-
-  NFD_LOG_TRACE("initializing privilege helper with user \"" << userName << "\""
-                << " group \"" << groupName << "\"");
-
-  // workflow from man getpwnam_r
-
-  if (!groupName.empty())
-    {
-      static int groupSize = ::sysconf(_SC_GETGR_R_SIZE_MAX);
-
-      if (groupSize == -1)
-        {
-          groupSize = FALLBACK_GROUP_BUFFER_SIZE;
-        }
-
-      std::vector<char> groupBuffer(groupSize);
-      struct group group;
-      struct group* groupResult = 0;
-
-      int errorCode = getgrnam_r(groupName.c_str(), &group,
-                                 &groupBuffer[0], groupSize, &groupResult);
-
-      while (errorCode == ERANGE)
-        {
-          if (groupBuffer.size() * 2 > MAX_GROUP_BUFFER_SIZE)
-            {
-              throw PrivilegeHelper::Error("Cannot allocate large enough buffer for struct group");
-            }
-
-          groupBuffer.resize(groupBuffer.size() * 2);
-
-          errorCode = getgrnam_r(groupName.c_str(), &group,
-                                 &groupBuffer[0], groupBuffer.size(), &groupResult);
-        }
-
-      if (errorCode != 0 || !groupResult)
-        {
-          throw PrivilegeHelper::Error("Failed to get gid for \"" + groupName + "\"");
-        }
-
-      s_normalGid = group.gr_gid;
-    }
-
-  if (!userName.empty())
-    {
-      static int passwdSize = ::sysconf(_SC_GETPW_R_SIZE_MAX);
-
-      if (passwdSize == -1)
-        {
-          passwdSize = FALLBACK_PASSWD_BUFFER_SIZE;
-        }
-
-      std::vector<char> passwdBuffer(passwdSize);
-      struct passwd passwd;
-      struct passwd* passwdResult = 0;
-
-      int errorCode =
-        getpwnam_r(userName.c_str(), &passwd,
-                   &passwdBuffer[0], passwdBuffer.size(), &passwdResult);
-
-      while (errorCode == ERANGE)
-        {
-          if (passwdBuffer.size() * 2 > MAX_PASSWD_BUFFER_SIZE)
-            {
-              throw PrivilegeHelper::Error("Cannot allocate large enough buffer for struct passwd");
-            }
-
-          passwdBuffer.resize(passwdBuffer.size() * 2);
-
-          errorCode = getpwnam_r(userName.c_str(), &passwd,
-                                 &passwdBuffer[0], passwdBuffer.size(), &passwdResult);
-        }
-
-      if (errorCode != 0 || !passwdResult)
-        {
-          throw PrivilegeHelper::Error("Failed to get uid for \"" + userName + "\"");
-        }
-
-      s_normalUid = passwd.pw_uid;
-    }
-}
-
-void
-PrivilegeHelper::drop()
-{
-  NFD_LOG_TRACE("dropping to effective gid=" << s_normalGid);
-  if (::setegid(s_normalGid) != 0)
-    {
-      std::stringstream error;
-      error << "Failed to drop to effective gid=" << s_normalGid;
-
-      throw PrivilegeHelper::Error(error.str());
-    }
-
-  NFD_LOG_TRACE("dropping to effective uid=" << s_normalUid);
-  if (::seteuid(s_normalUid) != 0)
-    {
-      std::stringstream error;
-      error << "Failed to drop to effective uid=" << s_normalUid;
-
-      throw PrivilegeHelper::Error(error.str());
-    }
-
-  NFD_LOG_INFO("dropped to effective uid=" << ::geteuid() << " gid=" << ::getegid());
-}
-
-void
-PrivilegeHelper::raise()
-{
-  NFD_LOG_TRACE("elevating to effective uid=" << s_privilegedUid);
-  if (::seteuid(s_privilegedUid) != 0)
-    {
-      std::stringstream error;
-      error << "Failed to elevate to effective uid=" << s_privilegedUid;
-
-      throw PrivilegeHelper::Error(error.str());
-    }
-
-  NFD_LOG_TRACE("elevating to effective gid=" << s_privilegedGid);
-  if (::setegid(s_privilegedGid) != 0)
-    {
-      std::stringstream error;
-      error << "Failed to elevate to effective gid=" << s_privilegedGid;
-
-      throw PrivilegeHelper::Error(error.str());
-    }
-  NFD_LOG_INFO("elevated to effective uid=" << ::geteuid() << " gid=" << ::getegid());
-}
-
-void
-PrivilegeHelper::runElevated(function<void()> f)
-{
-  raise();
-
-  try
-    {
-      f();
-    }
-  catch (...)
-    {
-      drop();
-      throw;
-    }
-  drop();
-}
-
-} // namespace nfd
diff --git a/NFD/core/privilege-helper.hpp b/NFD/core/privilege-helper.hpp
deleted file mode 100644
index 92bd53d..0000000
--- a/NFD/core/privilege-helper.hpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#ifndef NFD_CORE_PRIVILEGE_HELPER_HPP
-#define NFD_CORE_PRIVILEGE_HELPER_HPP
-
-#include "common.hpp"
-
-#include <unistd.h>
-
-namespace nfd {
-
-class PrivilegeHelper
-{
-public:
-
-  /// \brief PrivilegeHelper::Error represents a serious seteuid/gid failure and
-  ///        should only be caught by main in as part of a graceful program termination.
-  class Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : m_whatMessage(what)
-    {
-    }
-
-    const char*
-    what() const
-    {
-      return m_whatMessage.c_str();
-    }
-
-  private:
-    const std::string m_whatMessage;
-  };
-
-  static void
-  initialize(const std::string& userName, const std::string& groupName);
-
-  static void
-  drop();
-
-  static void
-  runElevated(function<void()> f);
-
-private:
-
-  static void
-  raise();
-
-private:
-
-  static uid_t s_normalUid;
-  static gid_t s_normalGid;
-
-  static uid_t s_privilegedUid;
-  static gid_t s_privilegedGid;
-};
-
-} // namespace nfd
-
-#endif // NFD_CORE_PRIVILEGE_HELPER_HPP
diff --git a/NFD/core/random.cpp b/NFD/core/random.cpp
deleted file mode 100644
index 51b137e..0000000
--- a/NFD/core/random.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "random.hpp"
-
-namespace nfd {
-
-static boost::random::mt19937 g_rng;
-
-boost::random::mt19937&
-getGlobalRng()
-{
-  return g_rng;
-}
-
-} // namespace nfd
diff --git a/NFD/core/random.hpp b/NFD/core/random.hpp
deleted file mode 100644
index 1515b72..0000000
--- a/NFD/core/random.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * This file declares the global random number generator
- * All random numbers in NFD should use this global random number generator,
- * so that the generator can be properly seeded when necessary.
- *
- * This random number generator is not suitable for security purposes;
- * security-critical code should use CryptoPP random number generator instead.
- */
-
-#ifndef NFD_CORE_RANDOM_HPP
-#define NFD_CORE_RANDOM_HPP
-
-#include <boost/random/mersenne_twister.hpp>
-
-namespace nfd {
-
-/** \return the global random number generator instance
- */
-boost::random::mt19937&
-getGlobalRng();
-
-} // namespace nfd
-
-#endif // NFD_CORE_RANDOM_HPP
diff --git a/NFD/core/scheduler.cpp b/NFD/core/scheduler.cpp
deleted file mode 100644
index c26d466..0000000
--- a/NFD/core/scheduler.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "scheduler.hpp"
-
-namespace ns3 {
-
-/// @cond include_hidden
-
-template<>
-struct EventMemberImplObjTraits<std::function<void()>> {
-  typedef std::function<void()> T;
-  static T&
-  GetReference(T& p)
-  {
-    return p;
-  }
-};
-
-/// @endcond
-
-} // namespace ns3
-
-namespace nfd {
-namespace scheduler {
-
-EventId
-schedule(const time::nanoseconds& after, const std::function<void()>& event)
-{
-  ns3::EventId id = ns3::Simulator::Schedule(ns3::NanoSeconds(after.count()),
-                                             &std::function<void()>::operator(), event);
-  return std::make_shared<ns3::EventId>(id);
-}
-
-void
-cancel(const EventId& eventId)
-{
-  if (eventId != nullptr) {
-    ns3::Simulator::Remove(*eventId);
-    const_cast<EventId&>(eventId).reset();
-  }
-}
-
-ScopedEventId::ScopedEventId()
-{
-}
-
-ScopedEventId::ScopedEventId(const EventId& event)
-  : m_event(event)
-{
-}
-
-ScopedEventId::ScopedEventId(ScopedEventId&& other)
-  : m_event(other.m_event)
-{
-  other.release();
-}
-
-ScopedEventId&
-ScopedEventId::operator=(const EventId& event)
-{
-  if (m_event != event) {
-    scheduler::cancel(m_event);
-    m_event = event;
-  }
-  return *this;
-}
-
-ScopedEventId::~ScopedEventId()
-{
-  scheduler::cancel(m_event);
-}
-
-void
-ScopedEventId::cancel()
-{
-  scheduler::cancel(m_event);
-}
-
-void
-ScopedEventId::release()
-{
-  m_event.reset();
-}
-
-} // namespace scheduler
-} // namespace nfd
diff --git a/NFD/core/scheduler.hpp b/NFD/core/scheduler.hpp
deleted file mode 100644
index 4ef124c..0000000
--- a/NFD/core/scheduler.hpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_CORE_SCHEDULER_HPP
-#define NFD_CORE_SCHEDULER_HPP
-
-#include "common.hpp"
-
-#include "ns3/simulator.h"
-
-namespace nfd {
-namespace scheduler {
-
-/** \class EventId
- *  \brief Opaque type (shared_ptr) representing ID of a scheduled event
- */
-typedef std::shared_ptr<ns3::EventId> EventId;
-
-/** \brief schedule an event
- */
-EventId
-schedule(const time::nanoseconds& after, const std::function<void()>& event);
-
-/** \brief cancel a scheduled event
- */
-void
-cancel(const EventId& eventId);
-
-/** \brief cancels an event automatically upon destruction
- */
-class ScopedEventId : noncopyable
-{
-public:
-  ScopedEventId();
-
-  /** \brief implicit constructor from EventId
-   *  \param event the event to be cancelled upon destruction
-   */
-  ScopedEventId(const EventId& event);
-
-  /** \brief move constructor
-   */
-  ScopedEventId(ScopedEventId&& other);
-
-  /** \brief assigns an event
-   *
-   *  If a different event has been assigned to this instance previously,
-   *  that event will be cancelled immediately.
-   */
-  ScopedEventId&
-  operator=(const EventId& event);
-
-  /** \brief cancels the event
-   */
-  ~ScopedEventId();
-
-  /** \brief cancels the event manually
-   */
-  void
-  cancel();
-
-  /** \brief releases the event so that it won't be disconnected
-   *         when this ScopedEventId is destructed
-   */
-  void
-  release();
-
-private:
-  EventId m_event;
-};
-
-} // namespace scheduler
-
-using scheduler::EventId;
-
-} // namespace nfd
-
-#endif // NFD_CORE_SCHEDULER_HPP
diff --git a/NFD/core/segment-publisher.hpp b/NFD/core/segment-publisher.hpp
deleted file mode 100644
index ccb3426..0000000
--- a/NFD/core/segment-publisher.hpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_CORE_SEGMENT_PUBLISHER_HPP
-#define NFD_CORE_SEGMENT_PUBLISHER_HPP
-
-#include "common.hpp"
-
-#include <ndn-cxx/encoding/encoding-buffer.hpp>
-#include <ndn-cxx/security/key-chain.hpp>
-
-namespace nfd {
-
-/** \brief provides a publisher of Status Dataset or other segmented octet stream
- *  \sa http://redmine.named-data.net/projects/nfd/wiki/StatusDataset
- */
-template <class FaceBase>
-class SegmentPublisher : noncopyable
-{
-public:
-  SegmentPublisher(FaceBase& face, const Name& prefix, ndn::KeyChain& keyChain)
-    : m_face(face)
-    , m_prefix(prefix)
-    , m_keyChain(keyChain)
-  {
-  }
-
-  virtual
-  ~SegmentPublisher()
-  {
-  }
-
-  static size_t
-  getMaxSegmentSize()
-  {
-    static const size_t MAX_SEGMENT_SIZE = ndn::MAX_NDN_PACKET_SIZE >> 1;
-    return MAX_SEGMENT_SIZE;
-  }
-
-  void
-  publish()
-  {
-    ndn::EncodingBuffer buffer;
-    generate(buffer);
-
-    const uint8_t* rawBuffer = buffer.buf();
-    const uint8_t* segmentBegin = rawBuffer;
-    const uint8_t* end = rawBuffer + buffer.size();
-
-    Name segmentPrefix(m_prefix);
-    segmentPrefix.appendVersion();
-
-    uint64_t segmentNo = 0;
-    do {
-      const uint8_t* segmentEnd = segmentBegin + getMaxSegmentSize();
-      if (segmentEnd > end) {
-        segmentEnd = end;
-      }
-
-      Name segmentName(segmentPrefix);
-      segmentName.appendSegment(segmentNo);
-
-      shared_ptr<Data> data = make_shared<Data>(segmentName);
-      data->setContent(segmentBegin, segmentEnd - segmentBegin);
-
-      segmentBegin = segmentEnd;
-      if (segmentBegin >= end) {
-        data->setFinalBlockId(segmentName[-1]);
-      }
-
-      publishSegment(data);
-      ++segmentNo;
-    } while (segmentBegin < end);
-  }
-
-protected:
-  /** \brief In a derived class, write the octets into outBuffer.
-   */
-  virtual size_t
-  generate(ndn::EncodingBuffer& outBuffer) = 0;
-
-private:
-  void
-  publishSegment(shared_ptr<Data>& data)
-  {
-    m_keyChain.sign(*data);
-    m_face.put(*data);
-  }
-
-private:
-  FaceBase& m_face;
-  const Name m_prefix;
-  ndn::KeyChain& m_keyChain;
-};
-
-} // namespace nfd
-
-#endif // NFD_CORE_SEGMENT_PUBLISHER_HPP
diff --git a/NFD/daemon/face/channel.cpp b/NFD/daemon/face/channel.cpp
deleted file mode 100644
index d161504..0000000
--- a/NFD/daemon/face/channel.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "channel.hpp"
-
-namespace nfd {
-
-Channel::~Channel()
-{
-}
-
-void
-Channel::setUri(const FaceUri& uri)
-{
-  m_uri = uri;
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/face/channel.hpp b/NFD/daemon/face/channel.hpp
deleted file mode 100644
index 810d726..0000000
--- a/NFD/daemon/face/channel.hpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#ifndef NFD_DAEMON_FACE_CHANNEL_HPP
-#define NFD_DAEMON_FACE_CHANNEL_HPP
-
-#include "face.hpp"
-
-namespace nfd {
-
-class Channel : noncopyable
-{
-public:
-  /** \brief Prototype for the callback called when 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
-   */
-  typedef function<void(const std::string& reason)> ConnectFailedCallback;
-
-  virtual
-  ~Channel();
-
-  const FaceUri&
-  getUri() const;
-
-protected:
-  void
-  setUri(const FaceUri& uri);
-
-private:
-  FaceUri m_uri;
-};
-
-inline const FaceUri&
-Channel::getUri() const
-{
-  return m_uri;
-}
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_FACE_CHANNEL_HPP
diff --git a/NFD/daemon/face/face-counters.hpp b/NFD/daemon/face/face-counters.hpp
deleted file mode 100644
index 6dc1d6a..0000000
--- a/NFD/daemon/face/face-counters.hpp
+++ /dev/null
@@ -1,251 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_FACE_FACE_COUNTERS_HPP
-#define NFD_DAEMON_FACE_FACE_COUNTERS_HPP
-
-#include "common.hpp"
-
-namespace nfd {
-
-/** \brief represents a counter of number of packets
- */
-// PacketCounter is noncopyable, because increment should be called on the counter,
-// not a copy of it; it's implicitly convertible to uint64_t to be observed
-class PacketCounter : noncopyable
-{
-public:
-  typedef uint64_t rep;
-
-  PacketCounter()
-    : m_value(0)
-  {
-  }
-
-  operator rep() const
-  {
-    return m_value;
-  }
-
-  PacketCounter&
-  operator++()
-  {
-    ++m_value;
-    return *this;
-  }
-  // postfix ++ operator is not provided because it's not needed
-
-  void
-  set(rep value)
-  {
-    m_value = value;
-  }
-
-private:
-  rep m_value;
-};
-
-/** \brief represents a counter of number of bytes
- */
-// ByteCounter is noncopyable, because increment should be called on the counter,
-// not a copy of it; it's implicitly convertible to uint64_t to be observed
-class ByteCounter : noncopyable
-{
-public:
-  typedef uint64_t rep;
-
-  ByteCounter()
-    : m_value(0)
-  {
-  }
-
-  operator rep() const
-  {
-    return m_value;
-  }
-
-  ByteCounter&
-  operator+=(rep n)
-  {
-    m_value += n;
-    return *this;
-  }
-
-  void
-  set(rep value)
-  {
-    m_value = value;
-  }
-
-private:
-  rep m_value;
-};
-
-/** \brief contains network layer packet counters
- */
-class NetworkLayerCounters : noncopyable
-{
-public:
-  /// incoming Interest
-  const PacketCounter&
-  getNInInterests() const
-  {
-    return m_nInInterests;
-  }
-
-  PacketCounter&
-  getNInInterests()
-  {
-    return m_nInInterests;
-  }
-
-  /// incoming Data
-  const PacketCounter&
-  getNInDatas() const
-  {
-    return m_nInDatas;
-  }
-
-  PacketCounter&
-  getNInDatas()
-  {
-    return m_nInDatas;
-  }
-
-  /// outgoing Interest
-  const PacketCounter&
-  getNOutInterests() const
-  {
-    return m_nOutInterests;
-  }
-
-  PacketCounter&
-  getNOutInterests()
-  {
-    return m_nOutInterests;
-  }
-
-  /// outgoing Data
-  const PacketCounter&
-  getNOutDatas() const
-  {
-    return m_nOutDatas;
-  }
-
-  PacketCounter&
-  getNOutDatas()
-  {
-    return m_nOutDatas;
-  }
-
-protected:
-  /** \brief copy current obseverations to a struct
-   *  \param recipient an object with set methods for counters
-   */
-  template<typename R>
-  void
-  copyTo(R& recipient) const
-  {
-    recipient.setNInInterests(this->getNInInterests());
-    recipient.setNInDatas(this->getNInDatas());
-    recipient.setNOutInterests(this->getNOutInterests());
-    recipient.setNOutDatas(this->getNOutDatas());
-  }
-
-private:
-  PacketCounter m_nInInterests;
-  PacketCounter m_nInDatas;
-  PacketCounter m_nOutInterests;
-  PacketCounter m_nOutDatas;
-};
-
-/** \brief contains link layer byte counters
- */
-class LinkLayerCounters : noncopyable
-{
-public:
-  /// received bytes
-  const ByteCounter&
-  getNInBytes() const
-  {
-    return m_nInBytes;
-  }
-
-  ByteCounter&
-  getNInBytes()
-  {
-    return m_nInBytes;
-  }
-
-  /// sent bytes
-  const ByteCounter&
-  getNOutBytes() const
-  {
-    return m_nOutBytes;
-  }
-
-  ByteCounter&
-  getNOutBytes()
-  {
-    return m_nOutBytes;
-  }
-
-protected:
-  /** \brief copy current obseverations to a struct
-   *  \param recipient an object with set methods for counters
-   */
-  template<typename R>
-  void
-  copyTo(R& recipient) const
-  {
-    recipient.setNInBytes(this->getNInBytes());
-    recipient.setNOutBytes(this->getNOutBytes());
-  }
-
-private:
-  ByteCounter m_nInBytes;
-  ByteCounter m_nOutBytes;
-};
-
-/** \brief contains counters on face
- */
-class FaceCounters : public NetworkLayerCounters, public LinkLayerCounters
-{
-public:
-  /** \brief copy current obseverations to a struct
-   *  \param recipient an object with set methods for counters
-   */
-  template<typename R>
-  void
-  copyTo(R& recipient) const
-  {
-    this->NetworkLayerCounters::copyTo(recipient);
-    this->LinkLayerCounters::copyTo(recipient);
-  }
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_FACE_FACE_COUNTERS_HPP
diff --git a/NFD/daemon/face/face.cpp b/NFD/daemon/face/face.cpp
deleted file mode 100644
index 61cc166..0000000
--- a/NFD/daemon/face/face.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "face.hpp"
-#include "core/logger.hpp"
-
-namespace nfd {
-
-Face::Face(const FaceUri& remoteUri, const FaceUri& localUri, bool isLocal)
-  : m_id(INVALID_FACEID)
-  , m_isLocal(isLocal)
-  , m_remoteUri(remoteUri)
-  , m_localUri(localUri)
-  , m_isOnDemand(false)
-  , m_isFailed(false)
-  , m_metric(0)
-{
-  onReceiveInterest += [this](const ndn::Interest&) { ++m_counters.getNInInterests(); };
-  onReceiveData     += [this](const ndn::Data&) {     ++m_counters.getNInDatas(); };
-  onSendInterest    += [this](const ndn::Interest&) { ++m_counters.getNOutInterests(); };
-  onSendData        += [this](const ndn::Data&) {     ++m_counters.getNOutDatas(); };
-}
-
-Face::~Face()
-{
-}
-
-FaceId
-Face::getId() const
-{
-  return m_id;
-}
-
-// this method is private and should be used only by the FaceTable
-void
-Face::setId(FaceId faceId)
-{
-  m_id = faceId;
-}
-
-void
-Face::setDescription(const std::string& description)
-{
-  m_description = description;
-}
-
-const std::string&
-Face::getDescription() const
-{
-  return m_description;
-}
-
-bool
-Face::isMultiAccess() const
-{
-  return false;
-}
-
-bool
-Face::isUp() const
-{
-  return true;
-}
-
-bool
-Face::decodeAndDispatchInput(const Block& element)
-{
-  try {
-    /// \todo Ensure lazy field decoding process
-
-    if (element.type() == tlv::Interest)
-      {
-        shared_ptr<Interest> i = make_shared<Interest>();
-        i->wireDecode(element);
-        this->onReceiveInterest(*i);
-      }
-    else if (element.type() == tlv::Data)
-      {
-        shared_ptr<Data> d = make_shared<Data>();
-        d->wireDecode(element);
-        this->onReceiveData(*d);
-      }
-    else
-      return false;
-
-    return true;
-  }
-  catch (tlv::Error&) {
-    return false;
-  }
-}
-
-void
-Face::fail(const std::string& reason)
-{
-  if (m_isFailed) {
-    return;
-  }
-
-  m_isFailed = true;
-  this->onFail(reason);
-
-  this->onFail.clear();
-}
-
-template<typename FaceTraits>
-void
-Face::copyStatusTo(FaceTraits& traits) const
-{
-  traits.setFaceId(getId())
-    .setRemoteUri(getRemoteUri().toString())
-    .setLocalUri(getLocalUri().toString());
-
-  if (isLocal()) {
-    traits.setFaceScope(ndn::nfd::FACE_SCOPE_LOCAL);
-  }
-  else {
-    traits.setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL);
-  }
-
-  if (isOnDemand()) {
-    traits.setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
-  }
-  else {
-    traits.setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
-  }
-}
-
-template void
-Face::copyStatusTo<ndn::nfd::FaceStatus>(ndn::nfd::FaceStatus&) const;
-
-template void
-Face::copyStatusTo<ndn::nfd::FaceEventNotification>(ndn::nfd::FaceEventNotification&) const;
-
-ndn::nfd::FaceStatus
-Face::getFaceStatus() const
-{
-  ndn::nfd::FaceStatus status;
-  copyStatusTo(status);
-
-  this->getCounters().copyTo(status);
-
-  return status;
-}
-
-} //namespace nfd
diff --git a/NFD/daemon/face/face.hpp b/NFD/daemon/face/face.hpp
deleted file mode 100644
index 803d62a..0000000
--- a/NFD/daemon/face/face.hpp
+++ /dev/null
@@ -1,271 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_FACE_FACE_HPP
-#define NFD_DAEMON_FACE_FACE_HPP
-
-#include "common.hpp"
-#include "face-counters.hpp"
-
-#include <ndn-cxx/util/face-uri.hpp>
-#include <ndn-cxx/management/nfd-face-status.hpp>
-#include <ndn-cxx/management/nfd-face-event-notification.hpp>
-
-namespace nfd {
-
-/** \class FaceId
- *  \brief identifies a face
- */
-typedef int FaceId;
-
-/// indicates an invalid FaceId
-const FaceId INVALID_FACEID = -1;
-
-/// identifies the InternalFace used in management
-const FaceId FACEID_INTERNAL_FACE = 1;
-/// identifies a packet comes from the ContentStore, in LocalControlHeader incomingFaceId
-const FaceId FACEID_CONTENT_STORE = 254;
-/// identifies the NullFace that drops every packet
-const FaceId FACEID_NULL = 255;
-/// upper bound of reserved FaceIds
-const FaceId FACEID_RESERVED_MAX = 255;
-
-using ndn::util::FaceUri;
-
-/** \brief represents a face
- */
-class Face : noncopyable, public enable_shared_from_this<Face>
-{
-public:
-  /**
-   * \brief Face-related error
-   */
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
-  Face(const FaceUri& remoteUri, const FaceUri& localUri, bool isLocal = false);
-
-  virtual
-  ~Face();
-
-  /// fires when an Interest is received
-  EventEmitter<Interest> onReceiveInterest;
-
-  /// fires when a Data is received
-  EventEmitter<Data> onReceiveData;
-
-  /// fires when an Interest is sent out
-  EventEmitter<Interest> onSendInterest;
-
-  /// fires when a Data is sent out
-  EventEmitter<Data> onSendData;
-
-  /// fires when face disconnects or fails to perform properly
-  EventEmitter<std::string/*reason*/> onFail;
-
-  /// send an Interest
-  virtual void
-  sendInterest(const Interest& interest) = 0;
-
-  /// send a Data
-  virtual void
-  sendData(const Data& data) = 0;
-
-  /** \brief Close the face
-   *
-   *  This terminates all communication on the face and cause
-   *  onFail() method event to be invoked
-   */
-  virtual void
-  close() = 0;
-
-public: // attributes
-  FaceId
-  getId() const;
-
-  /** \brief Set the description
-   *
-   *  This is typically invoked by mgmt on set description command
-   */
-  virtual void
-  setDescription(const std::string& description);
-
-  /// Get the description
-  virtual const std::string&
-  getDescription() const;
-
-  void
-  setMetric(uint64_t metric);
-
-  uint64_t
-  getMetric() const;
-
-  /** \brief Get whether face is connected to a local app
-   */
-  bool
-  isLocal() const;
-
-  /** \brief Get whether packets sent this Face may reach multiple peers
-   *
-   *  In this base class this property is always false.
-   */
-  virtual bool
-  isMultiAccess() const;
-
-  /** \brief Get whether underlying communication is up
-   *
-   *  In this base class this property is always true.
-   */
-  virtual bool
-  isUp() const;
-
-  /** \brief Get whether face is created on demand or explicitly via FaceManagement protocol
-   */
-  bool
-  isOnDemand() const;
-
-  const FaceCounters&
-  getCounters() const;
-
-  /** \return a FaceUri that represents the remote endpoint
-   */
-  const FaceUri&
-  getRemoteUri() const;
-
-  /** \return a FaceUri that represents the local endpoint (NFD side)
-   */
-  const FaceUri&
-  getLocalUri() const;
-
-  /** \return FaceTraits data structure filled with the current FaceTraits status
-   */
-  template<typename FaceTraits>
-  void
-  copyStatusTo(FaceTraits& traits) const;
-
-  /** \return FaceStatus data structure filled with the current Face status
-   */
-  virtual ndn::nfd::FaceStatus
-  getFaceStatus() const;
-
-protected:
-  // this is a non-virtual method
-  bool
-  decodeAndDispatchInput(const Block& element);
-
-  FaceCounters&
-  getMutableCounters();
-
-  void
-  setOnDemand(bool isOnDemand);
-
-  /** \brief fail the face and raise onFail event if it's UP; otherwise do nothing
-   */
-  void
-  fail(const std::string& reason);
-
-private:
-  void
-  setId(FaceId faceId);
-
-private:
-  FaceId m_id;
-  std::string m_description;
-  bool m_isLocal; // for scoping purposes
-  FaceCounters m_counters;
-  FaceUri m_remoteUri;
-  FaceUri m_localUri;
-  bool m_isOnDemand;
-  bool m_isFailed;
-  uint64_t m_metric;
-
-  // allow setting FaceId
-  friend class FaceTable;
-};
-
-inline bool
-Face::isLocal() const
-{
-  return m_isLocal;
-}
-
-inline const FaceCounters&
-Face::getCounters() const
-{
-  return m_counters;
-}
-
-inline FaceCounters&
-Face::getMutableCounters()
-{
-  return m_counters;
-}
-
-inline const FaceUri&
-Face::getRemoteUri() const
-{
-  return m_remoteUri;
-}
-
-inline const FaceUri&
-Face::getLocalUri() const
-{
-  return m_localUri;
-}
-
-inline void
-Face::setOnDemand(bool isOnDemand)
-{
-  m_isOnDemand = isOnDemand;
-}
-
-inline bool
-Face::isOnDemand() const
-{
-  return m_isOnDemand;
-}
-
-inline void
-Face::setMetric(uint64_t metric)
-{
-  m_metric = metric;
-}
-
-inline uint64_t
-Face::getMetric() const
-{
-  return m_metric;
-}
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_FACE_FACE_HPP
diff --git a/NFD/daemon/face/local-face.hpp b/NFD/daemon/face/local-face.hpp
deleted file mode 100644
index 5f2eb0d..0000000
--- a/NFD/daemon/face/local-face.hpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#ifndef NFD_DAEMON_FACE_LOCAL_FACE_HPP
-#define NFD_DAEMON_FACE_LOCAL_FACE_HPP
-
-#include "face.hpp"
-#include <ndn-cxx/management/nfd-control-parameters.hpp>
-
-namespace nfd {
-
-using ndn::nfd::LocalControlFeature;
-using ndn::nfd::LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID;
-using ndn::nfd::LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID;
-
-/** \brief represents a face
- */
-class LocalFace : public Face
-{
-public:
-  LocalFace(const FaceUri& remoteUri, const FaceUri& localUri);
-
-  /** \brief get whether any LocalControlHeader feature is enabled
-   *
-   * \returns true if any feature is enabled.
-   */
-  bool
-  isLocalControlHeaderEnabled() const;
-
-  /** \brief get whether a specific LocalControlHeader feature is enabled
-   *
-   *  \param feature The feature.
-   *  \returns true if the specified feature is enabled.
-   */
-  bool
-  isLocalControlHeaderEnabled(LocalControlFeature feature) const;
-
-  /** \brief enable or disable a LocalControlHeader feature
-   *
-   *  \param feature The feature. Cannot be LOCAL_CONTROL_FEATURE_ANY
-   *                                     or LOCAL_CONTROL_FEATURE_MAX
-   */
-  void
-  setLocalControlHeaderFeature(LocalControlFeature feature, bool enabled = true);
-
-public:
-
-  static const size_t LOCAL_CONTROL_FEATURE_MAX = 3; /// upper bound of LocalControlFeature enum
-  static const size_t LOCAL_CONTROL_FEATURE_ANY = 0; /// any feature
-
-protected:
-  // statically overridden from Face
-
-  /** \brief Decode block into Interest/Data, considering potential LocalControlHeader
-   *
-   *  If LocalControlHeader is present, the encoded data is filtered out, based
-   *  on enabled features on the face.
-   */
-  bool
-  decodeAndDispatchInput(const Block& element);
-
-  // LocalFace-specific methods
-
-  /** \brief Check if LocalControlHeader needs to be included, taking into account
-   *         both set parameters in supplied LocalControlHeader and features
-   *         enabled on the local face.
-   */
-  bool
-  isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const;
-
-  /** \brief Create LocalControlHeader, considering enabled features
-   */
-  template<class Packet>
-  Block
-  filterAndEncodeLocalControlHeader(const Packet& packet);
-
-private:
-  std::vector<bool> m_localControlHeaderFeatures;
-};
-
-inline
-LocalFace::LocalFace(const FaceUri& remoteUri, const FaceUri& localUri)
-  : Face(remoteUri, localUri, true)
-  , m_localControlHeaderFeatures(LocalFace::LOCAL_CONTROL_FEATURE_MAX)
-{
-}
-
-inline bool
-LocalFace::isLocalControlHeaderEnabled() const
-{
-  return m_localControlHeaderFeatures[LOCAL_CONTROL_FEATURE_ANY];
-}
-
-inline bool
-LocalFace::isLocalControlHeaderEnabled(LocalControlFeature feature) const
-{
-  BOOST_ASSERT(0 < feature &&
-               static_cast<size_t>(feature) < m_localControlHeaderFeatures.size());
-  return m_localControlHeaderFeatures[feature];
-}
-
-inline void
-LocalFace::setLocalControlHeaderFeature(LocalControlFeature feature, bool enabled/* = true*/)
-{
-  BOOST_ASSERT(0 < feature &&
-               static_cast<size_t>(feature) < m_localControlHeaderFeatures.size());
-
-  m_localControlHeaderFeatures[feature] = enabled;
-
-  m_localControlHeaderFeatures[LOCAL_CONTROL_FEATURE_ANY] =
-    std::find(m_localControlHeaderFeatures.begin() + 1,
-              m_localControlHeaderFeatures.end(), true) <
-              m_localControlHeaderFeatures.end();
-  // 'find(..) < .end()' instead of 'find(..) != .end()' due to LLVM Bug 16816
-}
-
-inline bool
-LocalFace::decodeAndDispatchInput(const Block& element)
-{
-  try {
-    const Block& payload = ndn::nfd::LocalControlHeader::getPayload(element);
-
-    // If received LocalControlHeader, but it is not enabled on the face
-    if ((&payload != &element) && !this->isLocalControlHeaderEnabled())
-      return false;
-
-    if (payload.type() == tlv::Interest)
-      {
-        shared_ptr<Interest> i = make_shared<Interest>();
-        i->wireDecode(payload);
-        if (&payload != &element)
-          {
-            uint8_t mask = 0;
-            if (this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID)) {
-              mask |= ndn::nfd::LocalControlHeader::ENCODE_NEXT_HOP;
-            }
-            i->getLocalControlHeader().wireDecode(element, mask);
-          }
-
-        this->onReceiveInterest(*i);
-      }
-    else if (payload.type() == tlv::Data)
-      {
-        shared_ptr<Data> d = make_shared<Data>();
-        d->wireDecode(payload);
-
-        /// \todo Uncomment and correct the following when we have more
-        ///       options in LocalControlHeader that apply for incoming
-        ///       Data packets (if ever)
-        // if (&payload != &element)
-        //   {
-        //
-        //     d->getLocalControlHeader().wireDecode(element,
-        //       false,
-        //       false);
-        //   }
-
-        this->onReceiveData(*d);
-      }
-    else
-      return false;
-
-    return true;
-  }
-  catch (tlv::Error&) {
-    return false;
-  }
-}
-
-inline bool
-LocalFace::isEmptyFilteredLocalControlHeader(const ndn::nfd::LocalControlHeader& header) const
-{
-  if (!this->isLocalControlHeaderEnabled())
-    return true;
-
-  uint8_t mask = 0;
-  if (this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID)) {
-    mask |= ndn::nfd::LocalControlHeader::ENCODE_INCOMING_FACE_ID;
-  }
-  return header.empty(mask);
-}
-
-template<class Packet>
-inline Block
-LocalFace::filterAndEncodeLocalControlHeader(const Packet& packet)
-{
-  uint8_t mask = 0;
-  if (this->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID)) {
-    mask |= ndn::nfd::LocalControlHeader::ENCODE_INCOMING_FACE_ID;
-  }
-  return packet.getLocalControlHeader().wireEncode(packet, mask);
-}
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_FACE_LOCAL_FACE_HPP
diff --git a/NFD/daemon/face/null-face.cpp b/NFD/daemon/face/null-face.cpp
deleted file mode 100644
index 5d55693..0000000
--- a/NFD/daemon/face/null-face.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "null-face.hpp"
-
-namespace nfd {
-
-// FIB might restrict creating a nexthop record toward non-local face in /localhost namespace.
-// NullFace has isLocal=true to enable creating a "blackhole" FIB entry under /localhost.
-
-NullFace::NullFace(const FaceUri& uri)
-  : Face(uri, uri, true)
-{
-}
-
-void
-NullFace::sendInterest(const Interest& interest)
-{
-}
-
-void
-NullFace::sendData(const Data& data)
-{
-}
-
-void
-NullFace::close()
-{
-  this->fail("close");
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/face/null-face.hpp b/NFD/daemon/face/null-face.hpp
deleted file mode 100644
index 3dae571..0000000
--- a/NFD/daemon/face/null-face.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_FACE_NULL_FACE_HPP
-#define NFD_DAEMON_FACE_NULL_FACE_HPP
-
-#include "face.hpp"
-
-namespace nfd {
-
-/**
- * \brief a Face that has no underlying transport and drops every packet
- */
-class NullFace : public Face
-{
-public:
-  explicit
-  NullFace(const FaceUri& uri = FaceUri("null://"));
-
-  virtual void
-  sendInterest(const Interest& interest);
-
-  /// send a Data
-  virtual void
-  sendData(const Data& data);
-
-  /** \brief Close the face
-   *
-   *  This terminates all communication on the face and cause
-   *  onFail() method event to be invoked
-   */
-  virtual void
-  close();
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_FACE_NULL_FACE_HPP
diff --git a/NFD/daemon/face/protocol-factory.hpp b/NFD/daemon/face/protocol-factory.hpp
deleted file mode 100644
index 0542017..0000000
--- a/NFD/daemon/face/protocol-factory.hpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_FACE_PROTOCOL_FACTORY_HPP
-#define NFD_DAEMON_FACE_PROTOCOL_FACTORY_HPP
-
-#include "face.hpp"
-
-namespace nfd {
-
-class Channel;
-
-/**
- * \brief Prototype for the callback called when 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
- */
-typedef function<void(const std::string& reason)> FaceConnectFailedCallback;
-
-
-class ProtocolFactory
-{
-public:
-  /**
-   * \brief Base class for all exceptions thrown by channel factories
-   */
-  struct Error : public std::runtime_error
-  {
-    Error(const std::string& what) : std::runtime_error(what) {}
-  };
-
-  /** \brief Try to create Face using the supplied Face URI
-   *
-   * This method should automatically choose channel, based on supplied Face URI
-   * and create face.
-   *
-   * \throws Factory::Error if Factory does not support connect operation
-   */
-  virtual void
-  createFace(const FaceUri& uri,
-             const FaceCreatedCallback& onCreated,
-             const FaceConnectFailedCallback& onConnectFailed) = 0;
-
-  virtual std::list<shared_ptr<const Channel> >
-  getChannels() const = 0;
-
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_FACE_PROTOCOL_FACTORY_HPP
diff --git a/NFD/daemon/fw/available-strategies.cpp b/NFD/daemon/fw/available-strategies.cpp
deleted file mode 100644
index 45be270..0000000
--- a/NFD/daemon/fw/available-strategies.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "best-route-strategy.hpp"
-#include "broadcast-strategy.hpp"
-#include "client-control-strategy.hpp"
-#include "ncc-strategy.hpp"
-#include "best-route-strategy2.hpp"
-
-namespace nfd {
-namespace fw {
-
-shared_ptr<Strategy>
-makeDefaultStrategy(Forwarder& forwarder)
-{
-  return make_shared<BestRouteStrategy2>(ref(forwarder));
-}
-
-template<typename S>
-inline void
-installStrategy(Forwarder& forwarder)
-{
-  StrategyChoice& strategyChoice = forwarder.getStrategyChoice();
-  if (!strategyChoice.hasStrategy(S::STRATEGY_NAME)) {
-    strategyChoice.install(make_shared<S>(ref(forwarder)));
-  }
-}
-
-void
-installStrategies(Forwarder& forwarder)
-{
-  installStrategy<BestRouteStrategy>(forwarder);
-  installStrategy<BroadcastStrategy>(forwarder);
-  installStrategy<ClientControlStrategy>(forwarder);
-  installStrategy<NccStrategy>(forwarder);
-  installStrategy<BestRouteStrategy2>(forwarder);
-}
-
-} // namespace fw
-} // namespace nfd
diff --git a/NFD/daemon/fw/available-strategies.hpp b/NFD/daemon/fw/available-strategies.hpp
deleted file mode 100644
index 616a1b4..0000000
--- a/NFD/daemon/fw/available-strategies.hpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#ifndef NFD_DAEMON_FW_AVAILABLE_STRATEGIES_HPP
-#define NFD_DAEMON_FW_AVAILABLE_STRATEGIES_HPP
-
-#include "strategy.hpp"
-
-namespace nfd {
-namespace fw {
-
-shared_ptr<Strategy>
-makeDefaultStrategy(Forwarder& forwarder);
-
-void
-installStrategies(Forwarder& forwarder);
-
-} // namespace fw
-} // namespace nfd
-
-#endif // NFD_DAEMON_FW_AVAILABLE_STRATEGIES_HPP
diff --git a/NFD/daemon/fw/best-route-strategy.cpp b/NFD/daemon/fw/best-route-strategy.cpp
deleted file mode 100644
index f64bb66..0000000
--- a/NFD/daemon/fw/best-route-strategy.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "best-route-strategy.hpp"
-
-namespace nfd {
-namespace fw {
-
-const Name BestRouteStrategy::STRATEGY_NAME("ndn:/localhost/nfd/strategy/best-route/%FD%01");
-
-BestRouteStrategy::BestRouteStrategy(Forwarder& forwarder, const Name& name)
-  : Strategy(forwarder, name)
-{
-}
-
-BestRouteStrategy::~BestRouteStrategy()
-{
-}
-
-static inline bool
-predicate_PitEntry_canForwardTo_NextHop(shared_ptr<pit::Entry> pitEntry,
-                                        const fib::NextHop& nexthop)
-{
-  return pitEntry->canForwardTo(*nexthop.getFace());
-}
-
-void
-BestRouteStrategy::afterReceiveInterest(const Face& inFace,
-                   const Interest& interest,
-                   shared_ptr<fib::Entry> fibEntry,
-                   shared_ptr<pit::Entry> pitEntry)
-{
-  if (pitEntry->hasUnexpiredOutRecords()) {
-    // not a new Interest, don't forward
-    return;
-  }
-
-  const fib::NextHopList& nexthops = fibEntry->getNextHops();
-  fib::NextHopList::const_iterator it = std::find_if(nexthops.begin(), nexthops.end(),
-    bind(&predicate_PitEntry_canForwardTo_NextHop, pitEntry, _1));
-
-  if (it == nexthops.end()) {
-    this->rejectPendingInterest(pitEntry);
-    return;
-  }
-
-  shared_ptr<Face> outFace = it->getFace();
-  this->sendInterest(pitEntry, outFace);
-}
-
-} // namespace fw
-} // namespace nfd
diff --git a/NFD/daemon/fw/best-route-strategy.hpp b/NFD/daemon/fw/best-route-strategy.hpp
deleted file mode 100644
index 7ec64ff..0000000
--- a/NFD/daemon/fw/best-route-strategy.hpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_FW_BEST_ROUTE_STRATEGY_HPP
-#define NFD_DAEMON_FW_BEST_ROUTE_STRATEGY_HPP
-
-#include "strategy.hpp"
-
-namespace nfd {
-namespace fw {
-
-/** \brief Best Route strategy version 1
- *
- *  This strategy forwards a new Interest to the lowest-cost nexthop
- *  that is not same as the downstream, and does not violate scope.
- *  Subsequent similar Interests or consumer retransmissions are suppressed
- *  until after InterestLifetime expiry.
- *
- *  \deprecated This strategy is superceded by Best Route strategy version 2,
- *              which allows consumer retransmissions. This version is kept for
- *              comparison purposes and is not recommended for general usage.
- */
-class BestRouteStrategy : public Strategy
-{
-public:
-  BestRouteStrategy(Forwarder& forwarder, const Name& name = STRATEGY_NAME);
-
-  virtual
-  ~BestRouteStrategy();
-
-  virtual void
-  afterReceiveInterest(const Face& inFace,
-                       const Interest& interest,
-                       shared_ptr<fib::Entry> fibEntry,
-                       shared_ptr<pit::Entry> pitEntry) DECL_OVERRIDE;
-
-public:
-  static const Name STRATEGY_NAME;
-};
-
-} // namespace fw
-} // namespace nfd
-
-#endif // NFD_DAEMON_FW_BEST_ROUTE_STRATEGY_HPP
diff --git a/NFD/daemon/fw/best-route-strategy2.cpp b/NFD/daemon/fw/best-route-strategy2.cpp
deleted file mode 100644
index 044f5e9..0000000
--- a/NFD/daemon/fw/best-route-strategy2.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "best-route-strategy2.hpp"
-#include "core/logger.hpp"
-
-namespace nfd {
-namespace fw {
-
-NFD_LOG_INIT("BestRouteStrategy2");
-
-const Name BestRouteStrategy2::STRATEGY_NAME("ndn:/localhost/nfd/strategy/best-route/%FD%02");
-/// \todo don't use fixed interval; make it adaptive or use exponential back-off #1913
-const time::milliseconds BestRouteStrategy2::MIN_RETRANSMISSION_INTERVAL(100);
-
-BestRouteStrategy2::BestRouteStrategy2(Forwarder& forwarder, const Name& name)
-  : Strategy(forwarder, name)
-{
-}
-
-/** \brief determines whether a NextHop is eligible
- *  \param currentDownstream incoming FaceId of current Interest
- *  \param wantUnused if true, NextHop must not have unexpired OutRecord
- *  \param now time::steady_clock::now(), ignored if !wantUnused
- */
-static inline bool
-predicate_NextHop_eligible(const shared_ptr<pit::Entry>& pitEntry,
-  const fib::NextHop& nexthop, FaceId currentDownstream,
-  bool wantUnused = false,
-  time::steady_clock::TimePoint now = time::steady_clock::TimePoint::min())
-{
-  shared_ptr<Face> upstream = nexthop.getFace();
-
-  // upstream is current downstream
-  if (upstream->getId() == currentDownstream)
-    return false;
-
-  // forwarding would violate scope
-  if (pitEntry->violatesScope(*upstream))
-    return false;
-
-  if (wantUnused) {
-    // NextHop must not have unexpired OutRecord
-    pit::OutRecordCollection::const_iterator outRecord = pitEntry->getOutRecord(*upstream);
-    if (outRecord != pitEntry->getOutRecords().end() &&
-        outRecord->getExpiry() > now) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-static inline bool
-compare_OutRecord_lastRenewed(const pit::OutRecord& a, const pit::OutRecord& b)
-{
-  return a.getLastRenewed() < b.getLastRenewed();
-}
-
-/** \brief pick an eligible NextHop with earliest OutRecord
- *  \note It is assumed that every nexthop has an OutRecord
- */
-static inline fib::NextHopList::const_iterator
-findEligibleNextHopWithEarliestOutRecord(const shared_ptr<pit::Entry>& pitEntry,
-                                         const fib::NextHopList& nexthops,
-                                         FaceId currentDownstream)
-{
-  fib::NextHopList::const_iterator found = nexthops.end();
-  time::steady_clock::TimePoint earliestRenewed = time::steady_clock::TimePoint::max();
-  for (fib::NextHopList::const_iterator it = nexthops.begin(); it != nexthops.end(); ++it) {
-    if (!predicate_NextHop_eligible(pitEntry, *it, currentDownstream))
-      continue;
-    pit::OutRecordCollection::const_iterator outRecord = pitEntry->getOutRecord(*it->getFace());
-    BOOST_ASSERT(outRecord != pitEntry->getOutRecords().end());
-    if (outRecord->getLastRenewed() < earliestRenewed) {
-      found = it;
-      earliestRenewed = outRecord->getLastRenewed();
-    }
-  }
-  return found;
-}
-
-void
-BestRouteStrategy2::afterReceiveInterest(const Face& inFace,
-                                         const Interest& interest,
-                                         shared_ptr<fib::Entry> fibEntry,
-                                         shared_ptr<pit::Entry> pitEntry)
-{
-  const fib::NextHopList& nexthops = fibEntry->getNextHops();
-  fib::NextHopList::const_iterator it = nexthops.end();
-
-  bool isNewPitEntry = !pitEntry->hasUnexpiredOutRecords();
-  if (isNewPitEntry) {
-    // forward to nexthop with lowest cost except downstream
-    it = std::find_if(nexthops.begin(), nexthops.end(),
-      bind(&predicate_NextHop_eligible, pitEntry, _1, inFace.getId(),
-           false, time::steady_clock::TimePoint::min()));
-
-    if (it == nexthops.end()) {
-      NFD_LOG_DEBUG(interest << " from=" << inFace.getId() << " noNextHop");
-      this->rejectPendingInterest(pitEntry);
-      return;
-    }
-
-    shared_ptr<Face> outFace = it->getFace();
-    this->sendInterest(pitEntry, outFace);
-    NFD_LOG_DEBUG(interest << " from=" << inFace.getId()
-                           << " newPitEntry-to=" << outFace->getId());
-    return;
-  }
-
-  // when was the last outgoing Interest?
-  const pit::OutRecordCollection& outRecords = pitEntry->getOutRecords();
-  pit::OutRecordCollection::const_iterator lastOutgoing = std::max_element(
-    outRecords.begin(), outRecords.end(), &compare_OutRecord_lastRenewed);
-  BOOST_ASSERT(lastOutgoing != outRecords.end()); // otherwise it's new PIT entry
-
-  time::steady_clock::TimePoint now = time::steady_clock::now();
-  time::steady_clock::Duration sinceLastOutgoing = now - lastOutgoing->getLastRenewed();
-  bool shouldRetransmit = sinceLastOutgoing >= MIN_RETRANSMISSION_INTERVAL;
-  if (!shouldRetransmit) {
-    NFD_LOG_DEBUG(interest << " from=" << inFace.getId()
-                           << " dontRetransmit sinceLastOutgoing=" << sinceLastOutgoing.count());
-    return;
-  }
-
-  // find an unused upstream with lowest cost except downstream
-  it = std::find_if(nexthops.begin(), nexthops.end(),
-    bind(&predicate_NextHop_eligible, pitEntry, _1, inFace.getId(), true, now));
-  if (it != nexthops.end()) {
-    shared_ptr<Face> outFace = it->getFace();
-    this->sendInterest(pitEntry, outFace);
-    NFD_LOG_DEBUG(interest << " from=" << inFace.getId()
-                           << " retransmit-unused-to=" << outFace->getId());
-    return;
-  }
-
-  // find an eligible upstream that is used earliest
-  it = findEligibleNextHopWithEarliestOutRecord(pitEntry, nexthops, inFace.getId());
-  if (it == nexthops.end()) {
-    NFD_LOG_DEBUG(interest << " from=" << inFace.getId() << " retransmitNoNextHop");
-  }
-  else {
-    shared_ptr<Face> outFace = it->getFace();
-    this->sendInterest(pitEntry, outFace);
-    NFD_LOG_DEBUG(interest << " from=" << inFace.getId()
-                           << " retransmit-retry-to=" << outFace->getId());
-  }
-}
-
-} // namespace fw
-} // namespace nfd
diff --git a/NFD/daemon/fw/best-route-strategy2.hpp b/NFD/daemon/fw/best-route-strategy2.hpp
deleted file mode 100644
index bb259d0..0000000
--- a/NFD/daemon/fw/best-route-strategy2.hpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_FW_BEST_ROUTE_STRATEGY2_HPP
-#define NFD_DAEMON_FW_BEST_ROUTE_STRATEGY2_HPP
-
-#include "strategy.hpp"
-
-namespace nfd {
-namespace fw {
-
-/** \brief Best Route strategy version 2
- *
- *  This strategy forwards a new Interest to the lowest-cost nexthop (except downstream).
- *  After that, it recognizes consumer retransmission:
- *  if a similar Interest arrives from any downstream after MIN_RETRANSMISSION_INTERVAL,
- *  the strategy forwards the Interest again to the lowest-cost nexthop (except downstream)
- *  that is not previously used. If all nexthops have been used, the strategy starts over.
- */
-class BestRouteStrategy2 : public Strategy
-{
-public:
-  BestRouteStrategy2(Forwarder& forwarder, const Name& name = STRATEGY_NAME);
-
-  virtual void
-  afterReceiveInterest(const Face& inFace,
-                       const Interest& interest,
-                       shared_ptr<fib::Entry> fibEntry,
-                       shared_ptr<pit::Entry> pitEntry) DECL_OVERRIDE;
-
-public:
-  static const Name STRATEGY_NAME;
-  static const time::milliseconds MIN_RETRANSMISSION_INTERVAL;
-};
-
-} // namespace fw
-} // namespace nfd
-
-#endif // NFD_DAEMON_FW_BEST_ROUTE_STRATEGY2_HPP
diff --git a/NFD/daemon/fw/broadcast-strategy.cpp b/NFD/daemon/fw/broadcast-strategy.cpp
deleted file mode 100644
index 48ab17b..0000000
--- a/NFD/daemon/fw/broadcast-strategy.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "broadcast-strategy.hpp"
-
-namespace nfd {
-namespace fw {
-
-const Name BroadcastStrategy::STRATEGY_NAME("ndn:/localhost/nfd/strategy/broadcast/%FD%01");
-
-BroadcastStrategy::BroadcastStrategy(Forwarder& forwarder, const Name& name)
-  : Strategy(forwarder, name)
-{
-}
-
-BroadcastStrategy::~BroadcastStrategy()
-{
-}
-
-void
-BroadcastStrategy::afterReceiveInterest(const Face& inFace,
-                   const Interest& interest,
-                   shared_ptr<fib::Entry> fibEntry,
-                   shared_ptr<pit::Entry> pitEntry)
-{
-  const fib::NextHopList& nexthops = fibEntry->getNextHops();
-
-  for (fib::NextHopList::const_iterator it = nexthops.begin(); it != nexthops.end(); ++it) {
-    shared_ptr<Face> outFace = it->getFace();
-    if (pitEntry->canForwardTo(*outFace)) {
-      this->sendInterest(pitEntry, outFace);
-    }
-  }
-
-  if (!pitEntry->hasUnexpiredOutRecords()) {
-    this->rejectPendingInterest(pitEntry);
-  }
-}
-
-} // namespace fw
-} // namespace nfd
diff --git a/NFD/daemon/fw/broadcast-strategy.hpp b/NFD/daemon/fw/broadcast-strategy.hpp
deleted file mode 100644
index 0807bde..0000000
--- a/NFD/daemon/fw/broadcast-strategy.hpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_FW_BROADCAST_STRATEGY_HPP
-#define NFD_DAEMON_FW_BROADCAST_STRATEGY_HPP
-
-#include "strategy.hpp"
-
-namespace nfd {
-namespace fw {
-
-/** \class BroadcastStrategy
- *  \brief a forwarding strategy that forwards Interest
- *         to all nexthops
- */
-class BroadcastStrategy : public Strategy
-{
-public:
-  BroadcastStrategy(Forwarder& forwarder, const Name& name = STRATEGY_NAME);
-
-  virtual
-  ~BroadcastStrategy();
-
-  virtual void
-  afterReceiveInterest(const Face& inFace,
-                       const Interest& interest,
-                       shared_ptr<fib::Entry> fibEntry,
-                       shared_ptr<pit::Entry> pitEntry) DECL_OVERRIDE;
-
-public:
-  static const Name STRATEGY_NAME;
-};
-
-} // namespace fw
-} // namespace nfd
-
-#endif // NFD_DAEMON_FW_BROADCAST_STRATEGY_HPP
diff --git a/NFD/daemon/fw/client-control-strategy.cpp b/NFD/daemon/fw/client-control-strategy.cpp
deleted file mode 100644
index d3700e3..0000000
--- a/NFD/daemon/fw/client-control-strategy.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "client-control-strategy.hpp"
-#include "core/logger.hpp"
-
-namespace nfd {
-namespace fw {
-
-NFD_LOG_INIT("ClientControlStrategy");
-
-const Name
-ClientControlStrategy::STRATEGY_NAME("ndn:/localhost/nfd/strategy/client-control/%FD%01");
-
-ClientControlStrategy::ClientControlStrategy(Forwarder& forwarder, const Name& name)
-  : BestRouteStrategy(forwarder, name)
-{
-}
-
-ClientControlStrategy::~ClientControlStrategy()
-{
-}
-
-void
-ClientControlStrategy::afterReceiveInterest(const Face& inFace,
-                                            const Interest& interest,
-                                            shared_ptr<fib::Entry> fibEntry,
-                                            shared_ptr<pit::Entry> pitEntry)
-{
-  // Strategy needn't check whether LocalControlHeader-NextHopFaceId is enabled.
-  // LocalFace does this check.
-  if (!interest.getLocalControlHeader().hasNextHopFaceId()) {
-    this->BestRouteStrategy::afterReceiveInterest(inFace, interest, fibEntry, pitEntry);
-    return;
-  }
-
-  FaceId outFaceId = static_cast<FaceId>(interest.getNextHopFaceId());
-  shared_ptr<Face> outFace = this->getFace(outFaceId);
-  if (!static_cast<bool>(outFace)) {
-    // If outFace doesn't exist, it's better to reject the Interest
-    // than to use BestRouteStrategy.
-    NFD_LOG_WARN("Interest " << interest.getName() <<
-                 " NextHopFaceId=" << outFaceId << " non-existent face");
-    this->rejectPendingInterest(pitEntry);
-    return;
-  }
-
-  this->sendInterest(pitEntry, outFace);
-}
-
-} // namespace fw
-} // namespace nfd
diff --git a/NFD/daemon/fw/client-control-strategy.hpp b/NFD/daemon/fw/client-control-strategy.hpp
deleted file mode 100644
index a0ddbf2..0000000
--- a/NFD/daemon/fw/client-control-strategy.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_FW_CLIENT_CONTROL_STRATEGY_HPP
-#define NFD_DAEMON_FW_CLIENT_CONTROL_STRATEGY_HPP
-
-#include "best-route-strategy.hpp"
-
-namespace nfd {
-namespace fw {
-
-/** \brief a forwarding strategy that forwards Interests
- *         according to NextHopFaceId field in LocalControlHeader
- */
-class ClientControlStrategy : public BestRouteStrategy
-{
-public:
-  ClientControlStrategy(Forwarder& forwarder, const Name& name = STRATEGY_NAME);
-
-  virtual
-  ~ClientControlStrategy();
-
-  virtual void
-  afterReceiveInterest(const Face& inFace,
-                       const Interest& interest,
-                       shared_ptr<fib::Entry> fibEntry,
-                       shared_ptr<pit::Entry> pitEntry) DECL_OVERRIDE;
-
-public:
-  static const Name STRATEGY_NAME;
-};
-
-} // namespace fw
-} // namespace nfd
-
-#endif // NFD_DAEMON_FW_CLIENT_CONTROL_STRATEGY_HPP
diff --git a/NFD/daemon/fw/face-table.cpp b/NFD/daemon/fw/face-table.cpp
deleted file mode 100644
index f1db53b..0000000
--- a/NFD/daemon/fw/face-table.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "face-table.hpp"
-#include "forwarder.hpp"
-#include "core/logger.hpp"
-
-namespace nfd {
-
-NFD_LOG_INIT("FaceTable");
-
-FaceTable::FaceTable(Forwarder& forwarder)
-  : m_forwarder(forwarder)
-  , m_lastFaceId(FACEID_RESERVED_MAX)
-{
-}
-
-FaceTable::~FaceTable()
-{
-
-}
-
-shared_ptr<Face>
-FaceTable::get(FaceId id) const
-{
-  std::map<FaceId, shared_ptr<Face> >::const_iterator i = m_faces.find(id);
-  return (i == m_faces.end()) ? (shared_ptr<Face>()) : (i->second);
-}
-
-size_t
-FaceTable::size() const
-{
-  return m_faces.size();
-}
-
-void
-FaceTable::add(shared_ptr<Face> face)
-{
-  if (face->getId() != INVALID_FACEID && m_faces.count(face->getId()) > 0) {
-    NFD_LOG_WARN("Trying to add existing face id=" << face->getId() << " to the face table");
-    return;
-  }
-
-  FaceId faceId = ++m_lastFaceId;
-  BOOST_ASSERT(faceId > FACEID_RESERVED_MAX);
-  this->addImpl(face, faceId);
-}
-
-void
-FaceTable::addReserved(shared_ptr<Face> face, FaceId faceId)
-{
-  BOOST_ASSERT(face->getId() == INVALID_FACEID);
-  BOOST_ASSERT(m_faces.count(face->getId()) == 0);
-  BOOST_ASSERT(faceId <= FACEID_RESERVED_MAX);
-  this->addImpl(face, faceId);
-}
-
-void
-FaceTable::addImpl(shared_ptr<Face> face, FaceId faceId)
-{
-  face->setId(faceId);
-  m_faces[faceId] = face;
-  NFD_LOG_INFO("Added face id=" << faceId << " remote=" << face->getRemoteUri()
-                                          << " local=" << face->getLocalUri());
-
-  face->onReceiveInterest += bind(&Forwarder::onInterest,
-                                  &m_forwarder, ref(*face), _1);
-  face->onReceiveData     += bind(&Forwarder::onData,
-                                  &m_forwarder, ref(*face), _1);
-  face->onFail            += bind(&FaceTable::remove,
-                                  this, face);
-
-  this->onAdd(face);
-}
-
-void
-FaceTable::remove(shared_ptr<Face> face)
-{
-  this->onRemove(face);
-
-  FaceId faceId = face->getId();
-  m_faces.erase(faceId);
-  face->setId(INVALID_FACEID);
-  NFD_LOG_INFO("Removed face id=" << faceId << " remote=" << face->getRemoteUri() <<
-                                                 " local=" << face->getLocalUri());
-
-  // XXX This clears all subscriptions, because EventEmitter
-  //     does not support only removing Forwarder's subscription
-  face->onReceiveInterest.clear();
-  face->onReceiveData    .clear();
-  face->onSendInterest   .clear();
-  face->onSendData       .clear();
-  // don't clear onFail because other functions may need to execute
-
-  m_forwarder.getFib().removeNextHopFromAllEntries(face);
-}
-
-FaceTable::ForwardRange
-FaceTable::getForwardRange() const
-{
-  return m_faces | boost::adaptors::map_values;
-}
-
-FaceTable::const_iterator
-FaceTable::begin() const
-{
-  return this->getForwardRange().begin();
-}
-
-FaceTable::const_iterator
-FaceTable::end() const
-{
-  return this->getForwardRange().end();
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/fw/face-table.hpp b/NFD/daemon/fw/face-table.hpp
deleted file mode 100644
index 435999e..0000000
--- a/NFD/daemon/fw/face-table.hpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_FW_FACE_TABLE_HPP
-#define NFD_DAEMON_FW_FACE_TABLE_HPP
-
-#include "face/face.hpp"
-#include <boost/range/adaptor/map.hpp>
-
-namespace nfd {
-
-class Forwarder;
-
-/** \brief container of all Faces
- */
-class FaceTable : noncopyable
-{
-public:
-  explicit
-  FaceTable(Forwarder& forwarder);
-
-  VIRTUAL_WITH_TESTS
-  ~FaceTable();
-
-  VIRTUAL_WITH_TESTS void
-  add(shared_ptr<Face> face);
-
-  /// add a special Face with a reserved FaceId
-  VIRTUAL_WITH_TESTS void
-  addReserved(shared_ptr<Face> face, FaceId faceId);
-
-  VIRTUAL_WITH_TESTS shared_ptr<Face>
-  get(FaceId id) const;
-
-  size_t
-  size() const;
-
-public: // enumeration
-  typedef std::map<FaceId, shared_ptr<Face>> FaceMap;
-
-  typedef boost::select_second_const_range<FaceMap> ForwardRange;
-
-  /** \brief ForwardIterator for shared_ptr<Face>
-   */
-  typedef boost::range_iterator<ForwardRange>::type const_iterator;
-
-  const_iterator
-  begin() const;
-
-  const_iterator
-  end() const;
-
-public: // signals
-  /** \brief fires after a Face is added
-   */
-  signal::Signal<FaceTable, shared_ptr<Face>> onAdd;
-
-  /** \brief fires before a Face is removed
-   *
-   *  FaceId is valid when this event is fired
-   */
-  signal::Signal<FaceTable, shared_ptr<Face>> onRemove;
-
-private:
-  void
-  addImpl(shared_ptr<Face> face, FaceId faceId);
-
-  // remove is private because it's a subscriber of face.onFail event.
-  // face->close() closes a face and triggers .remove(face)
-  void
-  remove(shared_ptr<Face> face);
-
-  ForwardRange
-  getForwardRange() const;
-
-private:
-  Forwarder& m_forwarder;
-  FaceId m_lastFaceId;
-  FaceMap m_faces;
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_FW_FACE_TABLE_HPP
diff --git a/NFD/daemon/fw/forwarder-counters.hpp b/NFD/daemon/fw/forwarder-counters.hpp
deleted file mode 100644
index ba3b57c..0000000
--- a/NFD/daemon/fw/forwarder-counters.hpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_FW_FORWARDER_COUNTERS_HPP
-#define NFD_DAEMON_FW_FORWARDER_COUNTERS_HPP
-
-#include "face/face-counters.hpp"
-
-namespace nfd {
-
-/** \brief contains counters on forwarder
- */
-class ForwarderCounters : public NetworkLayerCounters
-{
-public:
-  /** \brief copy current obseverations to a struct
-   *  \param recipient an object with set methods for counters
-   */
-  template<typename R>
-  void
-  copyTo(R& recipient) const
-  {
-    this->NetworkLayerCounters::copyTo(recipient);
-  }
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_FW_FORWARDER_COUNTERS_HPP
diff --git a/NFD/daemon/fw/forwarder.cpp b/NFD/daemon/fw/forwarder.cpp
deleted file mode 100644
index 8b8b11f..0000000
--- a/NFD/daemon/fw/forwarder.cpp
+++ /dev/null
@@ -1,479 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "forwarder.hpp"
-#include "core/logger.hpp"
-#include "core/random.hpp"
-#include "face/null-face.hpp"
-#include "available-strategies.hpp"
-
-#include "utils/ndn-ns3-packet-tag.hpp"
-
-#include <boost/random/uniform_int_distribution.hpp>
-
-namespace nfd {
-
-NFD_LOG_INIT("Forwarder");
-
-using fw::Strategy;
-
-const Name Forwarder::LOCALHOST_NAME("ndn:/localhost");
-
-Forwarder::Forwarder()
-  : m_faceTable(*this)
-  , m_fib(m_nameTree)
-  , m_pit(m_nameTree)
-  , m_measurements(m_nameTree)
-  , m_strategyChoice(m_nameTree, fw::makeDefaultStrategy(*this))
-  , m_csFace(make_shared<NullFace>(FaceUri("contentstore://")))
-{
-  fw::installStrategies(*this);
-  getFaceTable().addReserved(m_csFace, FACEID_CONTENT_STORE);
-}
-
-Forwarder::~Forwarder()
-{
-
-}
-
-void
-Forwarder::onIncomingInterest(Face& inFace, const Interest& interest)
-{
-  // receive Interest
-  NFD_LOG_DEBUG("onIncomingInterest face=" << inFace.getId() <<
-                " interest=" << interest.getName());
-  const_cast<Interest&>(interest).setIncomingFaceId(inFace.getId());
-  ++m_counters.getNInInterests();
-
-  // /localhost scope control
-  bool isViolatingLocalhost = !inFace.isLocal() &&
-                              LOCALHOST_NAME.isPrefixOf(interest.getName());
-  if (isViolatingLocalhost) {
-    NFD_LOG_DEBUG("onIncomingInterest face=" << inFace.getId() <<
-                  " interest=" << interest.getName() << " violates /localhost");
-    // (drop)
-    return;
-  }
-
-  // PIT insert
-  shared_ptr<pit::Entry> pitEntry = m_pit.insert(interest).first;
-
-  // detect duplicate Nonce
-  int dnw = pitEntry->findNonce(interest.getNonce(), inFace);
-  bool hasDuplicateNonce = (dnw != pit::DUPLICATE_NONCE_NONE) ||
-                           m_deadNonceList.has(interest.getName(), interest.getNonce());
-  if (hasDuplicateNonce) {
-    // goto Interest loop pipeline
-    this->onInterestLoop(inFace, interest, pitEntry);
-    return;
-  }
-
-  // cancel unsatisfy & straggler timer
-  this->cancelUnsatisfyAndStragglerTimer(pitEntry);
-
-  // is pending?
-  const pit::InRecordCollection& inRecords = pitEntry->getInRecords();
-  bool isPending = inRecords.begin() != inRecords.end();
-  if (!isPending) {
-    // CS lookup
-    const Data* csMatch;
-    shared_ptr<Data> match;
-    if (m_csFromNdnSim == nullptr)
-      csMatch = m_cs.find(interest);
-    else {
-      match = m_csFromNdnSim->Lookup(interest.shared_from_this());
-      csMatch = match.get();
-    }
-    if (csMatch != 0) {
-      const_cast<Data*>(csMatch)->setIncomingFaceId(FACEID_CONTENT_STORE);
-      // XXX should we lookup PIT for other Interests that also match csMatch?
-
-      // invoke PIT satisfy callback
-      beforeSatisfyInterest(*pitEntry, *m_csFace, *csMatch);
-      this->dispatchToStrategy(pitEntry, bind(&Strategy::beforeSatisfyInterest, _1,
-                                              pitEntry, cref(*m_csFace), cref(*csMatch)));
-      // set PIT straggler timer
-      this->setStragglerTimer(pitEntry, true, csMatch->getFreshnessPeriod());
-
-      // goto outgoing Data pipeline
-      this->onOutgoingData(*csMatch, inFace);
-      return;
-    }
-  }
-
-  // insert InRecord
-  pitEntry->insertOrUpdateInRecord(inFace.shared_from_this(), interest);
-
-  // set PIT unsatisfy timer
-  this->setUnsatisfyTimer(pitEntry);
-
-  // FIB lookup
-  shared_ptr<fib::Entry> fibEntry = m_fib.findLongestPrefixMatch(*pitEntry);
-
-  // dispatch to strategy
-  this->dispatchToStrategy(pitEntry, bind(&Strategy::afterReceiveInterest, _1,
-                                          cref(inFace), cref(interest), fibEntry, pitEntry));
-}
-
-void
-Forwarder::onInterestLoop(Face& inFace, const Interest& interest,
-                          shared_ptr<pit::Entry> pitEntry)
-{
-  NFD_LOG_DEBUG("onInterestLoop face=" << inFace.getId() <<
-                " interest=" << interest.getName());
-
-  // (drop)
-}
-
-/** \brief compare two InRecords for picking outgoing Interest
- *  \return true if b is preferred over a
- *
- *  This function should be passed to std::max_element over InRecordCollection.
- *  The outgoing Interest picked is the last incoming Interest
- *  that does not come from outFace.
- *  If all InRecords come from outFace, it's fine to pick that. This happens when
- *  there's only one InRecord that comes from outFace. The legit use is for
- *  vehicular network; otherwise, strategy shouldn't send to the sole inFace.
- */
-static inline bool
-compare_pickInterest(const pit::InRecord& a, const pit::InRecord& b, const Face* outFace)
-{
-  bool isOutFaceA = a.getFace().get() == outFace;
-  bool isOutFaceB = b.getFace().get() == outFace;
-
-  if (!isOutFaceA && isOutFaceB) {
-    return false;
-  }
-  if (isOutFaceA && !isOutFaceB) {
-    return true;
-  }
-
-  return a.getLastRenewed() > b.getLastRenewed();
-}
-
-void
-Forwarder::onOutgoingInterest(shared_ptr<pit::Entry> pitEntry, Face& outFace,
-                              bool wantNewNonce)
-{
-  if (outFace.getId() == INVALID_FACEID) {
-    NFD_LOG_WARN("onOutgoingInterest face=invalid interest=" << pitEntry->getName());
-    return;
-  }
-  NFD_LOG_DEBUG("onOutgoingInterest face=" << outFace.getId() <<
-                " interest=" << pitEntry->getName());
-
-  // scope control
-  if (pitEntry->violatesScope(outFace)) {
-    NFD_LOG_DEBUG("onOutgoingInterest face=" << outFace.getId() <<
-                  " interest=" << pitEntry->getName() << " violates scope");
-    return;
-  }
-
-  // pick Interest
-  const pit::InRecordCollection& inRecords = pitEntry->getInRecords();
-  pit::InRecordCollection::const_iterator pickedInRecord = std::max_element(
-    inRecords.begin(), inRecords.end(), bind(&compare_pickInterest, _1, _2, &outFace));
-  BOOST_ASSERT(pickedInRecord != inRecords.end());
-  shared_ptr<Interest> interest = const_pointer_cast<Interest>(
-    pickedInRecord->getInterest().shared_from_this());
-
-  if (wantNewNonce) {
-    interest = make_shared<Interest>(*interest);
-    static boost::random::uniform_int_distribution<uint32_t> dist;
-    interest->setNonce(dist(getGlobalRng()));
-  }
-
-  // insert OutRecord
-  pitEntry->insertOrUpdateOutRecord(outFace.shared_from_this(), *interest);
-
-  // send Interest
-  outFace.sendInterest(*interest);
-  ++m_counters.getNOutInterests();
-}
-
-void
-Forwarder::onInterestReject(shared_ptr<pit::Entry> pitEntry)
-{
-  if (pitEntry->hasUnexpiredOutRecords()) {
-    NFD_LOG_ERROR("onInterestReject interest=" << pitEntry->getName() <<
-                  " cannot reject forwarded Interest");
-    return;
-  }
-  NFD_LOG_DEBUG("onInterestReject interest=" << pitEntry->getName());
-
-  // cancel unsatisfy & straggler timer
-  this->cancelUnsatisfyAndStragglerTimer(pitEntry);
-
-  // set PIT straggler timer
-  this->setStragglerTimer(pitEntry, false);
-}
-
-void
-Forwarder::onInterestUnsatisfied(shared_ptr<pit::Entry> pitEntry)
-{
-  NFD_LOG_DEBUG("onInterestUnsatisfied interest=" << pitEntry->getName());
-
-  // invoke PIT unsatisfied callback
-  beforeExpirePendingInterest(*pitEntry);
-  this->dispatchToStrategy(pitEntry, bind(&Strategy::beforeExpirePendingInterest, _1,
-                                          pitEntry));
-
-  // goto Interest Finalize pipeline
-  this->onInterestFinalize(pitEntry, false);
-}
-
-void
-Forwarder::onInterestFinalize(shared_ptr<pit::Entry> pitEntry, bool isSatisfied,
-                              const time::milliseconds& dataFreshnessPeriod)
-{
-  NFD_LOG_DEBUG("onInterestFinalize interest=" << pitEntry->getName() <<
-                (isSatisfied ? " satisfied" : " unsatisfied"));
-
-  // Dead Nonce List insert if necessary
-  this->insertDeadNonceList(*pitEntry, isSatisfied, dataFreshnessPeriod, 0);
-
-  // PIT delete
-  this->cancelUnsatisfyAndStragglerTimer(pitEntry);
-  m_pit.erase(pitEntry);
-}
-
-void
-Forwarder::onIncomingData(Face& inFace, const Data& data)
-{
-  // receive Data
-  NFD_LOG_DEBUG("onIncomingData face=" << inFace.getId() << " data=" << data.getName());
-  const_cast<Data&>(data).setIncomingFaceId(inFace.getId());
-  ++m_counters.getNInDatas();
-
-  // /localhost scope control
-  bool isViolatingLocalhost = !inFace.isLocal() &&
-                              LOCALHOST_NAME.isPrefixOf(data.getName());
-  if (isViolatingLocalhost) {
-    NFD_LOG_DEBUG("onIncomingData face=" << inFace.getId() <<
-                  " data=" << data.getName() << " violates /localhost");
-    // (drop)
-    return;
-  }
-
-  // PIT match
-  pit::DataMatchResult pitMatches = m_pit.findAllDataMatches(data);
-  if (pitMatches.begin() == pitMatches.end()) {
-    // goto Data unsolicited pipeline
-    this->onDataUnsolicited(inFace, data);
-    return;
-  }
-
-  // Remove Ptr<Packet> from the Data before inserting into cache, serving two purposes
-  // - reduce amount of memory used by cached entries
-  // - remove all tags that (e.g., hop count tag) that could have been associated with Ptr<Packet>
-  //
-  // Copying of Data is relatively cheap operation, as it copies (mostly) a collection of Blocks
-  // pointing to the same underlying memory buffer.
-  shared_ptr<Data> dataCopyWithoutPacket = make_shared<Data>(data);
-  dataCopyWithoutPacket->removeTag<ns3::ndn::Ns3PacketTag>();
-
-  // CS insert
-  if (m_csFromNdnSim == nullptr)
-    m_cs.insert(*dataCopyWithoutPacket);
-  else
-    m_csFromNdnSim->Add(dataCopyWithoutPacket);
-
-  std::set<shared_ptr<Face> > pendingDownstreams;
-  // foreach PitEntry
-  for (const shared_ptr<pit::Entry>& pitEntry : pitMatches) {
-    NFD_LOG_DEBUG("onIncomingData matching=" << pitEntry->getName());
-
-    // cancel unsatisfy & straggler timer
-    this->cancelUnsatisfyAndStragglerTimer(pitEntry);
-
-    // remember pending downstreams
-    const pit::InRecordCollection& inRecords = pitEntry->getInRecords();
-    for (pit::InRecordCollection::const_iterator it = inRecords.begin();
-                                                 it != inRecords.end(); ++it) {
-      if (it->getExpiry() > time::steady_clock::now()) {
-        pendingDownstreams.insert(it->getFace());
-      }
-    }
-
-    // invoke PIT satisfy callback
-    beforeSatisfyInterest(*pitEntry, inFace, data);
-    this->dispatchToStrategy(pitEntry, bind(&Strategy::beforeSatisfyInterest, _1,
-                                            pitEntry, cref(inFace), cref(data)));
-
-    // Dead Nonce List insert if necessary (for OutRecord of inFace)
-    this->insertDeadNonceList(*pitEntry, true, data.getFreshnessPeriod(), &inFace);
-
-    // mark PIT satisfied
-    pitEntry->deleteInRecords();
-    pitEntry->deleteOutRecord(inFace);
-
-    // set PIT straggler timer
-    this->setStragglerTimer(pitEntry, true, data.getFreshnessPeriod());
-  }
-
-  // foreach pending downstream
-  for (std::set<shared_ptr<Face> >::iterator it = pendingDownstreams.begin();
-      it != pendingDownstreams.end(); ++it) {
-    shared_ptr<Face> pendingDownstream = *it;
-    if (pendingDownstream.get() == &inFace) {
-      continue;
-    }
-    // goto outgoing Data pipeline
-    this->onOutgoingData(data, *pendingDownstream);
-  }
-}
-
-void
-Forwarder::onDataUnsolicited(Face& inFace, const Data& data)
-{
-  // accept to cache?
-  bool acceptToCache = inFace.isLocal();
-  if (acceptToCache) {
-    // CS insert
-    if (m_csFromNdnSim == nullptr)
-      m_cs.insert(data, true);
-    else
-      m_csFromNdnSim->Add(data.shared_from_this());
-  }
-
-  NFD_LOG_DEBUG("onDataUnsolicited face=" << inFace.getId() <<
-                " data=" << data.getName() <<
-                (acceptToCache ? " cached" : " not cached"));
-}
-
-void
-Forwarder::onOutgoingData(const Data& data, Face& outFace)
-{
-  if (outFace.getId() == INVALID_FACEID) {
-    NFD_LOG_WARN("onOutgoingData face=invalid data=" << data.getName());
-    return;
-  }
-  NFD_LOG_DEBUG("onOutgoingData face=" << outFace.getId() << " data=" << data.getName());
-
-  // /localhost scope control
-  bool isViolatingLocalhost = !outFace.isLocal() &&
-                              LOCALHOST_NAME.isPrefixOf(data.getName());
-  if (isViolatingLocalhost) {
-    NFD_LOG_DEBUG("onOutgoingData face=" << outFace.getId() <<
-                  " data=" << data.getName() << " violates /localhost");
-    // (drop)
-    return;
-  }
-
-  // TODO traffic manager
-
-  // send Data
-  outFace.sendData(data);
-  ++m_counters.getNOutDatas();
-}
-
-static inline bool
-compare_InRecord_expiry(const pit::InRecord& a, const pit::InRecord& b)
-{
-  return a.getExpiry() < b.getExpiry();
-}
-
-void
-Forwarder::setUnsatisfyTimer(shared_ptr<pit::Entry> pitEntry)
-{
-  const pit::InRecordCollection& inRecords = pitEntry->getInRecords();
-  pit::InRecordCollection::const_iterator lastExpiring =
-    std::max_element(inRecords.begin(), inRecords.end(),
-    &compare_InRecord_expiry);
-
-  time::steady_clock::TimePoint lastExpiry = lastExpiring->getExpiry();
-  time::nanoseconds lastExpiryFromNow = lastExpiry  - time::steady_clock::now();
-  if (lastExpiryFromNow <= time::seconds(0)) {
-    // TODO all InRecords are already expired; will this happen?
-  }
-
-  scheduler::cancel(pitEntry->m_unsatisfyTimer);
-  pitEntry->m_unsatisfyTimer = scheduler::schedule(lastExpiryFromNow,
-    bind(&Forwarder::onInterestUnsatisfied, this, pitEntry));
-}
-
-void
-Forwarder::setStragglerTimer(shared_ptr<pit::Entry> pitEntry, bool isSatisfied,
-                             const time::milliseconds& dataFreshnessPeriod)
-{
-  time::nanoseconds stragglerTime = time::milliseconds(100);
-
-  scheduler::cancel(pitEntry->m_stragglerTimer);
-  pitEntry->m_stragglerTimer = scheduler::schedule(stragglerTime,
-    bind(&Forwarder::onInterestFinalize, this, pitEntry, isSatisfied, dataFreshnessPeriod));
-}
-
-void
-Forwarder::cancelUnsatisfyAndStragglerTimer(shared_ptr<pit::Entry> pitEntry)
-{
-  scheduler::cancel(pitEntry->m_unsatisfyTimer);
-  scheduler::cancel(pitEntry->m_stragglerTimer);
-}
-
-static inline void
-insertNonceToDnl(DeadNonceList& dnl, const pit::Entry& pitEntry,
-                 const pit::OutRecord& outRecord)
-{
-  dnl.add(pitEntry.getName(), outRecord.getLastNonce());
-}
-
-void
-Forwarder::insertDeadNonceList(pit::Entry& pitEntry, bool isSatisfied,
-                               const time::milliseconds& dataFreshnessPeriod,
-                               Face* upstream)
-{
-  // need Dead Nonce List insert?
-  bool needDnl = false;
-  if (isSatisfied) {
-    bool hasFreshnessPeriod = dataFreshnessPeriod >= time::milliseconds::zero();
-    // Data never becomes stale if it doesn't have FreshnessPeriod field
-    needDnl = static_cast<bool>(pitEntry.getInterest().getMustBeFresh()) &&
-              (hasFreshnessPeriod && dataFreshnessPeriod < m_deadNonceList.getLifetime());
-  }
-  else {
-    needDnl = true;
-  }
-
-  if (!needDnl) {
-    return;
-  }
-
-  // Dead Nonce List insert
-  if (upstream == 0) {
-    // insert all outgoing Nonces
-    const pit::OutRecordCollection& outRecords = pitEntry.getOutRecords();
-    std::for_each(outRecords.begin(), outRecords.end(),
-                  bind(&insertNonceToDnl, ref(m_deadNonceList), cref(pitEntry), _1));
-  }
-  else {
-    // insert outgoing Nonce of a specific face
-    pit::OutRecordCollection::const_iterator outRecord = pitEntry.getOutRecord(*upstream);
-    if (outRecord != pitEntry.getOutRecords().end()) {
-      m_deadNonceList.add(pitEntry.getName(), outRecord->getLastNonce());
-    }
-  }
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/fw/forwarder.hpp b/NFD/daemon/fw/forwarder.hpp
deleted file mode 100644
index 574688f..0000000
--- a/NFD/daemon/fw/forwarder.hpp
+++ /dev/null
@@ -1,329 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_FW_FORWARDER_HPP
-#define NFD_DAEMON_FW_FORWARDER_HPP
-
-#include "common.hpp"
-#include "core/scheduler.hpp"
-#include "forwarder-counters.hpp"
-#include "face-table.hpp"
-#include "table/fib.hpp"
-#include "table/pit.hpp"
-#include "table/cs.hpp"
-#include "table/measurements.hpp"
-#include "table/strategy-choice.hpp"
-#include "table/dead-nonce-list.hpp"
-
-#include "ns3/ndnSIM/model/cs/ndn-content-store.hpp"
-
-namespace nfd {
-
-namespace fw {
-class Strategy;
-} // namespace fw
-
-class NullFace;
-
-/** \brief main class of NFD
- *
- *  Forwarder owns all faces and tables, and implements forwarding pipelines.
- */
-class Forwarder
-{
-public:
-  Forwarder();
-
-  VIRTUAL_WITH_TESTS
-  ~Forwarder();
-
-  const ForwarderCounters&
-  getCounters() const;
-
-public: // faces
-  FaceTable&
-  getFaceTable();
-
-  /** \brief get existing Face
-   *
-   *  shortcut to .getFaceTable().get(face)
-   */
-  shared_ptr<Face>
-  getFace(FaceId id) const;
-
-  /** \brief add new Face
-   *
-   *  shortcut to .getFaceTable().add(face)
-   */
-  void
-  addFace(shared_ptr<Face> face);
-
-public: // forwarding entrypoints and tables
-  void
-  onInterest(Face& face, const Interest& interest);
-
-  void
-  onData(Face& face, const Data& data);
-
-  NameTree&
-  getNameTree();
-
-  Fib&
-  getFib();
-
-  Pit&
-  getPit();
-
-  Cs&
-  getCs();
-
-  Measurements&
-  getMeasurements();
-
-  StrategyChoice&
-  getStrategyChoice();
-
-  DeadNonceList&
-  getDeadNonceList();
-
-public: // allow enabling ndnSIM content store (will be removed in the future)
-  void
-  setCsFromNdnSim(ns3::Ptr<ns3::ndn::ContentStore> cs);
-
-public:
-  /** \brief trigger before PIT entry is satisfied
-   *  \sa Strategy::beforeSatisfyInterest
-   */
-  signal::Signal<Forwarder, pit::Entry, Face, Data> beforeSatisfyInterest;
-
-  /** \brief trigger before PIT entry expires
-   *  \sa Strategy::beforeExpirePendingInterest
-   */
-  signal::Signal<Forwarder, pit::Entry> beforeExpirePendingInterest;
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE: // pipelines
-  /** \brief incoming Interest pipeline
-   */
-  VIRTUAL_WITH_TESTS void
-  onIncomingInterest(Face& inFace, const Interest& interest);
-
-  /** \brief Interest loop pipeline
-   */
-  VIRTUAL_WITH_TESTS void
-  onInterestLoop(Face& inFace, const Interest& interest,
-                 shared_ptr<pit::Entry> pitEntry);
-
-  /** \brief outgoing Interest pipeline
-   */
-  VIRTUAL_WITH_TESTS void
-  onOutgoingInterest(shared_ptr<pit::Entry> pitEntry, Face& outFace,
-                     bool wantNewNonce = false);
-
-  /** \brief Interest reject pipeline
-   */
-  VIRTUAL_WITH_TESTS void
-  onInterestReject(shared_ptr<pit::Entry> pitEntry);
-
-  /** \brief Interest unsatisfied pipeline
-   */
-  VIRTUAL_WITH_TESTS void
-  onInterestUnsatisfied(shared_ptr<pit::Entry> pitEntry);
-
-  /** \brief Interest finalize pipeline
-   *  \param isSatisfied whether the Interest has been satisfied
-   *  \param dataFreshnessPeriod FreshnessPeriod of satisfying Data
-   */
-  VIRTUAL_WITH_TESTS void
-  onInterestFinalize(shared_ptr<pit::Entry> pitEntry, bool isSatisfied,
-                     const time::milliseconds& dataFreshnessPeriod = time::milliseconds(-1));
-
-  /** \brief incoming Data pipeline
-   */
-  VIRTUAL_WITH_TESTS void
-  onIncomingData(Face& inFace, const Data& data);
-
-  /** \brief Data unsolicited pipeline
-   */
-  VIRTUAL_WITH_TESTS void
-  onDataUnsolicited(Face& inFace, const Data& data);
-
-  /** \brief outgoing Data pipeline
-   */
-  VIRTUAL_WITH_TESTS void
-  onOutgoingData(const Data& data, Face& outFace);
-
-PROTECTED_WITH_TESTS_ELSE_PRIVATE:
-  VIRTUAL_WITH_TESTS void
-  setUnsatisfyTimer(shared_ptr<pit::Entry> pitEntry);
-
-  VIRTUAL_WITH_TESTS void
-  setStragglerTimer(shared_ptr<pit::Entry> pitEntry, bool isSatisfied,
-                    const time::milliseconds& dataFreshnessPeriod = time::milliseconds(-1));
-
-  VIRTUAL_WITH_TESTS void
-  cancelUnsatisfyAndStragglerTimer(shared_ptr<pit::Entry> pitEntry);
-
-  /** \brief insert Nonce to Dead Nonce List if necessary
-   *  \param upstream if null, insert Nonces from all OutRecords;
-   *                  if not null, insert Nonce only on the OutRecord of this face
-   */
-  VIRTUAL_WITH_TESTS void
-  insertDeadNonceList(pit::Entry& pitEntry, bool isSatisfied,
-                      const time::milliseconds& dataFreshnessPeriod,
-                      Face* upstream);
-
-  /// call trigger (method) on the effective strategy of pitEntry
-#ifdef WITH_TESTS
-  virtual void
-  dispatchToStrategy(shared_ptr<pit::Entry> pitEntry, function<void(fw::Strategy*)> trigger);
-#else
-  template<class Function>
-  void
-  dispatchToStrategy(shared_ptr<pit::Entry> pitEntry, Function trigger);
-#endif
-
-private:
-  ForwarderCounters m_counters;
-
-  FaceTable m_faceTable;
-
-  // tables
-  NameTree       m_nameTree;
-  Fib            m_fib;
-  Pit            m_pit;
-  Cs             m_cs;
-  Measurements   m_measurements;
-  StrategyChoice m_strategyChoice;
-  DeadNonceList  m_deadNonceList;
-  shared_ptr<NullFace> m_csFace;
-
-  ns3::Ptr<ns3::ndn::ContentStore> m_csFromNdnSim;
-
-  static const Name LOCALHOST_NAME;
-
-  // allow Strategy (base class) to enter pipelines
-  friend class fw::Strategy;
-};
-
-inline const ForwarderCounters&
-Forwarder::getCounters() const
-{
-  return m_counters;
-}
-
-inline FaceTable&
-Forwarder::getFaceTable()
-{
-  return m_faceTable;
-}
-
-inline shared_ptr<Face>
-Forwarder::getFace(FaceId id) const
-{
-  return m_faceTable.get(id);
-}
-
-inline void
-Forwarder::addFace(shared_ptr<Face> face)
-{
-  m_faceTable.add(face);
-}
-
-inline void
-Forwarder::onInterest(Face& face, const Interest& interest)
-{
-  this->onIncomingInterest(face, interest);
-}
-
-inline void
-Forwarder::onData(Face& face, const Data& data)
-{
-  this->onIncomingData(face, data);
-}
-
-inline NameTree&
-Forwarder::getNameTree()
-{
-  return m_nameTree;
-}
-
-inline Fib&
-Forwarder::getFib()
-{
-  return m_fib;
-}
-
-inline Pit&
-Forwarder::getPit()
-{
-  return m_pit;
-}
-
-inline Cs&
-Forwarder::getCs()
-{
-  return m_cs;
-}
-
-inline Measurements&
-Forwarder::getMeasurements()
-{
-  return m_measurements;
-}
-
-inline StrategyChoice&
-Forwarder::getStrategyChoice()
-{
-  return m_strategyChoice;
-}
-
-inline DeadNonceList&
-Forwarder::getDeadNonceList()
-{
-  return m_deadNonceList;
-}
-
-inline void
-Forwarder::setCsFromNdnSim(ns3::Ptr<ns3::ndn::ContentStore> cs)
-{
-  m_csFromNdnSim = cs;
-}
-
-#ifdef WITH_TESTS
-inline void
-Forwarder::dispatchToStrategy(shared_ptr<pit::Entry> pitEntry, function<void(fw::Strategy*)> trigger)
-#else
-template<class Function>
-inline void
-Forwarder::dispatchToStrategy(shared_ptr<pit::Entry> pitEntry, Function trigger)
-#endif
-{
-  fw::Strategy& strategy = m_strategyChoice.findEffectiveStrategy(*pitEntry);
-  trigger(&strategy);
-}
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_FW_FORWARDER_HPP
diff --git a/NFD/daemon/fw/ncc-strategy.cpp b/NFD/daemon/fw/ncc-strategy.cpp
deleted file mode 100644
index e5aaab9..0000000
--- a/NFD/daemon/fw/ncc-strategy.cpp
+++ /dev/null
@@ -1,314 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "ncc-strategy.hpp"
-#include "core/random.hpp"
-#include <boost/random/uniform_int_distribution.hpp>
-
-namespace nfd {
-namespace fw {
-
-const Name NccStrategy::STRATEGY_NAME("ndn:/localhost/nfd/strategy/ncc/%FD%01");
-
-NccStrategy::NccStrategy(Forwarder& forwarder, const Name& name)
-  : Strategy(forwarder, name)
-{
-}
-
-NccStrategy::~NccStrategy()
-{
-}
-
-const time::microseconds NccStrategy::DEFER_FIRST_WITHOUT_BEST_FACE = time::microseconds(4000);
-const time::microseconds NccStrategy::DEFER_RANGE_WITHOUT_BEST_FACE = time::microseconds(75000);
-const time::nanoseconds NccStrategy::MEASUREMENTS_LIFETIME = time::seconds(16);
-
-void
-NccStrategy::afterReceiveInterest(const Face& inFace,
-                                  const Interest& interest,
-                                  shared_ptr<fib::Entry> fibEntry,
-                                  shared_ptr<pit::Entry> pitEntry)
-{
-  const fib::NextHopList& nexthops = fibEntry->getNextHops();
-  if (nexthops.size() == 0) {
-    this->rejectPendingInterest(pitEntry);
-    return;
-  }
-
-  shared_ptr<PitEntryInfo> pitEntryInfo =
-    pitEntry->getOrCreateStrategyInfo<PitEntryInfo>();
-  bool isNewPitEntry = !pitEntry->hasUnexpiredOutRecords();
-  if (!isNewPitEntry) {
-    return;
-  }
-
-  shared_ptr<MeasurementsEntryInfo> measurementsEntryInfo =
-    this->getMeasurementsEntryInfo(pitEntry);
-
-  time::microseconds deferFirst = DEFER_FIRST_WITHOUT_BEST_FACE;
-  time::microseconds deferRange = DEFER_RANGE_WITHOUT_BEST_FACE;
-  size_t nUpstreams = nexthops.size();
-
-  shared_ptr<Face> bestFace = measurementsEntryInfo->getBestFace();
-  if (static_cast<bool>(bestFace) && fibEntry->hasNextHop(bestFace) &&
-      pitEntry->canForwardTo(*bestFace)) {
-    // TODO Should we use `randlow = 100 + nrand48(h->seed) % 4096U;` ?
-    deferFirst = measurementsEntryInfo->prediction;
-    deferRange = time::microseconds((deferFirst.count() + 1) / 2);
-    --nUpstreams;
-    this->sendInterest(pitEntry, bestFace);
-    pitEntryInfo->bestFaceTimeout = scheduler::schedule(
-      measurementsEntryInfo->prediction,
-      bind(&NccStrategy::timeoutOnBestFace, this, weak_ptr<pit::Entry>(pitEntry)));
-  }
-  else {
-    // use first nexthop
-    this->sendInterest(pitEntry, nexthops.begin()->getFace());
-    // TODO avoid sending to inFace
-  }
-
-  shared_ptr<Face> previousFace = measurementsEntryInfo->previousFace.lock();
-  if (static_cast<bool>(previousFace) && fibEntry->hasNextHop(previousFace) &&
-      pitEntry->canForwardTo(*previousFace)) {
-    --nUpstreams;
-  }
-
-  if (nUpstreams > 0) {
-    pitEntryInfo->maxInterval = std::max(time::microseconds(1),
-      time::microseconds((2 * deferRange.count() + nUpstreams - 1) / nUpstreams));
-  }
-  else {
-    // Normally, maxInterval is unused if there aren't any face beyond best and previousBest.
-    // However, in case FIB entry gains a new nexthop before doPropagate executes (bug 1853),
-    // this maxInterval would be used to determine when the next doPropagate would happen.
-    pitEntryInfo->maxInterval = deferFirst;
-  }
-  pitEntryInfo->propagateTimer = scheduler::schedule(deferFirst,
-    bind(&NccStrategy::doPropagate, this,
-         weak_ptr<pit::Entry>(pitEntry), weak_ptr<fib::Entry>(fibEntry)));
-}
-
-void
-NccStrategy::doPropagate(weak_ptr<pit::Entry> pitEntryWeak, weak_ptr<fib::Entry> fibEntryWeak)
-{
-  shared_ptr<pit::Entry> pitEntry = pitEntryWeak.lock();
-  if (!static_cast<bool>(pitEntry)) {
-    return;
-  }
-  shared_ptr<fib::Entry> fibEntry = fibEntryWeak.lock();
-  if (!static_cast<bool>(fibEntry)) {
-    return;
-  }
-
-  shared_ptr<PitEntryInfo> pitEntryInfo = pitEntry->getStrategyInfo<PitEntryInfo>();
-  // pitEntryInfo is guaranteed to exist here, because doPropagate is triggered
-  // from a timer set by NccStrategy.
-  BOOST_ASSERT(static_cast<bool>(pitEntryInfo));
-
-  shared_ptr<MeasurementsEntryInfo> measurementsEntryInfo =
-    this->getMeasurementsEntryInfo(pitEntry);
-
-  shared_ptr<Face> previousFace = measurementsEntryInfo->previousFace.lock();
-  if (static_cast<bool>(previousFace) && fibEntry->hasNextHop(previousFace) &&
-      pitEntry->canForwardTo(*previousFace)) {
-    this->sendInterest(pitEntry, previousFace);
-  }
-
-  const fib::NextHopList& nexthops = fibEntry->getNextHops();
-  bool isForwarded = false;
-  for (fib::NextHopList::const_iterator it = nexthops.begin(); it != nexthops.end(); ++it) {
-    shared_ptr<Face> face = it->getFace();
-    if (pitEntry->canForwardTo(*face)) {
-      isForwarded = true;
-      this->sendInterest(pitEntry, face);
-      break;
-    }
-  }
-
-  if (isForwarded) {
-    boost::random::uniform_int_distribution<time::nanoseconds::rep> dist(0,
-      pitEntryInfo->maxInterval.count() - 1);
-    time::nanoseconds deferNext = time::nanoseconds(dist(getGlobalRng()));
-    pitEntryInfo->propagateTimer = scheduler::schedule(deferNext,
-    bind(&NccStrategy::doPropagate, this,
-         weak_ptr<pit::Entry>(pitEntry), weak_ptr<fib::Entry>(fibEntry)));
-  }
-}
-
-void
-NccStrategy::timeoutOnBestFace(weak_ptr<pit::Entry> pitEntryWeak)
-{
-  shared_ptr<pit::Entry> pitEntry = pitEntryWeak.lock();
-  if (!static_cast<bool>(pitEntry)) {
-    return;
-  }
-  shared_ptr<measurements::Entry> measurementsEntry = this->getMeasurements().get(*pitEntry);
-
-  for (int i = 0; i < UPDATE_MEASUREMENTS_N_LEVELS; ++i) {
-    if (!static_cast<bool>(measurementsEntry)) {
-      // going out of this strategy's namespace
-      return;
-    }
-    this->getMeasurements().extendLifetime(*measurementsEntry, MEASUREMENTS_LIFETIME);
-
-    shared_ptr<MeasurementsEntryInfo> measurementsEntryInfo =
-      this->getMeasurementsEntryInfo(measurementsEntry);
-    measurementsEntryInfo->adjustPredictUp();
-
-    measurementsEntry = this->getMeasurements().getParent(*measurementsEntry);
-  }
-}
-
-void
-NccStrategy::beforeSatisfyInterest(shared_ptr<pit::Entry> pitEntry,
-                                   const Face& inFace, const Data& data)
-{
-  if (pitEntry->getInRecords().empty()) {
-    // PIT entry has already been satisfied (and is now waiting for straggler timer to expire)
-    // NCC does not collect measurements for non-best face
-    return;
-  }
-
-  shared_ptr<measurements::Entry> measurementsEntry = this->getMeasurements().get(*pitEntry);
-
-  for (int i = 0; i < UPDATE_MEASUREMENTS_N_LEVELS; ++i) {
-    if (!static_cast<bool>(measurementsEntry)) {
-      // going out of this strategy's namespace
-      return;
-    }
-    this->getMeasurements().extendLifetime(*measurementsEntry, MEASUREMENTS_LIFETIME);
-
-    shared_ptr<MeasurementsEntryInfo> measurementsEntryInfo =
-      this->getMeasurementsEntryInfo(measurementsEntry);
-    measurementsEntryInfo->updateBestFace(inFace);
-
-    measurementsEntry = this->getMeasurements().getParent(*measurementsEntry);
-  }
-
-  shared_ptr<PitEntryInfo> pitEntryInfo = pitEntry->getStrategyInfo<PitEntryInfo>();
-  if (static_cast<bool>(pitEntryInfo)) {
-    scheduler::cancel(pitEntryInfo->propagateTimer);
-  }
-}
-
-shared_ptr<NccStrategy::MeasurementsEntryInfo>
-NccStrategy::getMeasurementsEntryInfo(shared_ptr<pit::Entry> entry)
-{
-  shared_ptr<measurements::Entry> measurementsEntry = this->getMeasurements().get(*entry);
-  return this->getMeasurementsEntryInfo(measurementsEntry);
-}
-
-shared_ptr<NccStrategy::MeasurementsEntryInfo>
-NccStrategy::getMeasurementsEntryInfo(shared_ptr<measurements::Entry> entry)
-{
-  shared_ptr<MeasurementsEntryInfo> info = entry->getStrategyInfo<MeasurementsEntryInfo>();
-  if (static_cast<bool>(info)) {
-    return info;
-  }
-
-  info = make_shared<MeasurementsEntryInfo>();
-  entry->setStrategyInfo(info);
-
-  shared_ptr<measurements::Entry> parentEntry = this->getMeasurements().getParent(*entry);
-  if (static_cast<bool>(parentEntry)) {
-    shared_ptr<MeasurementsEntryInfo> parentInfo = this->getMeasurementsEntryInfo(parentEntry);
-    BOOST_ASSERT(static_cast<bool>(parentInfo));
-    info->inheritFrom(*parentInfo);
-  }
-
-  return info;
-}
-
-
-const time::microseconds NccStrategy::MeasurementsEntryInfo::INITIAL_PREDICTION =
-                                                             time::microseconds(8192);
-const time::microseconds NccStrategy::MeasurementsEntryInfo::MIN_PREDICTION =
-                                                             time::microseconds(127);
-const time::microseconds NccStrategy::MeasurementsEntryInfo::MAX_PREDICTION =
-                                                             time::microseconds(160000);
-
-NccStrategy::MeasurementsEntryInfo::MeasurementsEntryInfo()
-  : prediction(INITIAL_PREDICTION)
-{
-}
-
-void
-NccStrategy::MeasurementsEntryInfo::inheritFrom(const MeasurementsEntryInfo& other)
-{
-  this->operator=(other);
-}
-
-shared_ptr<Face>
-NccStrategy::MeasurementsEntryInfo::getBestFace(void) {
-  shared_ptr<Face> best = this->bestFace.lock();
-  if (static_cast<bool>(best)) {
-    return best;
-  }
-  this->bestFace = best = this->previousFace.lock();
-  return best;
-}
-
-void
-NccStrategy::MeasurementsEntryInfo::updateBestFace(const Face& face) {
-  if (this->bestFace.expired()) {
-    this->bestFace = const_cast<Face&>(face).shared_from_this();
-    return;
-  }
-  shared_ptr<Face> bestFace = this->bestFace.lock();
-  if (bestFace.get() == &face) {
-    this->adjustPredictDown();
-  }
-  else {
-    this->previousFace = this->bestFace;
-    this->bestFace = const_cast<Face&>(face).shared_from_this();
-  }
-}
-
-void
-NccStrategy::MeasurementsEntryInfo::adjustPredictDown() {
-  prediction = std::max(MIN_PREDICTION,
-    time::microseconds(prediction.count() - (prediction.count() >> ADJUST_PREDICT_DOWN_SHIFT)));
-}
-
-void
-NccStrategy::MeasurementsEntryInfo::adjustPredictUp() {
-  prediction = std::min(MAX_PREDICTION,
-    time::microseconds(prediction.count() + (prediction.count() >> ADJUST_PREDICT_UP_SHIFT)));
-}
-
-void
-NccStrategy::MeasurementsEntryInfo::ageBestFace() {
-  this->previousFace = this->bestFace;
-  this->bestFace.reset();
-}
-
-NccStrategy::PitEntryInfo::~PitEntryInfo()
-{
-  scheduler::cancel(this->bestFaceTimeout);
-  scheduler::cancel(this->propagateTimer);
-}
-
-} // namespace fw
-} // namespace nfd
diff --git a/NFD/daemon/fw/ncc-strategy.hpp b/NFD/daemon/fw/ncc-strategy.hpp
deleted file mode 100644
index 14a4696..0000000
--- a/NFD/daemon/fw/ncc-strategy.hpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_FW_NCC_STRATEGY_HPP
-#define NFD_DAEMON_FW_NCC_STRATEGY_HPP
-
-#include "strategy.hpp"
-
-namespace nfd {
-namespace fw {
-
-/** \brief a forwarding strategy similar to CCNx 0.7.2
- */
-class NccStrategy : public Strategy
-{
-public:
-  NccStrategy(Forwarder& forwarder, const Name& name = STRATEGY_NAME);
-
-  virtual
-  ~NccStrategy();
-
-  virtual void
-  afterReceiveInterest(const Face& inFace,
-                       const Interest& interest,
-                       shared_ptr<fib::Entry> fibEntry,
-                       shared_ptr<pit::Entry> pitEntry) DECL_OVERRIDE;
-
-  virtual void
-  beforeSatisfyInterest(shared_ptr<pit::Entry> pitEntry,
-                        const Face& inFace, const Data& data) DECL_OVERRIDE;
-
-protected:
-  /// StrategyInfo on measurements::Entry
-  class MeasurementsEntryInfo : public StrategyInfo
-  {
-  public:
-    static constexpr int
-    getTypeId()
-    {
-      return 1000;
-    }
-
-    MeasurementsEntryInfo();
-
-    void
-    inheritFrom(const MeasurementsEntryInfo& other);
-
-    shared_ptr<Face>
-    getBestFace();
-
-    void
-    updateBestFace(const Face& face);
-
-    void
-    adjustPredictUp();
-
-  private:
-    void
-    adjustPredictDown();
-
-    void
-    ageBestFace();
-
-  public:
-    weak_ptr<Face> bestFace;
-    weak_ptr<Face> previousFace;
-    time::microseconds prediction;
-
-    static const time::microseconds INITIAL_PREDICTION;
-    static const time::microseconds MIN_PREDICTION;
-    static const int ADJUST_PREDICT_DOWN_SHIFT = 7;
-    static const time::microseconds MAX_PREDICTION;
-    static const int ADJUST_PREDICT_UP_SHIFT = 3;
-  };
-
-  /// StrategyInfo on pit::Entry
-  class PitEntryInfo : public StrategyInfo
-  {
-  public:
-    static constexpr int
-    getTypeId()
-    {
-      return 1001;
-    }
-
-    virtual
-    ~PitEntryInfo();
-
-  public:
-    /// timer that expires when best face does not respond within predicted time
-    EventId bestFaceTimeout;
-    /// timer for propagating to another face
-    EventId propagateTimer;
-    /// maximum interval between forwarding to two nexthops except best and previous
-    time::microseconds maxInterval;
-  };
-
-protected:
-  shared_ptr<MeasurementsEntryInfo>
-  getMeasurementsEntryInfo(shared_ptr<measurements::Entry> entry);
-
-  shared_ptr<MeasurementsEntryInfo>
-  getMeasurementsEntryInfo(shared_ptr<pit::Entry> entry);
-
-  /// propagate to another upstream
-  void
-  doPropagate(weak_ptr<pit::Entry> pitEntryWeak, weak_ptr<fib::Entry> fibEntryWeak);
-
-  /// best face did not reply within prediction
-  void
-  timeoutOnBestFace(weak_ptr<pit::Entry> pitEntryWeak);
-
-public:
-  static const Name STRATEGY_NAME;
-
-protected:
-  static const time::microseconds DEFER_FIRST_WITHOUT_BEST_FACE;
-  static const time::microseconds DEFER_RANGE_WITHOUT_BEST_FACE;
-  static const int UPDATE_MEASUREMENTS_N_LEVELS = 2;
-  static const time::nanoseconds MEASUREMENTS_LIFETIME;
-};
-
-} // namespace fw
-} // namespace nfd
-
-#endif // NFD_DAEMON_FW_NCC_STRATEGY_HPP
diff --git a/NFD/daemon/fw/rtt-estimator.cpp b/NFD/daemon/fw/rtt-estimator.cpp
deleted file mode 100644
index 97b2ab0..0000000
--- a/NFD/daemon/fw/rtt-estimator.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "rtt-estimator.hpp"
-
-namespace nfd {
-
-RttEstimator::RttEstimator(uint16_t maxMultiplier, Duration minRto, double gain)
-  : m_maxMultiplier(maxMultiplier)
-  , m_minRto(minRto.count())
-  , m_rtt(RttEstimator::getInitialRtt().count())
-  , m_gain(gain)
-  , m_variance(0)
-  , m_multiplier(1)
-  , m_nSamples(0)
-{
-}
-
-void
-RttEstimator::addMeasurement(Duration measure)
-{
-  double m = static_cast<double>(measure.count());
-  if (m_nSamples > 0) {
-    double err = m - m_rtt;
-    double gErr = err * m_gain;
-    m_rtt += gErr;
-    double difference = std::abs(err) - m_variance;
-    m_variance += difference * m_gain;
-  } else {
-    m_rtt = m;
-    m_variance = m;
-  }
-  ++m_nSamples;
-  m_multiplier = 1;
-}
-
-void
-RttEstimator::incrementMultiplier()
-{
-  m_multiplier = std::min(static_cast<uint16_t>(m_multiplier + 1), m_maxMultiplier);
-}
-
-void
-RttEstimator::doubleMultiplier()
-{
-  m_multiplier = std::min(static_cast<uint16_t>(m_multiplier * 2), m_maxMultiplier);
-}
-
-RttEstimator::Duration
-RttEstimator::computeRto() const
-{
-  double rto = std::max(m_minRto, m_rtt + 4 * m_variance);
-  rto *= m_multiplier;
-  return Duration(static_cast<Duration::rep>(rto));
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/fw/rtt-estimator.hpp b/NFD/daemon/fw/rtt-estimator.hpp
deleted file mode 100644
index a830c5a..0000000
--- a/NFD/daemon/fw/rtt-estimator.hpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#ifndef NFD_DAEMON_FW_RTT_ESTIMATOR_HPP
-#define NFD_DAEMON_FW_RTT_ESTIMATOR_HPP
-
-#include "common.hpp"
-
-namespace nfd {
-
-/**
- * \brief implements the Mean-Deviation RTT estimator
- *
- * reference: ns3::RttMeanDeviation
- *
- * This RttEstimator algorithm is designed for TCP, which is a continuous stream.
- * NDN Interest-Data traffic is not always a continuous stream,
- * so NDN may need a different RttEstimator.
- * The design of a more suitable RttEstimator is a research question.
- */
-class RttEstimator
-{
-public:
-  typedef time::microseconds Duration;
-
-  static Duration
-  getInitialRtt(void)
-  {
-    return time::seconds(1);
-  }
-
-  RttEstimator(uint16_t maxMultiplier = 16,
-               Duration minRto = time::milliseconds(1),
-               double gain = 0.1);
-
-  void
-  addMeasurement(Duration measure);
-
-  void
-  incrementMultiplier();
-
-  void
-  doubleMultiplier();
-
-  Duration
-  computeRto() const;
-
-private:
-  uint16_t m_maxMultiplier;
-  double m_minRto;
-
-  double m_rtt;
-  double m_gain;
-  double m_variance;
-  uint16_t m_multiplier;
-  uint32_t m_nSamples;
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_FW_RTT_ESTIMATOR_HPP
diff --git a/NFD/daemon/fw/strategy-info.hpp b/NFD/daemon/fw/strategy-info.hpp
deleted file mode 100644
index b701fc5..0000000
--- a/NFD/daemon/fw/strategy-info.hpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_FW_STRATEGY_INFO_HPP
-#define NFD_DAEMON_FW_STRATEGY_INFO_HPP
-
-#include "common.hpp"
-
-namespace nfd {
-namespace fw {
-
-/** \brief contains arbitrary information forwarding strategy places on table entries
- */
-class StrategyInfo
-{
-public:
-  /** \fn static constexpr int getTypeId()
-   *  \return an integer that uniquely identifies this StrategyInfo type
-   *  \sa http://redmine.named-data.net/projects/nfd/wiki/StrategyInfoType
-   */
-  // static constexpr int
-  // getTypeId()
-  // {
-  //   return <type-identifier>;
-  // }
-
-  virtual
-  ~StrategyInfo();
-};
-
-
-inline
-StrategyInfo::~StrategyInfo()
-{
-}
-
-} // namespace fw
-} // namespace nfd
-
-#endif // NFD_DAEMON_FW_STRATEGY_INFO_HPP
diff --git a/NFD/daemon/fw/strategy.cpp b/NFD/daemon/fw/strategy.cpp
deleted file mode 100644
index f1a16f5..0000000
--- a/NFD/daemon/fw/strategy.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "strategy.hpp"
-#include "forwarder.hpp"
-#include "core/logger.hpp"
-
-namespace nfd {
-namespace fw {
-
-NFD_LOG_INIT("Strategy");
-
-Strategy::Strategy(Forwarder& forwarder, const Name& name)
-  : afterAddFace(forwarder.getFaceTable().onAdd)
-  , beforeRemoveFace(forwarder.getFaceTable().onRemove)
-  , m_name(name)
-  , m_forwarder(forwarder)
-  , m_measurements(m_forwarder.getMeasurements(),
-                   m_forwarder.getStrategyChoice(), this)
-{
-}
-
-Strategy::~Strategy()
-{
-}
-
-void
-Strategy::beforeSatisfyInterest(shared_ptr<pit::Entry> pitEntry,
-                                const Face& inFace, const Data& data)
-{
-  NFD_LOG_DEBUG("beforeSatisfyInterest pitEntry=" << pitEntry->getName() <<
-    " inFace=" << inFace.getId() << " data=" << data.getName());
-}
-
-void
-Strategy::beforeExpirePendingInterest(shared_ptr<pit::Entry> pitEntry)
-{
-  NFD_LOG_DEBUG("beforeExpirePendingInterest pitEntry=" << pitEntry->getName());
-}
-
-//void
-//Strategy::afterAddFibEntry(shared_ptr<fib::Entry> fibEntry)
-//{
-//  NFD_LOG_DEBUG("afterAddFibEntry fibEntry=" << fibEntry->getPrefix());
-//}
-//
-//void
-//Strategy::afterUpdateFibEntry(shared_ptr<fib::Entry> fibEntry)
-//{
-//  NFD_LOG_DEBUG("afterUpdateFibEntry fibEntry=" << fibEntry->getPrefix());
-//}
-//
-//void
-//Strategy::beforeRemoveFibEntry(shared_ptr<fib::Entry> fibEntry)
-//{
-//  NFD_LOG_DEBUG("beforeRemoveFibEntry fibEntry=" << fibEntry->getPrefix());
-//}
-
-} // namespace fw
-} // namespace nfd
diff --git a/NFD/daemon/fw/strategy.hpp b/NFD/daemon/fw/strategy.hpp
deleted file mode 100644
index 813cce0..0000000
--- a/NFD/daemon/fw/strategy.hpp
+++ /dev/null
@@ -1,194 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_FW_STRATEGY_HPP
-#define NFD_DAEMON_FW_STRATEGY_HPP
-
-#include "forwarder.hpp"
-#include "table/measurements-accessor.hpp"
-
-namespace nfd {
-namespace fw {
-
-/** \brief represents a forwarding strategy
- */
-class Strategy : public enable_shared_from_this<Strategy>, noncopyable
-{
-public:
-  /** \brief construct a strategy instance
-   *  \param forwarder a reference to the Forwarder, used to enable actions and accessors.
-   *         Strategy subclasses should pass this reference,
-   *         and should not keep a reference themselves.
-   *  \param name the strategy Name.
-   *         It's recommended to include a version number as the last component.
-   */
-  Strategy(Forwarder& forwarder, const Name& name);
-
-  virtual
-  ~Strategy();
-
-  /// a Name that represent the Strategy program
-  const Name&
-  getName() const;
-
-public: // triggers
-  /** \brief trigger after Interest is received
-   *
-   *  The Interest:
-   *  - does not violate Scope
-   *  - is not looped
-   *  - cannot be satisfied by ContentStore
-   *  - is under a namespace managed by this strategy
-   *
-   *  The strategy should decide whether and where to forward this Interest.
-   *  - If the strategy decides to forward this Interest,
-   *    invoke this->sendInterest one or more times, either now or shortly after
-   *  - If strategy concludes that this Interest cannot be forwarded,
-   *    invoke this->rejectPendingInterest so that PIT entry will be deleted shortly
-   *
-   *  \note The strategy is permitted to store a weak reference to fibEntry.
-   *        Do not store a shared reference, because PIT entry may be deleted at any moment.
-   *        fibEntry is passed by value to allow obtaining a weak reference from it.
-   *  \note The strategy is permitted to store a shared reference to pitEntry.
-   *        pitEntry is passed by value to reflect this fact.
-   */
-  virtual void
-  afterReceiveInterest(const Face& inFace,
-                       const Interest& interest,
-                       shared_ptr<fib::Entry> fibEntry,
-                       shared_ptr<pit::Entry> pitEntry) = 0;
-
-  /** \brief trigger before PIT entry is satisfied
-   *
-   *  This trigger is invoked when an incoming Data satisfies the PIT entry.
-   *  It can be invoked even if the PIT entry has already been satisfied.
-   *
-   *  In this base class this method does nothing.
-   *
-   *  \note The strategy is permitted to store a shared reference to pitEntry.
-   *        pitEntry is passed by value to reflect this fact.
-   */
-  virtual void
-  beforeSatisfyInterest(shared_ptr<pit::Entry> pitEntry,
-                        const Face& inFace, const Data& data);
-
-  /** \brief trigger before PIT entry expires
-   *
-   *  PIT entry expires when InterestLifetime has elapsed for all InRecords,
-   *  and it is not satisfied by an incoming Data.
-   *
-   *  This trigger is not invoked for PIT entry already satisfied.
-   *
-   *  In this base class this method does nothing.
-   *
-   *  \note The strategy is permitted to store a shared reference to pitEntry.
-   *        pitEntry is passed by value to reflect this fact.
-   */
-  virtual void
-  beforeExpirePendingInterest(shared_ptr<pit::Entry> pitEntry);
-
-protected: // actions
-  /// send Interest to outFace
-  VIRTUAL_WITH_TESTS void
-  sendInterest(shared_ptr<pit::Entry> pitEntry,
-               shared_ptr<Face> outFace,
-               bool wantNewNonce = false);
-
-  /** \brief decide that a pending Interest cannot be forwarded
-   *
-   *  This shall not be called if the pending Interest has been
-   *  forwarded earlier, and does not need to be resent now.
-   */
-  VIRTUAL_WITH_TESTS void
-  rejectPendingInterest(shared_ptr<pit::Entry> pitEntry);
-
-protected: // accessors
-  MeasurementsAccessor&
-  getMeasurements();
-
-  shared_ptr<Face>
-  getFace(FaceId id);
-
-  const FaceTable&
-  getFaceTable();
-
-protected: // accessors
-  signal::Signal<FaceTable, shared_ptr<Face>>& afterAddFace;
-  signal::Signal<FaceTable, shared_ptr<Face>>& beforeRemoveFace;
-
-private:
-  Name m_name;
-
-  /** \brief reference to the forwarder
-   *
-   *  Triggers can access forwarder indirectly via actions.
-   */
-  Forwarder& m_forwarder;
-
-  MeasurementsAccessor m_measurements;
-};
-
-inline const Name&
-Strategy::getName() const
-{
-  return m_name;
-}
-
-inline void
-Strategy::sendInterest(shared_ptr<pit::Entry> pitEntry,
-                       shared_ptr<Face> outFace,
-                       bool wantNewNonce)
-{
-  m_forwarder.onOutgoingInterest(pitEntry, *outFace, wantNewNonce);
-}
-
-inline void
-Strategy::rejectPendingInterest(shared_ptr<pit::Entry> pitEntry)
-{
-  m_forwarder.onInterestReject(pitEntry);
-}
-
-inline MeasurementsAccessor&
-Strategy::getMeasurements()
-{
-  return m_measurements;
-}
-
-inline shared_ptr<Face>
-Strategy::getFace(FaceId id)
-{
-  return m_forwarder.getFace(id);
-}
-
-inline const FaceTable&
-Strategy::getFaceTable()
-{
-  return m_forwarder.getFaceTable();
-}
-
-} // namespace fw
-} // namespace nfd
-
-#endif // NFD_DAEMON_FW_STRATEGY_HPP
diff --git a/NFD/daemon/mgmt/app-face.hpp b/NFD/daemon/mgmt/app-face.hpp
deleted file mode 100644
index 13442a8..0000000
--- a/NFD/daemon/mgmt/app-face.hpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_MGMT_APP_FACE_HPP
-#define NFD_DAEMON_MGMT_APP_FACE_HPP
-
-#include "common.hpp"
-
-#include <ndn-cxx/security/key-chain.hpp>
-
-namespace nfd {
-
-typedef function<void(const Name&, const Interest&)> OnInterest;
-
-class AppFace
-{
-public:
-  virtual void
-  setInterestFilter(const Name& filter,
-                    OnInterest onInterest) = 0;
-
-  virtual void
-  put(const Data& data) = 0;
-
-  virtual
-  ~AppFace() { }
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_APP_FACE_HPP
diff --git a/NFD/daemon/mgmt/channel-status-publisher.cpp b/NFD/daemon/mgmt/channel-status-publisher.cpp
deleted file mode 100644
index 8abe2fb..0000000
--- a/NFD/daemon/mgmt/channel-status-publisher.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "channel-status-publisher.hpp"
-
-#include "core/logger.hpp"
-#include "face/protocol-factory.hpp"
-#include "face/channel.hpp"
-
-#include <ndn-cxx/management/nfd-channel-status.hpp>
-
-namespace nfd {
-
-NFD_LOG_INIT("ChannelStatusPublisher");
-
-
-ChannelStatusPublisher::ChannelStatusPublisher(const FactoryMap& factories,
-                                               AppFace& face,
-                                               const Name& prefix,
-                                               ndn::KeyChain& keyChain)
-  : SegmentPublisher(face, prefix, keyChain)
-  , m_factories(factories)
-{
-
-}
-
-
-ChannelStatusPublisher::~ChannelStatusPublisher()
-{
-
-}
-
-size_t
-ChannelStatusPublisher::generate(ndn::EncodingBuffer& outBuffer)
-{
-  size_t totalLength = 0;
-  std::set<shared_ptr<ProtocolFactory> > seenFactories;
-
-  for (FactoryMap::const_iterator i = m_factories.begin();
-       i != m_factories.end(); ++i)
-    {
-      const shared_ptr<ProtocolFactory>& factory = i->second;
-
-      if (seenFactories.find(factory) != seenFactories.end())
-        {
-          continue;
-        }
-      seenFactories.insert(factory);
-
-      std::list<shared_ptr<const Channel> > channels = factory->getChannels();
-
-      for (std::list<shared_ptr<const Channel> >::const_iterator j = channels.begin();
-           j != channels.end(); ++j)
-        {
-          ndn::nfd::ChannelStatus entry;
-          entry.setLocalUri((*j)->getUri().toString());
-
-          totalLength += entry.wireEncode(outBuffer);
-        }
-    }
-
-  return totalLength;
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/mgmt/channel-status-publisher.hpp b/NFD/daemon/mgmt/channel-status-publisher.hpp
deleted file mode 100644
index ef660a3..0000000
--- a/NFD/daemon/mgmt/channel-status-publisher.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_MGMT_CHANNEL_STATUS_PUBLISHER_HPP
-#define NFD_DAEMON_MGMT_CHANNEL_STATUS_PUBLISHER_HPP
-
-#include "core/segment-publisher.hpp"
-#include "mgmt/app-face.hpp"
-
-namespace nfd {
-
-class ProtocolFactory;
-
-class ChannelStatusPublisher : public SegmentPublisher<AppFace>
-{
-public:
-  typedef std::map< std::string/*protocol*/, shared_ptr<ProtocolFactory> > FactoryMap;
-
-  ChannelStatusPublisher(const FactoryMap& factories,
-                         AppFace& face,
-                         const Name& prefix,
-                         ndn::KeyChain& keyChain);
-
-  virtual
-  ~ChannelStatusPublisher();
-
-protected:
-
-  virtual size_t
-  generate(ndn::EncodingBuffer& outBuffer);
-
-private:
-  const FactoryMap& m_factories;
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_CHANNEL_STATUS_PUBLISHER_HPP
diff --git a/NFD/daemon/mgmt/command-validator.cpp b/NFD/daemon/mgmt/command-validator.cpp
deleted file mode 100644
index 396cfe4..0000000
--- a/NFD/daemon/mgmt/command-validator.cpp
+++ /dev/null
@@ -1,222 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "command-validator.hpp"
-#include "core/logger.hpp"
-
-#include <ndn-cxx/util/io.hpp>
-#include <ndn-cxx/security/identity-certificate.hpp>
-
-#include <boost/filesystem.hpp>
-#include <fstream>
-
-namespace nfd {
-
-NFD_LOG_INIT("CommandValidator");
-
-CommandValidator::CommandValidator()
-{
-
-}
-
-CommandValidator::~CommandValidator()
-{
-
-}
-
-void
-CommandValidator::setConfigFile(ConfigFile& configFile)
-{
-  configFile.addSectionHandler("authorizations",
-                               bind(&CommandValidator::onConfig, this, _1, _2, _3));
-}
-
-static inline void
-aggregateErrors(std::stringstream& ss, const std::string& msg)
-{
-  if (!ss.str().empty())
-    {
-      ss << "\n";
-    }
-  ss << msg;
-}
-
-void
-CommandValidator::onConfig(const ConfigSection& section,
-                           bool isDryRun,
-                           const std::string& filename)
-{
-  using namespace boost::filesystem;
-
-  const ConfigSection EMPTY_SECTION;
-
-  m_validator.reset();
-
-  if (section.begin() == section.end())
-    {
-      throw ConfigFile::Error("No authorize sections found");
-    }
-
-  std::stringstream dryRunErrors;
-  ConfigSection::const_iterator authIt;
-  for (authIt = section.begin(); authIt != section.end(); authIt++)
-    {
-      std::string certfile;
-      try
-        {
-          certfile = authIt->second.get<std::string>("certfile");
-        }
-      catch (const std::runtime_error& e)
-        {
-          std::string msg = "No certfile specified";
-          if (!isDryRun)
-            {
-              throw ConfigFile::Error(msg);
-            }
-          aggregateErrors(dryRunErrors, msg);
-          continue;
-        }
-
-      shared_ptr<ndn::IdentityCertificate> id;
-
-      if (certfile != "any")
-        {
-          path certfilePath = absolute(certfile, path(filename).parent_path());
-          NFD_LOG_DEBUG("generated certfile path: " << certfilePath.native());
-
-          std::ifstream in;
-          in.open(certfilePath.c_str());
-          if (!in.is_open())
-            {
-              std::string msg = "Unable to open certificate file " + certfilePath.native();
-              if (!isDryRun)
-                {
-                  throw ConfigFile::Error(msg);
-                }
-              aggregateErrors(dryRunErrors, msg);
-              continue;
-            }
-
-          try
-            {
-              id = ndn::io::load<ndn::IdentityCertificate>(in);
-            }
-          catch (const std::runtime_error& error)
-            {
-              // do nothing
-            }
-
-          if (!static_cast<bool>(id)) {
-            std::string msg = "Malformed certificate file " + certfilePath.native();
-            if (!isDryRun)
-              {
-                throw ConfigFile::Error(msg);
-              }
-            aggregateErrors(dryRunErrors, msg);
-            continue;
-          }
-
-          in.close();
-        }
-
-      std::string keyNameForLogging;
-      if (static_cast<bool>(id))
-        keyNameForLogging = id->getPublicKeyName().toUri();
-      else
-        {
-          keyNameForLogging = "wildcard";
-          NFD_LOG_WARN("Wildcard identity is intended for demo purpose only and " <<
-                       "SHOULD NOT be used in production environment");
-        }
-      const ConfigSection* privileges = 0;
-      try
-        {
-          privileges = &authIt->second.get_child("privileges");
-        }
-      catch (const std::runtime_error& error)
-        {
-          std::string msg = "No privileges section found for certificate file " +
-            certfile + " (" + keyNameForLogging + ")";
-          if (!isDryRun)
-            {
-              throw ConfigFile::Error(msg);
-            }
-          aggregateErrors(dryRunErrors, msg);
-          continue;
-        }
-
-      if (privileges->begin() == privileges->end())
-        {
-          NFD_LOG_WARN("No privileges specified for certificate file " << certfile
-                       << " (" << keyNameForLogging << ")");
-        }
-
-      ConfigSection::const_iterator privIt;
-      for (privIt = privileges->begin(); privIt != privileges->end(); privIt++)
-        {
-          const std::string& privilegeName = privIt->first;
-          if (m_supportedPrivileges.find(privilegeName) != m_supportedPrivileges.end())
-            {
-              NFD_LOG_INFO("Giving privilege \"" << privilegeName
-                           << "\" to identity " << keyNameForLogging);
-              if (!isDryRun)
-                {
-                  const std::string regex = "^<localhost><nfd><" + privilegeName + ">";
-                  if (static_cast<bool>(id))
-                    m_validator.addInterestRule(regex, *id);
-                  else
-                    m_validator.addInterestBypassRule(regex);
-                }
-            }
-          else
-            {
-              // Invalid configuration
-              std::string msg = "Invalid privilege \"" + privilegeName +
-                "\" for certificate file " + certfile + " (" + keyNameForLogging + ")";
-              if (!isDryRun)
-                {
-                  throw ConfigFile::Error(msg);
-                }
-              aggregateErrors(dryRunErrors, msg);
-            }
-        }
-    }
-
-  if (!dryRunErrors.str().empty())
-    {
-      throw ConfigFile::Error(dryRunErrors.str());
-    }
-}
-
-void
-CommandValidator::addSupportedPrivilege(const std::string& privilege)
-{
-  if (m_supportedPrivileges.find(privilege) != m_supportedPrivileges.end())
-    {
-      throw CommandValidator::Error("Duplicated privilege: " + privilege);
-    }
-  m_supportedPrivileges.insert(privilege);
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/mgmt/command-validator.hpp b/NFD/daemon/mgmt/command-validator.hpp
deleted file mode 100644
index b2cb184..0000000
--- a/NFD/daemon/mgmt/command-validator.hpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#ifndef NFD_DAEMON_MGMT_COMMAND_VALIDATOR_HPP
-#define NFD_DAEMON_MGMT_COMMAND_VALIDATOR_HPP
-
-#include "common.hpp"
-#include "config-file.hpp"
-#include <ndn-cxx/util/command-interest-validator.hpp>
-
-namespace nfd {
-
-class CommandValidator
-{
-public:
-
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-
-    }
-  };
-
-  CommandValidator();
-
-  ~CommandValidator();
-
-  void
-  setConfigFile(ConfigFile& configFile);
-
-  /**
-   * \param section "authorizations" section to parse
-   * \param isDryRun true if performing a dry run of configuration, false otherwise
-   * \param filename filename of configuration file
-   * \throws ConfigFile::Error on parse error
-   */
-  void
-  onConfig(const ConfigSection& section, bool isDryRun, const std::string& filename);
-
-  /**
-   * \param privilege name of privilege to add
-   * \throws CommandValidator::Error on duplicated privilege
-   */
-  void
-  addSupportedPrivilege(const std::string& privilege);
-
-  void
-  addInterestRule(const std::string& regex,
-                  const ndn::IdentityCertificate& certificate);
-
-  void
-  addInterestRule(const std::string& regex,
-                  const Name& keyName,
-                  const ndn::PublicKey& publicKey);
-
-  void
-  validate(const Interest& interest,
-           const ndn::OnInterestValidated& onValidated,
-           const ndn::OnInterestValidationFailed& onValidationFailed);
-
-private:
-  ndn::CommandInterestValidator m_validator;
-  std::set<std::string> m_supportedPrivileges;
-};
-
-inline void
-CommandValidator::addInterestRule(const std::string& regex,
-                                  const ndn::IdentityCertificate& certificate)
-{
-  m_validator.addInterestRule(regex, certificate);
-}
-
-inline void
-CommandValidator::addInterestRule(const std::string& regex,
-                                  const Name& keyName,
-                                  const ndn::PublicKey& publicKey)
-{
-  m_validator.addInterestRule(regex, keyName, publicKey);
-}
-
-inline void
-CommandValidator::validate(const Interest& interest,
-                           const ndn::OnInterestValidated& onValidated,
-                           const ndn::OnInterestValidationFailed& onValidationFailed)
-{
-  m_validator.validate(interest, onValidated, onValidationFailed);
-}
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_COMMAND_VALIDATOR_HPP
diff --git a/NFD/daemon/mgmt/face-manager.cpp b/NFD/daemon/mgmt/face-manager.cpp
deleted file mode 100644
index 164df04..0000000
--- a/NFD/daemon/mgmt/face-manager.cpp
+++ /dev/null
@@ -1,500 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "face-manager.hpp"
-
-#include "core/logger.hpp"
-#include "core/config-file.hpp"
-#include "face/protocol-factory.hpp"
-#include "fw/face-table.hpp"
-
-#include <ndn-cxx/management/nfd-face-event-notification.hpp>
-#include <ndn-cxx/management/nfd-face-query-filter.hpp>
-
-namespace nfd {
-
-NFD_LOG_INIT("FaceManager");
-
-const Name FaceManager::COMMAND_PREFIX("/localhost/nfd/faces");
-
-const size_t FaceManager::COMMAND_UNSIGNED_NCOMPS =
-  FaceManager::COMMAND_PREFIX.size() +
-  1 + // verb
-  1;  // verb parameters
-
-const size_t FaceManager::COMMAND_SIGNED_NCOMPS =
-  FaceManager::COMMAND_UNSIGNED_NCOMPS +
-  4; // (timestamp, nonce, signed info tlv, signature tlv)
-
-const FaceManager::SignedVerbAndProcessor FaceManager::SIGNED_COMMAND_VERBS[] =
-  {
-    SignedVerbAndProcessor(
-                           Name::Component("create"),
-                           &FaceManager::createFace
-                           ),
-
-    SignedVerbAndProcessor(
-                           Name::Component("destroy"),
-                           &FaceManager::destroyFace
-                           ),
-
-    SignedVerbAndProcessor(
-                           Name::Component("enable-local-control"),
-                           &FaceManager::enableLocalControl
-                           ),
-
-    SignedVerbAndProcessor(
-                           Name::Component("disable-local-control"),
-                           &FaceManager::disableLocalControl
-                           ),
-  };
-
-const FaceManager::UnsignedVerbAndProcessor FaceManager::UNSIGNED_COMMAND_VERBS[] =
-  {
-    UnsignedVerbAndProcessor(
-                             Name::Component("list"),
-                             &FaceManager::listFaces
-                             ),
-
-    UnsignedVerbAndProcessor(
-                             Name::Component("events"),
-                             &FaceManager::ignoreUnsignedVerb
-                             ),
-
-    UnsignedVerbAndProcessor(
-                             Name::Component("channels"),
-                             &FaceManager::listChannels
-                             ),
-
-    UnsignedVerbAndProcessor(
-                             Name::Component("query"),
-                             &FaceManager::listQueriedFaces
-                             ),
-  };
-
-const Name FaceManager::FACES_LIST_DATASET_PREFIX("/localhost/nfd/faces/list");
-const size_t FaceManager::FACES_LIST_DATASET_NCOMPS = FACES_LIST_DATASET_PREFIX.size();
-
-const Name FaceManager::FACE_EVENTS_PREFIX("/localhost/nfd/faces/events");
-
-const Name FaceManager::CHANNELS_LIST_DATASET_PREFIX("/localhost/nfd/faces/channels");
-const size_t FaceManager::CHANNELS_LIST_DATASET_NCOMPS = CHANNELS_LIST_DATASET_PREFIX.size();
-
-const Name FaceManager::FACES_QUERY_DATASET_PREFIX("/localhost/nfd/faces/query");
-const size_t FaceManager::FACES_QUERY_DATASET_NCOMPS = FACES_QUERY_DATASET_PREFIX.size() + 1;
-
-FaceManager::FaceManager(FaceTable& faceTable,
-                         shared_ptr<InternalFace> face,
-                         ndn::KeyChain& keyChain)
-  : ManagerBase(face, FACE_MANAGER_PRIVILEGE, keyChain)
-  , m_faceTable(faceTable)
-  , m_faceAddConn(m_faceTable.onAdd.connect(bind(&FaceManager::onAddFace, this, _1)))
-  , m_faceRemoveConn(m_faceTable.onRemove.connect(bind(&FaceManager::onRemoveFace, this, _1)))
-  , m_faceStatusPublisher(m_faceTable, *m_face, FACES_LIST_DATASET_PREFIX, keyChain)
-  , m_channelStatusPublisher(m_factories, *m_face, CHANNELS_LIST_DATASET_PREFIX, keyChain)
-  , m_notificationStream(*m_face, FACE_EVENTS_PREFIX, keyChain)
-  , m_signedVerbDispatch(SIGNED_COMMAND_VERBS,
-                         SIGNED_COMMAND_VERBS +
-                         (sizeof(SIGNED_COMMAND_VERBS) / sizeof(SignedVerbAndProcessor)))
-  , m_unsignedVerbDispatch(UNSIGNED_COMMAND_VERBS,
-                           UNSIGNED_COMMAND_VERBS +
-                           (sizeof(UNSIGNED_COMMAND_VERBS) / sizeof(UnsignedVerbAndProcessor)))
-
-{
-  face->setInterestFilter("/localhost/nfd/faces",
-                          bind(&FaceManager::onFaceRequest, this, _2));
-}
-
-FaceManager::~FaceManager()
-{
-
-}
-
-void
-FaceManager::setConfigFile(ConfigFile& configFile)
-{
-  configFile.addSectionHandler("face_system",
-                               bind(&FaceManager::onConfig, this, _1, _2, _3));
-}
-
-
-void
-FaceManager::onConfig(const ConfigSection& configSection,
-                      bool isDryRun,
-                      const std::string& filename)
-{
-  throw Error("Not supported");
-}
-
-void
-FaceManager::onFaceRequest(const Interest& request)
-{
-  const Name& command = request.getName();
-  const size_t commandNComps = command.size();
-
-  if (commandNComps <= COMMAND_PREFIX.size())
-    {
-      // command is too short to have a verb
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-      return;
-    }
-
-  const Name::Component& verb = command.at(COMMAND_PREFIX.size());
-
-  const auto unsignedVerbProcessor = m_unsignedVerbDispatch.find(verb);
-  if (unsignedVerbProcessor != m_unsignedVerbDispatch.end())
-    {
-      NFD_LOG_DEBUG("command result: processing verb: " << verb);
-      (unsignedVerbProcessor->second)(this, request);
-    }
-  else if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
-           commandNComps < COMMAND_SIGNED_NCOMPS)
-    {
-      NFD_LOG_DEBUG("command result: unsigned verb: " << command);
-      sendResponse(command, 401, "Signature required");
-    }
-  else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
-           !COMMAND_PREFIX.isPrefixOf(command))
-    {
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-    }
-  else
-    {
-      validate(request,
-               bind(&FaceManager::onValidatedFaceRequest, this, _1),
-               bind(&ManagerBase::onCommandValidationFailed, this, _1, _2));
-    }
-}
-
-void
-FaceManager::onValidatedFaceRequest(const shared_ptr<const Interest>& request)
-{
-  const Name& command = request->getName();
-  const Name::Component& verb = command[COMMAND_PREFIX.size()];
-  const Name::Component& parameterComponent = command[COMMAND_PREFIX.size() + 1];
-
-  SignedVerbDispatchTable::const_iterator signedVerbProcessor = m_signedVerbDispatch.find(verb);
-  if (signedVerbProcessor != m_signedVerbDispatch.end())
-    {
-      ControlParameters parameters;
-      if (!extractParameters(parameterComponent, parameters))
-        {
-          sendResponse(command, 400, "Malformed command");
-          return;
-        }
-
-      NFD_LOG_DEBUG("command result: processing verb: " << verb);
-      (signedVerbProcessor->second)(this, *request, parameters);
-    }
-  else
-    {
-      NFD_LOG_DEBUG("command result: unsupported verb: " << verb);
-      sendResponse(command, 501, "Unsupported command");
-    }
-
-}
-
-void
-FaceManager::addCreatedFaceToForwarder(const shared_ptr<Face>& newFace)
-{
-  m_faceTable.add(newFace);
-
-  //NFD_LOG_DEBUG("Created face " << newFace->getRemoteUri() << " ID " << newFace->getId());
-}
-
-void
-FaceManager::onCreated(const Name& requestName,
-                       ControlParameters& parameters,
-                       const shared_ptr<Face>& newFace)
-{
-  addCreatedFaceToForwarder(newFace);
-  parameters.setFaceId(newFace->getId());
-  parameters.setUri(newFace->getRemoteUri().toString());
-
-  sendResponse(requestName, 200, "Success", parameters.wireEncode());
-}
-
-void
-FaceManager::onConnectFailed(const Name& requestName, const std::string& reason)
-{
-  NFD_LOG_DEBUG("Failed to create face: " << reason);
-  sendResponse(requestName, 408, reason);
-}
-
-void
-FaceManager::createFace(const Interest& request,
-                        ControlParameters& parameters)
-{
-  const Name& requestName = request.getName();
-  ndn::nfd::FaceCreateCommand command;
-
-  if (!validateParameters(command, parameters))
-    {
-      sendResponse(requestName, 400, "Malformed command");
-      NFD_LOG_TRACE("invalid control parameters URI");
-      return;
-    }
-
-  FaceUri uri;
-  if (!uri.parse(parameters.getUri()))
-    {
-      sendResponse(requestName, 400, "Malformed command");
-      NFD_LOG_TRACE("failed to parse URI");
-      return;
-    }
-
-  if (!uri.isCanonical())
-    {
-      sendResponse(requestName, 400, "Non-canonical URI");
-      NFD_LOG_TRACE("received non-canonical URI");
-      return;
-    }
-
-  FactoryMap::iterator factory = m_factories.find(uri.getScheme());
-  if (factory == m_factories.end())
-    {
-      sendResponse(requestName, 501, "Unsupported protocol");
-      return;
-    }
-
-  try
-    {
-      factory->second->createFace(uri,
-                                  bind(&FaceManager::onCreated,
-                                       this, requestName, parameters, _1),
-                                  bind(&FaceManager::onConnectFailed,
-                                       this, requestName, _1));
-    }
-  catch (const std::runtime_error& error)
-    {
-      std::string errorMessage = "NFD error: ";
-      errorMessage += error.what();
-
-      NFD_LOG_ERROR(errorMessage);
-      sendResponse(requestName, 500, errorMessage);
-    }
-  catch (const std::logic_error& error)
-    {
-      std::string errorMessage = "NFD error: ";
-      errorMessage += error.what();
-
-      NFD_LOG_ERROR(errorMessage);
-      sendResponse(requestName, 500, errorMessage);
-    }
-}
-
-
-void
-FaceManager::destroyFace(const Interest& request,
-                         ControlParameters& parameters)
-{
-  const Name& requestName = request.getName();
-  ndn::nfd::FaceDestroyCommand command;
-
-  if (!validateParameters(command, parameters))
-    {
-      sendResponse(requestName, 400, "Malformed command");
-      return;
-    }
-
-  shared_ptr<Face> target = m_faceTable.get(parameters.getFaceId());
-  if (static_cast<bool>(target))
-    {
-      target->close();
-    }
-
-  sendResponse(requestName, 200, "Success", parameters.wireEncode());
-
-}
-
-void
-FaceManager::onAddFace(shared_ptr<Face> face)
-{
-  ndn::nfd::FaceEventNotification notification;
-  notification.setKind(ndn::nfd::FACE_EVENT_CREATED);
-  face->copyStatusTo(notification);
-
-  m_notificationStream.postNotification(notification);
-}
-
-void
-FaceManager::onRemoveFace(shared_ptr<Face> face)
-{
-  ndn::nfd::FaceEventNotification notification;
-  notification.setKind(ndn::nfd::FACE_EVENT_DESTROYED);
-  face->copyStatusTo(notification);
-
-  m_notificationStream.postNotification(notification);
-}
-
-bool
-FaceManager::extractLocalControlParameters(const Interest& request,
-                                           ControlParameters& parameters,
-                                           ControlCommand& command,
-                                           shared_ptr<LocalFace>& outFace,
-                                           LocalControlFeature& outFeature)
-{
-  if (!validateParameters(command, parameters))
-    {
-      sendResponse(request.getName(), 400, "Malformed command");
-      return false;
-    }
-
-  shared_ptr<Face> face = m_faceTable.get(request.getIncomingFaceId());
-
-  if (!static_cast<bool>(face))
-    {
-      NFD_LOG_DEBUG("command result: faceid " << request.getIncomingFaceId() << " not found");
-      sendResponse(request.getName(), 410, "Face not found");
-      return false;
-    }
-  else if (!face->isLocal())
-    {
-      NFD_LOG_DEBUG("command result: cannot enable local control on non-local faceid " <<
-                    face->getId());
-      sendResponse(request.getName(), 412, "Face is non-local");
-      return false;
-    }
-
-  outFace = dynamic_pointer_cast<LocalFace>(face);
-  outFeature = static_cast<LocalControlFeature>(parameters.getLocalControlFeature());
-
-  return true;
-}
-
-void
-FaceManager::enableLocalControl(const Interest& request,
-                                ControlParameters& parameters)
-{
-  ndn::nfd::FaceEnableLocalControlCommand command;
-
-
-  shared_ptr<LocalFace> face;
-  LocalControlFeature feature;
-
-  if (extractLocalControlParameters(request, parameters, command, face, feature))
-    {
-      face->setLocalControlHeaderFeature(feature, true);
-      sendResponse(request.getName(), 200, "Success", parameters.wireEncode());
-    }
-}
-
-void
-FaceManager::disableLocalControl(const Interest& request,
-                                 ControlParameters& parameters)
-{
-  ndn::nfd::FaceDisableLocalControlCommand command;
-  shared_ptr<LocalFace> face;
-  LocalControlFeature feature;
-
-  if (extractLocalControlParameters(request, parameters, command, face, feature))
-    {
-      face->setLocalControlHeaderFeature(feature, false);
-      sendResponse(request.getName(), 200, "Success", parameters.wireEncode());
-    }
-}
-
-void
-FaceManager::listFaces(const Interest& request)
-{
-  const Name& command = request.getName();
-  const size_t commandNComps = command.size();
-
-  if (commandNComps < FACES_LIST_DATASET_NCOMPS ||
-      !FACES_LIST_DATASET_PREFIX.isPrefixOf(command))
-    {
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-      return;
-    }
-
-  m_faceStatusPublisher.publish();
-}
-
-void
-FaceManager::listChannels(const Interest& request)
-{
-  NFD_LOG_DEBUG("in listChannels");
-  const Name& command = request.getName();
-  const size_t commandNComps = command.size();
-
-  if (commandNComps < CHANNELS_LIST_DATASET_NCOMPS ||
-      !CHANNELS_LIST_DATASET_PREFIX.isPrefixOf(command))
-    {
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-      return;
-    }
-
-  NFD_LOG_DEBUG("publishing");
-  m_channelStatusPublisher.publish();
-}
-
-void
-FaceManager::listQueriedFaces(const Interest& request)
-{
-  NFD_LOG_DEBUG("in listQueriedFaces");
-  const Name& query = request.getName();
-  const size_t queryNComps = query.size();
-
-  if (queryNComps < FACES_QUERY_DATASET_NCOMPS ||
-      !FACES_QUERY_DATASET_PREFIX.isPrefixOf(query))
-    {
-      NFD_LOG_DEBUG("query result: malformed");
-      sendNack(query);
-      return;
-    }
-
-  ndn::nfd::FaceQueryFilter faceFilter;
-  try
-    {
-      faceFilter.wireDecode(query[-1].blockFromValue());
-    }
-  catch (tlv::Error&)
-    {
-      NFD_LOG_DEBUG("query result: malformed filter");
-      sendNack(query);
-      return;
-    }
-
-  FaceQueryStatusPublisher
-    faceQueryStatusPublisher(m_faceTable, *m_face, query, faceFilter, m_keyChain);
-
-  faceQueryStatusPublisher.publish();
-}
-
-shared_ptr<ProtocolFactory>
-FaceManager::findFactory(const std::string& protocol)
-{
-  FactoryMap::iterator factory = m_factories.find(protocol);
-  if (factory != m_factories.end())
-    return factory->second;
-  else
-    return shared_ptr<ProtocolFactory>();
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/mgmt/face-manager.hpp b/NFD/daemon/mgmt/face-manager.hpp
deleted file mode 100644
index eb375fc..0000000
--- a/NFD/daemon/mgmt/face-manager.hpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_MGMT_FACE_MANAGER_HPP
-#define NFD_DAEMON_MGMT_FACE_MANAGER_HPP
-
-#include "common.hpp"
-#include "core/notification-stream.hpp"
-#include "face/local-face.hpp"
-#include "mgmt/manager-base.hpp"
-#include "mgmt/face-status-publisher.hpp"
-#include "mgmt/channel-status-publisher.hpp"
-#include "mgmt/face-query-status-publisher.hpp"
-
-#include <ndn-cxx/management/nfd-control-parameters.hpp>
-#include <ndn-cxx/management/nfd-control-response.hpp>
-
-namespace nfd {
-
-const std::string FACE_MANAGER_PRIVILEGE = "faces";
-
-class ConfigFile;
-class Face;
-class FaceTable;
-class LocalFace;
-class NetworkInterfaceInfo;
-class ProtocolFactory;
-
-class FaceManager : public ManagerBase
-{
-public:
-  class Error : public ManagerBase::Error
-  {
-  public:
-    Error(const std::string& what) : ManagerBase::Error(what) {}
-  };
-
-  /**
-   * \throws FaceManager::Error if localPort is an invalid port number
-   */
-  FaceManager(FaceTable& faceTable,
-              shared_ptr<InternalFace> face,
-              ndn::KeyChain& keyChain);
-
-  virtual
-  ~FaceManager();
-
-  /** \brief Subscribe to a face management section(s) for the config file
-   */
-  void
-  setConfigFile(ConfigFile& configFile);
-
-  void
-  onFaceRequest(const Interest& request);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  void
-  listFaces(const Interest& request);
-
-  void
-  listChannels(const Interest& request);
-
-  void
-  listQueriedFaces(const Interest& request);
-
-  shared_ptr<ProtocolFactory>
-  findFactory(const std::string& protocol);
-
-PROTECTED_WITH_TESTS_ELSE_PRIVATE:
-  void
-  onValidatedFaceRequest(const shared_ptr<const Interest>& request);
-
-  VIRTUAL_WITH_TESTS void
-  createFace(const Interest& request,
-             ControlParameters& parameters);
-
-  VIRTUAL_WITH_TESTS void
-  destroyFace(const Interest& request,
-              ControlParameters& parameters);
-
-  VIRTUAL_WITH_TESTS bool
-  extractLocalControlParameters(const Interest& request,
-                                ControlParameters& parameters,
-                                ControlCommand& command,
-                                shared_ptr<LocalFace>& outFace,
-                                LocalControlFeature& outFeature);
-
-  VIRTUAL_WITH_TESTS void
-  enableLocalControl(const Interest& request,
-                     ControlParameters& parambeters);
-
-  VIRTUAL_WITH_TESTS void
-  disableLocalControl(const Interest& request,
-                      ControlParameters& parameters);
-
-  void
-  ignoreUnsignedVerb(const Interest& request);
-
-  void
-  addCreatedFaceToForwarder(const shared_ptr<Face>& newFace);
-
-  void
-  onCreated(const Name& requestName,
-            ControlParameters& parameters,
-            const shared_ptr<Face>& newFace);
-
-  void
-  onConnectFailed(const Name& requestName, const std::string& reason);
-
-  void
-  onAddFace(shared_ptr<Face> face);
-
-  void
-  onRemoveFace(shared_ptr<Face> face);
-
-private:
-  void
-  onConfig(const ConfigSection& configSection, bool isDryRun, const std::string& filename);
-
-  /** \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"
-   */
-  bool
-  parseYesNo(const ConfigSection::const_iterator& i,
-             const std::string& optionName,
-             const std::string& sectionName);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  typedef std::map<std::string/*protocol*/, shared_ptr<ProtocolFactory>> FactoryMap;
-  FactoryMap m_factories;
-
-private:
-  FaceTable& m_faceTable;
-  signal::ScopedConnection m_faceAddConn;
-  signal::ScopedConnection m_faceRemoveConn;
-  FaceStatusPublisher m_faceStatusPublisher;
-  ChannelStatusPublisher m_channelStatusPublisher;
-  NotificationStream<AppFace> m_notificationStream;
-
-  typedef function<void(FaceManager*,
-                        const Interest&,
-                        ControlParameters&)> SignedVerbProcessor;
-
-  typedef std::map<Name::Component, SignedVerbProcessor> SignedVerbDispatchTable;
-  typedef std::pair<Name::Component, SignedVerbProcessor> SignedVerbAndProcessor;
-
-  typedef function<void(FaceManager*, const Interest&)> UnsignedVerbProcessor;
-
-  typedef std::map<Name::Component, UnsignedVerbProcessor> UnsignedVerbDispatchTable;
-  typedef std::pair<Name::Component, UnsignedVerbProcessor> UnsignedVerbAndProcessor;
-
-  const SignedVerbDispatchTable m_signedVerbDispatch;
-  const UnsignedVerbDispatchTable m_unsignedVerbDispatch;
-
-  static const Name COMMAND_PREFIX; // /localhost/nfd/faces
-
-  // number of components in an invalid signed command (i.e. should be signed, but isn't)
-  // (/localhost/nfd/faces + verb + parameters) = 5
-  static const size_t COMMAND_UNSIGNED_NCOMPS;
-
-  // number of components in a valid signed command.
-  // (see UNSIGNED_NCOMPS), 9 with signed Interest support.
-  static const size_t COMMAND_SIGNED_NCOMPS;
-
-  static const SignedVerbAndProcessor SIGNED_COMMAND_VERBS[];
-  static const UnsignedVerbAndProcessor UNSIGNED_COMMAND_VERBS[];
-
-  static const Name FACES_LIST_DATASET_PREFIX;
-  static const size_t FACES_LIST_DATASET_NCOMPS;
-
-  static const Name CHANNELS_LIST_DATASET_PREFIX;
-  static const size_t CHANNELS_LIST_DATASET_NCOMPS;
-
-  static const Name FACES_QUERY_DATASET_PREFIX;
-  static const size_t FACES_QUERY_DATASET_NCOMPS;
-
-  static const Name FACE_EVENTS_PREFIX;
-};
-
-inline bool
-FaceManager::parseYesNo(const ConfigSection::const_iterator& i,
-                        const std::string& optionName,
-                        const std::string& sectionName)
-{
-  const std::string value = i->second.get_value<std::string>();
-  if (value == "yes")
-    {
-      return true;
-    }
-  else if (value == "no")
-    {
-      return false;
-    }
-
-  throw ConfigFile::Error("Invalid value for option \"" +
-                          optionName + "\" in \"" +
-                          sectionName + "\" section");
-}
-
-inline void
-FaceManager::ignoreUnsignedVerb(const Interest& request)
-{
-  // do nothing
-}
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_FACE_MANAGER_HPP
diff --git a/NFD/daemon/mgmt/face-query-status-publisher.cpp b/NFD/daemon/mgmt/face-query-status-publisher.cpp
deleted file mode 100644
index d208087..0000000
--- a/NFD/daemon/mgmt/face-query-status-publisher.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "face-query-status-publisher.hpp"
-#include "core/logger.hpp"
-#include <boost/range/adaptor/reversed.hpp>
-
-#include <ndn-cxx/management/nfd-face-status.hpp>
-
-namespace nfd {
-
-NFD_LOG_INIT("FaceQueryStatusPublisher");
-
-
-FaceQueryStatusPublisher::FaceQueryStatusPublisher(const FaceTable& faceTable,
-                                                   AppFace& face,
-                                                   const Name& prefix,
-                                                   const ndn::nfd::FaceQueryFilter& filter,
-                                                   ndn::KeyChain& keyChain)
-  : SegmentPublisher(face, prefix, keyChain)
-  , m_faceTable(faceTable)
-  , m_faceFilter(filter)
-{
-}
-
-FaceQueryStatusPublisher::~FaceQueryStatusPublisher()
-{
-}
-
-bool
-FaceQueryStatusPublisher::doesMatchFilter(const shared_ptr<Face>& face)
-{
-  if (m_faceFilter.hasFaceId() &&
-      m_faceFilter.getFaceId() != static_cast<uint64_t>(face->getId())) {
-    return false;
-  }
-
-  if (m_faceFilter.hasUriScheme() &&
-      (m_faceFilter.getUriScheme() != face->getRemoteUri().getScheme() ||
-       m_faceFilter.getUriScheme() != face->getLocalUri().getScheme())) {
-    return false;
-  }
-
-  if (m_faceFilter.hasRemoteUri() &&
-      m_faceFilter.getRemoteUri() != face->getRemoteUri().toString()) {
-    return false;
-  }
-
-  if (m_faceFilter.hasLocalUri() && m_faceFilter.getLocalUri() != face->getLocalUri().toString()) {
-    return false;
-  }
-
-  if (m_faceFilter.hasFaceScope() &&
-      (m_faceFilter.getFaceScope() == ndn::nfd::FACE_SCOPE_LOCAL) != face->isLocal()) {
-    return false;
-  }
-
-  if (m_faceFilter.hasFacePersistency() &&
-      (m_faceFilter.getFacePersistency() == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) !=
-      face->isOnDemand()) {
-    return false;
-  }
-
-  if (m_faceFilter.hasLinkType() &&
-      (m_faceFilter.getLinkType() == ndn::nfd::LINK_TYPE_MULTI_ACCESS) != face->isMultiAccess()) {
-    return false;
-  }
-
-  return true;
-}
-
-size_t
-FaceQueryStatusPublisher::generate(ndn::EncodingBuffer& outBuffer)
-{
-  size_t totalLength = 0;
-
-  for (const shared_ptr<Face>& face : m_faceTable | boost::adaptors::reversed) {
-    if (doesMatchFilter(face)) {
-      ndn::nfd::FaceStatus status = face->getFaceStatus();
-      totalLength += status.wireEncode(outBuffer);
-    }
-  }
-  return totalLength;
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/mgmt/face-query-status-publisher.hpp b/NFD/daemon/mgmt/face-query-status-publisher.hpp
deleted file mode 100644
index 237cecb..0000000
--- a/NFD/daemon/mgmt/face-query-status-publisher.hpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_MGMT_QUERIED_FACE_STATUS_PUBLISHER_HPP
-#define NFD_DAEMON_MGMT_QUERIED_FACE_STATUS_PUBLISHER_HPP
-
-#include "core/segment-publisher.hpp"
-#include "mgmt/app-face.hpp"
-#include "fw/face-table.hpp"
-
-#include <ndn-cxx/management/nfd-face-query-filter.hpp>
-
-namespace nfd {
-
-class FaceQueryStatusPublisher : public SegmentPublisher<AppFace>
-{
-public:
-  FaceQueryStatusPublisher(const FaceTable& faceTable,
-                           AppFace& face,
-                           const Name& prefix,
-                           const ndn::nfd::FaceQueryFilter& filter,
-                           ndn::KeyChain& keyChain);
-
-  virtual
-  ~FaceQueryStatusPublisher();
-
-  bool
-  doesMatchFilter(const shared_ptr<Face>& face);
-
-protected:
-
-  virtual size_t
-  generate(ndn::EncodingBuffer& outBuffer);
-
-private:
-  const FaceTable& m_faceTable;
-  const ndn::nfd::FaceQueryFilter& m_faceFilter;
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_QUERIED_FACE_STATUS_PUBLISHER_HPP
diff --git a/NFD/daemon/mgmt/face-status-publisher.cpp b/NFD/daemon/mgmt/face-status-publisher.cpp
deleted file mode 100644
index 759f9ce..0000000
--- a/NFD/daemon/mgmt/face-status-publisher.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "face-status-publisher.hpp"
-#include "core/logger.hpp"
-#include "fw/face-table.hpp"
-#include <boost/range/adaptor/reversed.hpp>
-
-#include <ndn-cxx/management/nfd-face-status.hpp>
-
-namespace nfd {
-
-NFD_LOG_INIT("FaceStatusPublisher");
-
-
-FaceStatusPublisher::FaceStatusPublisher(const FaceTable& faceTable,
-                                         AppFace& face,
-                                         const Name& prefix,
-                                         ndn::KeyChain& keyChain)
-  : SegmentPublisher(face, prefix, keyChain)
-  , m_faceTable(faceTable)
-{
-
-}
-
-
-FaceStatusPublisher::~FaceStatusPublisher()
-{
-
-}
-
-size_t
-FaceStatusPublisher::generate(ndn::EncodingBuffer& outBuffer)
-{
-  size_t totalLength = 0;
-
-  for (const shared_ptr<Face>& face : m_faceTable | boost::adaptors::reversed) {
-    ndn::nfd::FaceStatus status = face->getFaceStatus();
-    totalLength += status.wireEncode(outBuffer);
-  }
-  return totalLength;
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/mgmt/face-status-publisher.hpp b/NFD/daemon/mgmt/face-status-publisher.hpp
deleted file mode 100644
index 5091165..0000000
--- a/NFD/daemon/mgmt/face-status-publisher.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_MGMT_FACE_STATUS_PUBLISHER_HPP
-#define NFD_DAEMON_MGMT_FACE_STATUS_PUBLISHER_HPP
-
-#include "core/segment-publisher.hpp"
-#include "mgmt/app-face.hpp"
-
-namespace nfd {
-
-class FaceTable;
-
-class FaceStatusPublisher : public SegmentPublisher<AppFace>
-{
-public:
-  FaceStatusPublisher(const FaceTable& faceTable,
-                      AppFace& face,
-                      const Name& prefix,
-                      ndn::KeyChain& keyChain);
-
-  virtual
-  ~FaceStatusPublisher();
-
-protected:
-
-  virtual size_t
-  generate(ndn::EncodingBuffer& outBuffer);
-
-private:
-  const FaceTable& m_faceTable;
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_FACE_STATUS_PUBLISHER_HPP
diff --git a/NFD/daemon/mgmt/fib-enumeration-publisher.cpp b/NFD/daemon/mgmt/fib-enumeration-publisher.cpp
deleted file mode 100644
index b7bad51..0000000
--- a/NFD/daemon/mgmt/fib-enumeration-publisher.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "fib-enumeration-publisher.hpp"
-#include "core/logger.hpp"
-#include "table/fib.hpp"
-
-#include <ndn-cxx/management/nfd-fib-entry.hpp>
-
-namespace nfd {
-
-NFD_LOG_INIT("FibEnumerationPublisher");
-
-FibEnumerationPublisher::FibEnumerationPublisher(const Fib& fib,
-                                                 AppFace& face,
-                                                 const Name& prefix,
-                                                 ndn::KeyChain& keyChain)
-  : SegmentPublisher(face, prefix, keyChain)
-  , m_fib(fib)
-{
-}
-
-FibEnumerationPublisher::~FibEnumerationPublisher()
-{
-}
-
-size_t
-FibEnumerationPublisher::generate(ndn::EncodingBuffer& outBuffer)
-{
-  size_t totalLength = 0;
-
-  /// \todo Enable use of Fib::const_reverse_iterator (when it is available)
-  for (Fib::const_iterator i = m_fib.begin(); i != m_fib.end(); ++i)
-    {
-      const fib::Entry& entry = *i;
-      const Name& prefix = entry.getPrefix();
-      size_t fibEntryLength = 0;
-
-      ndn::nfd::FibEntry tlvEntry;
-      const fib::NextHopList& nextHops = entry.getNextHops();
-
-      for (fib::NextHopList::const_iterator j = nextHops.begin();
-           j != nextHops.end();
-           ++j)
-        {
-          const fib::NextHop& next = *j;
-          ndn::nfd::NextHopRecord nextHopRecord;
-          nextHopRecord.setFaceId(next.getFace()->getId());
-          nextHopRecord.setCost(next.getCost());
-
-          tlvEntry.addNextHopRecord(nextHopRecord);
-        }
-
-      tlvEntry.setPrefix(prefix);
-      fibEntryLength += tlvEntry.wireEncode(outBuffer);
-
-      NFD_LOG_DEBUG("generate: fib entry length = " << fibEntryLength);
-
-      totalLength += fibEntryLength;
-    }
-  NFD_LOG_DEBUG("generate: Total length = " << totalLength);
-  return totalLength;
-}
-
-
-} // namespace nfd
diff --git a/NFD/daemon/mgmt/fib-enumeration-publisher.hpp b/NFD/daemon/mgmt/fib-enumeration-publisher.hpp
deleted file mode 100644
index 2ff5c31..0000000
--- a/NFD/daemon/mgmt/fib-enumeration-publisher.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_MGMT_FIB_ENUMERATION_PUBLISHER_HPP
-#define NFD_DAEMON_MGMT_FIB_ENUMERATION_PUBLISHER_HPP
-
-#include "core/segment-publisher.hpp"
-#include "mgmt/app-face.hpp"
-
-namespace nfd {
-
-class Fib;
-
-class FibEnumerationPublisher : public SegmentPublisher<AppFace>
-{
-public:
-  FibEnumerationPublisher(const Fib& fib,
-                          AppFace& face,
-                          const Name& prefix,
-                          ndn::KeyChain& keyChain);
-
-  virtual
-  ~FibEnumerationPublisher();
-
-protected:
-
-  virtual size_t
-  generate(ndn::EncodingBuffer& outBuffer);
-
-private:
-  const Fib& m_fib;
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_FIB_ENUMERATION_PUBLISHER_HPP
diff --git a/NFD/daemon/mgmt/fib-manager.cpp b/NFD/daemon/mgmt/fib-manager.cpp
deleted file mode 100644
index 3db26e7..0000000
--- a/NFD/daemon/mgmt/fib-manager.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "fib-manager.hpp"
-
-#include "core/logger.hpp"
-#include "table/fib.hpp"
-#include "fw/forwarder.hpp"
-#include "mgmt/internal-face.hpp"
-#include "mgmt/app-face.hpp"
-
-#include <ndn-cxx/encoding/tlv.hpp>
-
-namespace nfd {
-
-NFD_LOG_INIT("FibManager");
-
-const Name FibManager::COMMAND_PREFIX = "/localhost/nfd/fib";
-
-const size_t FibManager::COMMAND_UNSIGNED_NCOMPS =
-  FibManager::COMMAND_PREFIX.size() +
-  1 + // verb
-  1;  // verb parameters
-
-const size_t FibManager::COMMAND_SIGNED_NCOMPS =
-  FibManager::COMMAND_UNSIGNED_NCOMPS +
-  4; // (timestamp, nonce, signed info tlv, signature tlv)
-
-const FibManager::SignedVerbAndProcessor FibManager::SIGNED_COMMAND_VERBS[] =
-  {
-
-    SignedVerbAndProcessor(
-                           Name::Component("add-nexthop"),
-                           &FibManager::addNextHop
-                           ),
-
-    SignedVerbAndProcessor(
-                           Name::Component("remove-nexthop"),
-                           &FibManager::removeNextHop
-                           ),
-
-  };
-
-const FibManager::UnsignedVerbAndProcessor FibManager::UNSIGNED_COMMAND_VERBS[] =
-  {
-    UnsignedVerbAndProcessor(
-                             Name::Component("list"),
-                             &FibManager::listEntries
-                             ),
-  };
-
-const Name FibManager::LIST_COMMAND_PREFIX("/localhost/nfd/fib/list");
-const size_t FibManager::LIST_COMMAND_NCOMPS = LIST_COMMAND_PREFIX.size();
-
-
-FibManager::FibManager(Fib& fib,
-                       function<shared_ptr<Face>(FaceId)> getFace,
-                       shared_ptr<InternalFace> face,
-                       ndn::KeyChain& keyChain)
-  : ManagerBase(face, FIB_PRIVILEGE, keyChain)
-  , m_managedFib(fib)
-  , m_getFace(getFace)
-  , m_fibEnumerationPublisher(fib, *face, LIST_COMMAND_PREFIX, keyChain)
-  , m_signedVerbDispatch(SIGNED_COMMAND_VERBS,
-                         SIGNED_COMMAND_VERBS +
-                         (sizeof(SIGNED_COMMAND_VERBS) / sizeof(SignedVerbAndProcessor)))
-  , m_unsignedVerbDispatch(UNSIGNED_COMMAND_VERBS,
-                           UNSIGNED_COMMAND_VERBS +
-                           (sizeof(UNSIGNED_COMMAND_VERBS) / sizeof(UnsignedVerbAndProcessor)))
-{
-  face->setInterestFilter("/localhost/nfd/fib",
-                          bind(&FibManager::onFibRequest, this, _2));
-}
-
-FibManager::~FibManager()
-{
-
-}
-
-void
-FibManager::onFibRequest(const Interest& request)
-{
-  const Name& command = request.getName();
-  const size_t commandNComps = command.size();
-
-  if (commandNComps <= COMMAND_PREFIX.size())
-    {
-      // command is too short to have a verb
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-      return;
-    }
-
-  const Name::Component& verb = command.at(COMMAND_PREFIX.size());
-
-  const auto unsignedVerbProcessor = m_unsignedVerbDispatch.find(verb);
-  if (unsignedVerbProcessor != m_unsignedVerbDispatch.end())
-    {
-      NFD_LOG_DEBUG("command result: processing verb: " << verb);
-      (unsignedVerbProcessor->second)(this, request);
-    }
-  else if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
-           commandNComps < COMMAND_SIGNED_NCOMPS)
-    {
-      NFD_LOG_DEBUG("command result: unsigned verb: " << command);
-      sendResponse(command, 401, "Signature required");
-    }
-  else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
-           !COMMAND_PREFIX.isPrefixOf(command))
-    {
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-    }
-  else
-    {
-      validate(request,
-               bind(&FibManager::onValidatedFibRequest, this, _1),
-               bind(&ManagerBase::onCommandValidationFailed, this, _1, _2));
-    }
-}
-
-void
-FibManager::onValidatedFibRequest(const shared_ptr<const Interest>& request)
-{
-  const Name& command = request->getName();
-  const Name::Component& verb = command[COMMAND_PREFIX.size()];
-  const Name::Component& parameterComponent = command[COMMAND_PREFIX.size() + 1];
-
-  SignedVerbDispatchTable::const_iterator verbProcessor = m_signedVerbDispatch.find(verb);
-  if (verbProcessor != m_signedVerbDispatch.end())
-    {
-      ControlParameters parameters;
-      if (!extractParameters(parameterComponent, parameters))
-        {
-          NFD_LOG_DEBUG("command result: malformed verb: " << verb);
-          sendResponse(command, 400, "Malformed command");
-          return;
-        }
-
-      bool isSelfRegistration = (!parameters.hasFaceId() || parameters.getFaceId() == 0);
-      if (isSelfRegistration)
-        {
-          parameters.setFaceId(request->getIncomingFaceId());
-        }
-
-      NFD_LOG_DEBUG("command result: processing verb: " << verb);
-      ControlResponse response;
-      (verbProcessor->second)(this, parameters, response);
-      sendResponse(command, response);
-    }
-  else
-    {
-      NFD_LOG_DEBUG("command result: unsupported verb: " << verb);
-      sendResponse(command, 501, "Unsupported command");
-    }
-}
-
-void
-FibManager::addNextHop(ControlParameters& parameters,
-                       ControlResponse& response)
-{
-  ndn::nfd::FibAddNextHopCommand command;
-
-  if (!validateParameters(command, parameters))
-    {
-      NFD_LOG_DEBUG("add-nexthop result: FAIL reason: malformed");
-      setResponse(response, 400, "Malformed command");
-      return;
-    }
-
-  const Name& prefix = parameters.getName();
-  FaceId faceId = parameters.getFaceId();
-  uint64_t cost = parameters.getCost();
-
-  NFD_LOG_TRACE("add-nexthop prefix: " << prefix
-                << " faceid: " << faceId
-                << " cost: " << cost);
-
-  shared_ptr<Face> nextHopFace = m_getFace(faceId);
-  if (static_cast<bool>(nextHopFace))
-    {
-      shared_ptr<fib::Entry> entry = m_managedFib.insert(prefix).first;
-
-      entry->addNextHop(nextHopFace, cost);
-
-      NFD_LOG_DEBUG("add-nexthop result: OK"
-                    << " prefix:" << prefix
-                    << " faceid: " << faceId
-                    << " cost: " << cost);
-
-      setResponse(response, 200, "Success", parameters.wireEncode());
-    }
-  else
-    {
-      NFD_LOG_DEBUG("add-nexthop result: FAIL reason: unknown-faceid: " << faceId);
-      setResponse(response, 410, "Face not found");
-    }
-}
-
-void
-FibManager::removeNextHop(ControlParameters& parameters,
-                          ControlResponse& response)
-{
-  ndn::nfd::FibRemoveNextHopCommand command;
-  if (!validateParameters(command, parameters))
-    {
-      NFD_LOG_DEBUG("remove-nexthop result: FAIL reason: malformed");
-      setResponse(response, 400, "Malformed command");
-      return;
-    }
-
-  NFD_LOG_TRACE("remove-nexthop prefix: " << parameters.getName()
-                << " faceid: " << parameters.getFaceId());
-
-  shared_ptr<Face> faceToRemove = m_getFace(parameters.getFaceId());
-  if (static_cast<bool>(faceToRemove))
-    {
-      shared_ptr<fib::Entry> entry = m_managedFib.findExactMatch(parameters.getName());
-      if (static_cast<bool>(entry))
-        {
-          entry->removeNextHop(faceToRemove);
-          NFD_LOG_DEBUG("remove-nexthop result: OK prefix: " << parameters.getName()
-                        << " faceid: " << parameters.getFaceId());
-
-          if (!entry->hasNextHops())
-            {
-              m_managedFib.erase(*entry);
-            }
-        }
-      else
-        {
-          NFD_LOG_DEBUG("remove-nexthop result: OK, but entry for face id "
-                        << parameters.getFaceId() << " not found");
-        }
-    }
-  else
-    {
-      NFD_LOG_DEBUG("remove-nexthop result: OK, but face id "
-                    << parameters.getFaceId() << " not found");
-    }
-
-  setResponse(response, 200, "Success", parameters.wireEncode());
-}
-
-void
-FibManager::listEntries(const Interest& request)
-{
-  const Name& command = request.getName();
-  const size_t commandNComps = command.size();
-
-  if (commandNComps < LIST_COMMAND_NCOMPS ||
-      !LIST_COMMAND_PREFIX.isPrefixOf(command))
-    {
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-      return;
-    }
-
-  m_fibEnumerationPublisher.publish();
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/mgmt/fib-manager.hpp b/NFD/daemon/mgmt/fib-manager.hpp
deleted file mode 100644
index c8c21ea..0000000
--- a/NFD/daemon/mgmt/fib-manager.hpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_MGMT_FIB_MANAGER_HPP
-#define NFD_DAEMON_MGMT_FIB_MANAGER_HPP
-
-#include "common.hpp"
-#include "mgmt/manager-base.hpp"
-#include "mgmt/fib-enumeration-publisher.hpp"
-
-namespace nfd {
-
-class Face;
-class Forwarder;
-class Fib;
-
-const std::string FIB_PRIVILEGE = "fib"; // config file privilege name
-
-class FibManager : public ManagerBase
-{
-public:
-
-  FibManager(Fib& fib,
-             function<shared_ptr<Face>(FaceId)> getFace,
-             shared_ptr<InternalFace> face,
-             ndn::KeyChain& keyChain);
-
-  virtual
-  ~FibManager();
-
-  void
-  onFibRequest(const Interest& request);
-
-private:
-
-  void
-  onValidatedFibRequest(const shared_ptr<const Interest>& request);
-
-  void
-  addNextHop(ControlParameters& parameters,
-             ControlResponse& response);
-
-  void
-  removeNextHop(ControlParameters& parameters,
-                ControlResponse& response);
-
-  void
-  listEntries(const Interest& request);
-
-private:
-
-  Fib& m_managedFib;
-  function<shared_ptr<Face>(FaceId)> m_getFace;
-  FibEnumerationPublisher m_fibEnumerationPublisher;
-
-  typedef function<void(FibManager*,
-                        ControlParameters&,
-                        ControlResponse&)> SignedVerbProcessor;
-
-  typedef std::map<Name::Component, SignedVerbProcessor> SignedVerbDispatchTable;
-
-  typedef std::pair<Name::Component, SignedVerbProcessor> SignedVerbAndProcessor;
-
-  typedef function<void(FibManager*, const Interest&)> UnsignedVerbProcessor;
-
-  typedef std::map<Name::Component, UnsignedVerbProcessor> UnsignedVerbDispatchTable;
-  typedef std::pair<Name::Component, UnsignedVerbProcessor> UnsignedVerbAndProcessor;
-
-
-  const SignedVerbDispatchTable m_signedVerbDispatch;
-  const UnsignedVerbDispatchTable m_unsignedVerbDispatch;
-
-  static const Name COMMAND_PREFIX; // /localhost/nfd/fib
-
-  // number of components in an invalid, but not malformed, unsigned command.
-  // (/localhost/nfd/fib + verb + parameters) = 5
-  static const size_t COMMAND_UNSIGNED_NCOMPS;
-
-  // number of components in a valid signed Interest.
-  // UNSIGNED_NCOMPS + 4 command Interest components = 9
-  static const size_t COMMAND_SIGNED_NCOMPS;
-
-  static const SignedVerbAndProcessor SIGNED_COMMAND_VERBS[];
-  static const UnsignedVerbAndProcessor UNSIGNED_COMMAND_VERBS[];
-
-  static const Name LIST_COMMAND_PREFIX;
-  static const size_t LIST_COMMAND_NCOMPS;
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_FIB_MANAGER_HPP
diff --git a/NFD/daemon/mgmt/general-config-section.cpp b/NFD/daemon/mgmt/general-config-section.cpp
deleted file mode 100644
index 02f45e8..0000000
--- a/NFD/daemon/mgmt/general-config-section.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "general-config-section.hpp"
-
-#include "common.hpp"
-#include "core/logger.hpp"
-#include "core/privilege-helper.hpp"
-#include "core/config-file.hpp"
-
-namespace nfd {
-
-namespace general {
-
-NFD_LOG_INIT("GeneralConfigSection");
-
-static void
-onConfig(const ConfigSection& configSection,
-         bool isDryRun,
-         const std::string& filename)
-{
-  // general
-  // {
-  //    ; user "ndn-user"
-  //    ; group "ndn-user"
-  // }
-
-  std::string user;
-  std::string group;
-
-  for (ConfigSection::const_iterator i = configSection.begin();
-       i != configSection.end();
-       ++i)
-    {
-      if (i->first == "user")
-        {
-          try
-            {
-              user = i->second.get_value<std::string>("user");
-
-              if (user.empty())
-                {
-                  throw ConfigFile::Error("Invalid value for \"user\""
-                                          " in \"general\" section");
-                }
-            }
-          catch (const boost::property_tree::ptree_error& error)
-            {
-              throw ConfigFile::Error("Invalid value for \"user\""
-                                      " in \"general\" section");
-            }
-        }
-      else if (i->first == "group")
-        {
-          try
-            {
-              group = i->second.get_value<std::string>("group");
-
-              if (group.empty())
-                {
-                  throw ConfigFile::Error("Invalid value for \"group\""
-                                          " in \"general\" section");
-                }
-            }
-          catch (const boost::property_tree::ptree_error& error)
-            {
-              throw ConfigFile::Error("Invalid value for \"group\""
-                                      " in \"general\" section");
-            }
-        }
-    }
-  NFD_LOG_TRACE("using user \"" << user << "\" group \"" << group << "\"");
-
-  PrivilegeHelper::initialize(user, group);
-}
-
-void
-setConfigFile(ConfigFile& configFile)
-{
-  configFile.addSectionHandler("general", &onConfig);
-}
-
-} // namespace general
-
-} // namespace nfd
diff --git a/NFD/daemon/mgmt/general-config-section.hpp b/NFD/daemon/mgmt/general-config-section.hpp
deleted file mode 100644
index 6ce5473..0000000
--- a/NFD/daemon/mgmt/general-config-section.hpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#ifndef NFD_MGMT_GENERAL_CONFIG_SECTION_HPP
-#define NFD_MGMT_GENERAL_CONFIG_SECTION_HPP
-
-namespace nfd {
-
-class ConfigFile;
-
-namespace general {
-
-void
-setConfigFile(ConfigFile& configFile);
-
-} // namespace general
-
-} // namespace nfd
-
-#endif // NFD_MGMT_GENERAL_CONFIG_SECTION_HPP
diff --git a/NFD/daemon/mgmt/internal-face.cpp b/NFD/daemon/mgmt/internal-face.cpp
deleted file mode 100644
index f7ce65b..0000000
--- a/NFD/daemon/mgmt/internal-face.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "internal-face.hpp"
-#include "core/logger.hpp"
-#include "core/scheduler.hpp"
-
-namespace nfd {
-
-NFD_LOG_INIT("InternalFace");
-
-InternalFace::InternalFace()
-  : Face(FaceUri("internal://"), FaceUri("internal://"), true)
-{
-}
-
-void
-InternalFace::sendInterest(const Interest& interest)
-{
-  onSendInterest(interest);
-
-  // Invoke .processInterest a bit later,
-  // to avoid potential problems in forwarding pipelines.
-  scheduler::schedule(time::seconds(0),
-                      bind(&InternalFace::processInterest, this, interest.shared_from_this()));
-}
-
-void
-InternalFace::processInterest(const shared_ptr<const Interest>& interest)
-{
-  if (m_interestFilters.size() == 0)
-    {
-      NFD_LOG_DEBUG("no Interest filters to match against");
-      return;
-    }
-
-  const Name& interestName(interest->getName());
-  NFD_LOG_DEBUG("received Interest: " << interestName);
-
-  std::map<Name, OnInterest>::const_iterator filter =
-    m_interestFilters.lower_bound(interestName);
-
-  // lower_bound gives us the first Name that is
-  // an exact match OR ordered after interestName.
-  //
-  // If we reach the end of the map, then we need
-  // only check if the before-end element is a match.
-  //
-  // If we match an element, then the current
-  // position or the previous element are potential
-  // matches.
-  //
-  // If we hit begin, the element is either an exact
-  // match or there is no matching prefix in the map.
-
-
-  if (filter == m_interestFilters.end() && filter != m_interestFilters.begin())
-    {
-      // We hit the end, check if the previous element
-      // is a match
-      --filter;
-      if (filter->first.isPrefixOf(interestName))
-        {
-          NFD_LOG_DEBUG("found Interest filter for " << filter->first << " (before end match)");
-          filter->second(interestName, *interest);
-        }
-      else
-        {
-          NFD_LOG_DEBUG("no Interest filter found for " << interestName << " (before end)");
-        }
-    }
-  else if (filter->first == interestName)
-    {
-      NFD_LOG_DEBUG("found Interest filter for " << filter->first << " (exact match)");
-      filter->second(interestName, *interest);
-    }
-  else if (filter != m_interestFilters.begin())
-    {
-      // the element we found is canonically
-      // ordered after interestName.
-      // Check the previous element.
-      --filter;
-      if (filter->first.isPrefixOf(interestName))
-        {
-          NFD_LOG_DEBUG("found Interest filter for " << filter->first << " (previous match)");
-          filter->second(interestName, *interest);
-        }
-      else
-        {
-          NFD_LOG_DEBUG("no Interest filter found for " << interestName << " (previous)");
-        }
-    }
-  else
-    {
-      NFD_LOG_DEBUG("no Interest filter found for " << interestName << " (begin)");
-    }
-  //Drop Interest
-}
-
-void
-InternalFace::sendData(const Data& data)
-{
-  onSendData(data);
-}
-
-void
-InternalFace::close()
-{
-  throw Error("Internal face cannot be closed");
-}
-
-void
-InternalFace::setInterestFilter(const Name& filter,
-                                OnInterest onInterest)
-{
-  NFD_LOG_INFO("registering callback for " << filter);
-  m_interestFilters[filter] = onInterest;
-}
-
-void
-InternalFace::put(const Data& data)
-{
-  onReceiveData(data);
-}
-
-InternalFace::~InternalFace()
-{
-
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/mgmt/internal-face.hpp b/NFD/daemon/mgmt/internal-face.hpp
deleted file mode 100644
index c35676f..0000000
--- a/NFD/daemon/mgmt/internal-face.hpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_MGMT_INTERNAL_FACE_HPP
-#define NFD_DAEMON_MGMT_INTERNAL_FACE_HPP
-
-#include "face/face.hpp"
-#include "app-face.hpp"
-
-#include "command-validator.hpp"
-
-namespace nfd {
-
-class InternalFace : public Face, public AppFace
-{
-public:
-  /**
-   * \brief InternalFace-related error
-   */
-  class Error : public Face::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : Face::Error(what)
-    {
-    }
-  };
-
-  InternalFace();
-
-  CommandValidator&
-  getValidator();
-
-  virtual
-  ~InternalFace();
-
-  // Overridden Face methods for forwarder
-
-  virtual void
-  sendInterest(const Interest& interest);
-
-  virtual void
-  sendData(const Data& data);
-
-  virtual void
-  close();
-
-  // Methods implementing AppFace interface. Do not invoke from forwarder.
-
-  virtual void
-  setInterestFilter(const Name& filter,
-                    OnInterest onInterest);
-
-  virtual void
-  put(const Data& data);
-
-private:
-  void
-  processInterest(const shared_ptr<const Interest>& interest);
-
-private:
-  std::map<Name, OnInterest> m_interestFilters;
-  CommandValidator m_validator;
-};
-
-inline CommandValidator&
-InternalFace::getValidator()
-{
-  return m_validator;
-}
-
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_INTERNAL_FACE_HPP
diff --git a/NFD/daemon/mgmt/manager-base.cpp b/NFD/daemon/mgmt/manager-base.cpp
deleted file mode 100644
index cf75d04..0000000
--- a/NFD/daemon/mgmt/manager-base.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "manager-base.hpp"
-#include "core/logger.hpp"
-
-namespace nfd {
-
-NFD_LOG_INIT("ManagerBase");
-
-ManagerBase::ManagerBase(shared_ptr<InternalFace> face, const std::string& privilege,
-                         ndn::KeyChain& keyChain)
-  : m_face(face)
-  , m_keyChain(keyChain)
-{
-  face->getValidator().addSupportedPrivilege(privilege);
-}
-
-ManagerBase::~ManagerBase()
-{
-
-}
-
-bool
-ManagerBase::extractParameters(const Name::Component& parameterComponent,
-                               ControlParameters& extractedParameters)
-{
-  try
-    {
-      Block rawParameters = parameterComponent.blockFromValue();
-      extractedParameters.wireDecode(rawParameters);
-    }
-  catch (const tlv::Error&)
-    {
-      return false;
-    }
-
-  NFD_LOG_DEBUG("Parameters parsed OK");
-  return true;
-}
-
-void
-ManagerBase::sendResponse(const Name& name,
-                          uint32_t code,
-                          const std::string& text)
-{
-  ControlResponse response(code, text);
-  sendResponse(name, response);
-}
-
-void
-ManagerBase::sendResponse(const Name& name,
-                          uint32_t code,
-                          const std::string& text,
-                          const Block& body)
-{
-  ControlResponse response(code, text);
-  response.setBody(body);
-  sendResponse(name, response);
-}
-
-void
-ManagerBase::sendResponse(const Name& name,
-                          const ControlResponse& response)
-{
-  NFD_LOG_DEBUG("responding"
-                << " name: " << name
-                << " code: " << response.getCode()
-                << " text: " << response.getText());
-
-  const Block& encodedControl = response.wireEncode();
-
-  shared_ptr<Data> responseData(make_shared<Data>(name));
-  responseData->setContent(encodedControl);
-
-  m_keyChain.sign(*responseData);
-  m_face->put(*responseData);
-}
-
-void
-ManagerBase::sendNack(const Name& name)
-{
-  NFD_LOG_DEBUG("responding NACK to " << name);
-
-  ndn::MetaInfo meta;
-  meta.setType(tlv::ContentType_Nack);
-
-  shared_ptr<Data> responseData(make_shared<Data>(name));
-  responseData->setMetaInfo(meta);
-
-  m_keyChain.sign(*responseData);
-  m_face->put(*responseData);
-}
-
-bool
-ManagerBase::validateParameters(const ControlCommand& command,
-                                ControlParameters& parameters)
-{
-  try
-    {
-      command.validateRequest(parameters);
-    }
-  catch (const ControlCommand::ArgumentError& error)
-    {
-      return false;
-    }
-
-  command.applyDefaultsToRequest(parameters);
-
-  return true;
-}
-
-void
-ManagerBase::onCommandValidationFailed(const shared_ptr<const Interest>& command,
-                                       const std::string& error)
-{
-  NFD_LOG_DEBUG("command result: unauthorized command: " << *command << " (" << error << ")");
-  sendResponse(command->getName(), 403, "Unauthorized command");
-}
-
-
-} // namespace nfd
diff --git a/NFD/daemon/mgmt/manager-base.hpp b/NFD/daemon/mgmt/manager-base.hpp
deleted file mode 100644
index 1611615..0000000
--- a/NFD/daemon/mgmt/manager-base.hpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_MGMT_MANAGER_BASE_HPP
-#define NFD_DAEMON_MGMT_MANAGER_BASE_HPP
-
-#include "common.hpp"
-
-#include "mgmt/command-validator.hpp"
-#include "mgmt/internal-face.hpp"
-
-#include <ndn-cxx/management/nfd-control-command.hpp>
-#include <ndn-cxx/management/nfd-control-response.hpp>
-#include <ndn-cxx/management/nfd-control-parameters.hpp>
-
-namespace nfd {
-
-using ndn::nfd::ControlCommand;
-using ndn::nfd::ControlResponse;
-using ndn::nfd::ControlParameters;
-
-class InternalFace;
-
-class ManagerBase
-{
-public:
-
-  struct Error : public std::runtime_error
-  {
-    Error(const std::string& what) : std::runtime_error(what) {}
-  };
-
-  ManagerBase(shared_ptr<InternalFace> face,
-              const std::string& privilege,
-              ndn::KeyChain& keyChain);
-
-  virtual
-  ~ManagerBase();
-
-  void
-  onCommandValidationFailed(const shared_ptr<const Interest>& command,
-                            const std::string& error);
-
-protected:
-
-  static bool
-  extractParameters(const Name::Component& parameterComponent,
-                    ControlParameters& extractedParameters);
-
-  void
-  setResponse(ControlResponse& response,
-              uint32_t code,
-              const std::string& text);
-  void
-  setResponse(ControlResponse& response,
-              uint32_t code,
-              const std::string& text,
-              const Block& body);
-
-  void
-  sendResponse(const Name& name,
-               const ControlResponse& response);
-
-  void
-  sendResponse(const Name& name,
-               uint32_t code,
-               const std::string& text);
-
-  void
-  sendResponse(const Name& name,
-               uint32_t code,
-               const std::string& text,
-               const Block& body);
-
-  void
-  sendNack(const Name& name);
-
-  virtual bool
-  validateParameters(const ControlCommand& command,
-                     ControlParameters& parameters);
-
-PUBLIC_WITH_TESTS_ELSE_PROTECTED:
-  void
-  addInterestRule(const std::string& regex,
-                  const ndn::IdentityCertificate& certificate);
-
-  void
-  addInterestRule(const std::string& regex,
-                  const Name& keyName,
-                  const ndn::PublicKey& publicKey);
-
-  void
-  validate(const Interest& interest,
-           const ndn::OnInterestValidated& onValidated,
-           const ndn::OnInterestValidationFailed& onValidationFailed);
-
-protected:
-  shared_ptr<InternalFace> m_face;
-  ndn::KeyChain& m_keyChain;
-};
-
-inline void
-ManagerBase::setResponse(ControlResponse& response,
-                         uint32_t code,
-                         const std::string& text)
-{
-  response.setCode(code);
-  response.setText(text);
-}
-
-inline void
-ManagerBase::setResponse(ControlResponse& response,
-                         uint32_t code,
-                         const std::string& text,
-                         const Block& body)
-{
-  setResponse(response, code, text);
-  response.setBody(body);
-}
-
-inline void
-ManagerBase::addInterestRule(const std::string& regex,
-                             const ndn::IdentityCertificate& certificate)
-{
-  m_face->getValidator().addInterestRule(regex, certificate);
-}
-
-inline void
-ManagerBase::addInterestRule(const std::string& regex,
-                             const Name& keyName,
-                             const ndn::PublicKey& publicKey)
-{
-  m_face->getValidator().addInterestRule(regex, keyName, publicKey);
-}
-
-inline void
-ManagerBase::validate(const Interest& interest,
-                      const ndn::OnInterestValidated& onValidated,
-                      const ndn::OnInterestValidationFailed& onValidationFailed)
-{
-  m_face->getValidator().validate(interest, onValidated, onValidationFailed);
-}
-
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_MANAGER_BASE_HPP
diff --git a/NFD/daemon/mgmt/status-server.cpp b/NFD/daemon/mgmt/status-server.cpp
deleted file mode 100644
index c8ce5b4..0000000
--- a/NFD/daemon/mgmt/status-server.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "status-server.hpp"
-#include "fw/forwarder.hpp"
-#include "version.hpp"
-
-namespace nfd {
-
-const Name StatusServer::DATASET_PREFIX = "ndn:/localhost/nfd/status";
-const time::milliseconds StatusServer::RESPONSE_FRESHNESS = time::milliseconds(5000);
-
-StatusServer::StatusServer(shared_ptr<AppFace> face, Forwarder& forwarder, ndn::KeyChain& keyChain)
-  : m_face(face)
-  , m_forwarder(forwarder)
-  , m_startTimestamp(time::system_clock::now())
-  , m_keyChain(keyChain)
-{
-  m_face->setInterestFilter(DATASET_PREFIX, bind(&StatusServer::onInterest, this, _2));
-}
-
-void
-StatusServer::onInterest(const Interest& interest) const
-{
-  Name name(DATASET_PREFIX);
-  name.appendVersion();
-  name.appendSegment(0);
-
-  shared_ptr<Data> data = make_shared<Data>(name);
-  data->setFreshnessPeriod(RESPONSE_FRESHNESS);
-
-  shared_ptr<ndn::nfd::ForwarderStatus> status = this->collectStatus();
-  data->setContent(status->wireEncode());
-
-  m_keyChain.sign(*data);
-  m_face->put(*data);
-}
-
-shared_ptr<ndn::nfd::ForwarderStatus>
-StatusServer::collectStatus() const
-{
-  shared_ptr<ndn::nfd::ForwarderStatus> status = make_shared<ndn::nfd::ForwarderStatus>();
-
-  status->setNfdVersion(NFD_VERSION_BUILD_STRING);
-  status->setStartTimestamp(m_startTimestamp);
-  status->setCurrentTimestamp(time::system_clock::now());
-
-  status->setNNameTreeEntries(m_forwarder.getNameTree().size());
-  status->setNFibEntries(m_forwarder.getFib().size());
-  status->setNPitEntries(m_forwarder.getPit().size());
-  status->setNMeasurementsEntries(m_forwarder.getMeasurements().size());
-  status->setNCsEntries(m_forwarder.getCs().size());
-
-  m_forwarder.getCounters().copyTo(*status);
-
-  return status;
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/mgmt/status-server.hpp b/NFD/daemon/mgmt/status-server.hpp
deleted file mode 100644
index 16dbf8e..0000000
--- a/NFD/daemon/mgmt/status-server.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_MGMT_STATUS_SERVER_HPP
-#define NFD_DAEMON_MGMT_STATUS_SERVER_HPP
-
-#include "mgmt/app-face.hpp"
-#include <ndn-cxx/management/nfd-forwarder-status.hpp>
-
-namespace nfd {
-
-class Forwarder;
-
-class StatusServer : noncopyable
-{
-public:
-  StatusServer(shared_ptr<AppFace> face, Forwarder& forwarder, ndn::KeyChain& keyChain);
-
-private:
-  void
-  onInterest(const Interest& interest) const;
-
-  shared_ptr<ndn::nfd::ForwarderStatus>
-  collectStatus() const;
-
-private:
-  static const Name DATASET_PREFIX;
-  static const time::milliseconds RESPONSE_FRESHNESS;
-
-  shared_ptr<AppFace> m_face;
-  Forwarder& m_forwarder;
-  time::system_clock::TimePoint m_startTimestamp;
-  ndn::KeyChain& m_keyChain;
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_STATUS_SERVER_HPP
diff --git a/NFD/daemon/mgmt/strategy-choice-manager.cpp b/NFD/daemon/mgmt/strategy-choice-manager.cpp
deleted file mode 100644
index 4f2728c..0000000
--- a/NFD/daemon/mgmt/strategy-choice-manager.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "strategy-choice-manager.hpp"
-#include "table/strategy-choice.hpp"
-#include "core/logger.hpp"
-#include "mgmt/app-face.hpp"
-
-namespace nfd {
-
-NFD_LOG_INIT("StrategyChoiceManager");
-
-const Name StrategyChoiceManager::COMMAND_PREFIX = "/localhost/nfd/strategy-choice";
-
-const size_t StrategyChoiceManager::COMMAND_UNSIGNED_NCOMPS =
-  StrategyChoiceManager::COMMAND_PREFIX.size() +
-  1 + // verb
-  1;  // verb parameters
-
-const size_t StrategyChoiceManager::COMMAND_SIGNED_NCOMPS =
-  StrategyChoiceManager::COMMAND_UNSIGNED_NCOMPS +
-  4; // (timestamp, nonce, signed info tlv, signature tlv)
-
-const Name StrategyChoiceManager::LIST_DATASET_PREFIX("/localhost/nfd/strategy-choice/list");
-
-StrategyChoiceManager::StrategyChoiceManager(StrategyChoice& strategyChoice,
-                                             shared_ptr<InternalFace> face,
-                                             ndn::KeyChain& keyChain)
-  : ManagerBase(face, STRATEGY_CHOICE_PRIVILEGE, keyChain)
-  , m_strategyChoice(strategyChoice)
-  , m_listPublisher(strategyChoice, *m_face, LIST_DATASET_PREFIX, keyChain)
-{
-  face->setInterestFilter("/localhost/nfd/strategy-choice",
-                          bind(&StrategyChoiceManager::onStrategyChoiceRequest, this, _2));
-}
-
-StrategyChoiceManager::~StrategyChoiceManager()
-{
-
-}
-
-void
-StrategyChoiceManager::onStrategyChoiceRequest(const Interest& request)
-{
-  const Name& command = request.getName();
-  const size_t commandNComps = command.size();
-
-  if (command == LIST_DATASET_PREFIX)
-    {
-      listStrategies(request);
-      return;
-    }
-  else if (commandNComps <= COMMAND_PREFIX.size())
-    {
-      // command is too short to have a verb
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-      return;
-    }
-
-  if (COMMAND_UNSIGNED_NCOMPS <= commandNComps &&
-      commandNComps < COMMAND_SIGNED_NCOMPS)
-    {
-      NFD_LOG_DEBUG("command result: unsigned verb: " << command);
-      sendResponse(command, 401, "Signature required");
-
-      return;
-    }
-  else if (commandNComps < COMMAND_SIGNED_NCOMPS ||
-           !COMMAND_PREFIX.isPrefixOf(command))
-    {
-      NFD_LOG_DEBUG("command result: malformed");
-      sendResponse(command, 400, "Malformed command");
-      return;
-    }
-
-  validate(request,
-           bind(&StrategyChoiceManager::onValidatedStrategyChoiceRequest, this, _1),
-           bind(&ManagerBase::onCommandValidationFailed, this, _1, _2));
-}
-
-void
-StrategyChoiceManager::listStrategies(const Interest& request)
-{
-  m_listPublisher.publish();
-}
-
-void
-StrategyChoiceManager::onValidatedStrategyChoiceRequest(const shared_ptr<const Interest>& request)
-{
-  static const Name::Component VERB_SET("set");
-  static const Name::Component VERB_UNSET("unset");
-
-  const Name& command = request->getName();
-  const Name::Component& parameterComponent = command[COMMAND_PREFIX.size() + 1];
-
-  ControlParameters parameters;
-  if (!extractParameters(parameterComponent, parameters))
-    {
-      sendResponse(command, 400, "Malformed command");
-      return;
-    }
-
-  const Name::Component& verb = command.at(COMMAND_PREFIX.size());
-  ControlResponse response;
-  if (verb == VERB_SET)
-    {
-      setStrategy(parameters, response);
-    }
-  else if (verb == VERB_UNSET)
-    {
-      unsetStrategy(parameters, response);
-    }
-  else
-    {
-      NFD_LOG_DEBUG("command result: unsupported verb: " << verb);
-      setResponse(response, 501, "Unsupported command");
-    }
-
-  sendResponse(command, response);
-}
-
-void
-StrategyChoiceManager::setStrategy(ControlParameters& parameters,
-                                   ControlResponse& response)
-{
-  ndn::nfd::StrategyChoiceSetCommand command;
-
-  if (!validateParameters(command, parameters))
-    {
-      NFD_LOG_DEBUG("strategy-choice result: FAIL reason: malformed");
-      setResponse(response, 400, "Malformed command");
-      return;
-    }
-
-  const Name& prefix = parameters.getName();
-  const Name& selectedStrategy = parameters.getStrategy();
-
-  if (!m_strategyChoice.hasStrategy(selectedStrategy))
-    {
-      NFD_LOG_DEBUG("strategy-choice result: FAIL reason: unknown-strategy: "
-                    << parameters.getStrategy());
-      setResponse(response, 504, "Unsupported strategy");
-      return;
-    }
-
-  if (m_strategyChoice.insert(prefix, selectedStrategy))
-    {
-      NFD_LOG_DEBUG("strategy-choice result: SUCCESS");
-      auto currentStrategyChoice = m_strategyChoice.get(prefix);
-      BOOST_ASSERT(currentStrategyChoice.first);
-      parameters.setStrategy(currentStrategyChoice.second);
-      setResponse(response, 200, "Success", parameters.wireEncode());
-    }
-  else
-    {
-      NFD_LOG_DEBUG("strategy-choice result: FAIL reason: not-installed");
-      setResponse(response, 405, "Strategy not installed");
-    }
-}
-
-void
-StrategyChoiceManager::unsetStrategy(ControlParameters& parameters,
-                                     ControlResponse& response)
-{
-  ndn::nfd::StrategyChoiceUnsetCommand command;
-
-  if (!validateParameters(command, parameters))
-    {
-      static const Name ROOT_PREFIX;
-      if (parameters.hasName() && parameters.getName() == ROOT_PREFIX)
-        {
-          NFD_LOG_DEBUG("strategy-choice result: FAIL reason: unset-root");
-          setResponse(response, 403, "Cannot unset root prefix strategy");
-        }
-      else
-        {
-          NFD_LOG_DEBUG("strategy-choice result: FAIL reason: malformed");
-          setResponse(response, 400, "Malformed command");
-        }
-      return;
-    }
-
-  m_strategyChoice.erase(parameters.getName());
-
-  NFD_LOG_DEBUG("strategy-choice result: SUCCESS");
-  setResponse(response, 200, "Success", parameters.wireEncode());
-}
-
-
-
-} // namespace nfd
diff --git a/NFD/daemon/mgmt/strategy-choice-manager.hpp b/NFD/daemon/mgmt/strategy-choice-manager.hpp
deleted file mode 100644
index c2ccd53..0000000
--- a/NFD/daemon/mgmt/strategy-choice-manager.hpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_MGMT_STRATEGY_CHOICE_MANAGER_HPP
-#define NFD_DAEMON_MGMT_STRATEGY_CHOICE_MANAGER_HPP
-
-#include "mgmt/manager-base.hpp"
-#include "mgmt/strategy-choice-publisher.hpp"
-
-#include <ndn-cxx/management/nfd-control-parameters.hpp>
-
-namespace nfd {
-
-const std::string STRATEGY_CHOICE_PRIVILEGE = "strategy-choice";
-
-class StrategyChoice;
-
-class StrategyChoiceManager : public ManagerBase
-{
-public:
-  StrategyChoiceManager(StrategyChoice& strategyChoice,
-                        shared_ptr<InternalFace> face,
-                        ndn::KeyChain& keyChain);
-
-  virtual
-  ~StrategyChoiceManager();
-
-  void
-  onStrategyChoiceRequest(const Interest& request);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-
-  void
-  listStrategies(const Interest& request);
-
-  void
-  onValidatedStrategyChoiceRequest(const shared_ptr<const Interest>& request);
-
-  void
-  setStrategy(ControlParameters& parameters,
-              ControlResponse& response);
-
-  void
-  unsetStrategy(ControlParameters& parameters,
-                ControlResponse& response);
-
-private:
-
-  StrategyChoice& m_strategyChoice;
-
-  StrategyChoicePublisher m_listPublisher;
-
-  static const Name COMMAND_PREFIX; // /localhost/nfd/strategy-choice
-
-  // number of components in an invalid, but not malformed, unsigned command.
-  // (/localhost/nfd/strategy-choice + verb + parameters) = 5
-  static const size_t COMMAND_UNSIGNED_NCOMPS;
-
-  // number of components in a valid signed Interest.
-  // (see UNSIGNED_NCOMPS), 9 with signed Interest support.
-  static const size_t COMMAND_SIGNED_NCOMPS;
-
-  static const Name LIST_DATASET_PREFIX; // /localhost/nfd/strategy-choice/list
-
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_STRATEGY_CHOICE_MANAGER_HPP
diff --git a/NFD/daemon/mgmt/strategy-choice-publisher.cpp b/NFD/daemon/mgmt/strategy-choice-publisher.cpp
deleted file mode 100644
index 163ac3a..0000000
--- a/NFD/daemon/mgmt/strategy-choice-publisher.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "strategy-choice-publisher.hpp"
-#include "core/logger.hpp"
-#include "table/strategy-choice.hpp"
-
-#include <ndn-cxx/management/nfd-strategy-choice.hpp>
-
-namespace nfd {
-
-NFD_LOG_INIT("StrategyChoicePublisher");
-
-
-StrategyChoicePublisher::StrategyChoicePublisher(const StrategyChoice& strategyChoice,
-                                                 AppFace& face,
-                                                 const Name& prefix,
-                                                 ndn::KeyChain& keyChain)
-  : SegmentPublisher(face, prefix, keyChain)
-  , m_strategyChoice(strategyChoice)
-{
-
-}
-
-StrategyChoicePublisher::~StrategyChoicePublisher()
-{
-
-}
-
-size_t
-StrategyChoicePublisher::generate(ndn::EncodingBuffer& outBuffer)
-{
-  size_t totalLength = 0;
-
-  for (StrategyChoice::const_iterator i = m_strategyChoice.begin();
-       i != m_strategyChoice.end();
-       ++i)
-    {
-      ndn::nfd::StrategyChoice entry;
-
-      entry.setName(i->getPrefix())
-           .setStrategy(i->getStrategyName());
-
-      totalLength += entry.wireEncode(outBuffer);
-    }
-
-  return totalLength;
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/mgmt/strategy-choice-publisher.hpp b/NFD/daemon/mgmt/strategy-choice-publisher.hpp
deleted file mode 100644
index 8322b63..0000000
--- a/NFD/daemon/mgmt/strategy-choice-publisher.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#ifndef NFD_DAEMON_MGMT_STRATEGY_CHOICE_PUBLISHER_HPP
-#define NFD_DAEMON_MGMT_STRATEGY_CHOICE_PUBLISHER_HPP
-
-#include "core/segment-publisher.hpp"
-#include "mgmt/app-face.hpp"
-
-namespace nfd {
-
-class StrategyChoice;
-
-class StrategyChoicePublisher : public SegmentPublisher<AppFace>
-{
-public:
-  StrategyChoicePublisher(const StrategyChoice& strategyChoice,
-                          AppFace& face,
-                          const Name& prefix,
-                          ndn::KeyChain& keyChain);
-
-  virtual
-  ~StrategyChoicePublisher();
-
-protected:
-
-  virtual size_t
-  generate(ndn::EncodingBuffer& outBuffer);
-
-private:
-
-  const StrategyChoice& m_strategyChoice;
-
-};
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_STRATEGY_CHOICE_PUBLISHER_HPP
diff --git a/NFD/daemon/mgmt/tables-config-section.cpp b/NFD/daemon/mgmt/tables-config-section.cpp
deleted file mode 100644
index 861ed7f..0000000
--- a/NFD/daemon/mgmt/tables-config-section.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "tables-config-section.hpp"
-
-#include "common.hpp"
-#include "core/logger.hpp"
-#include "core/config-file.hpp"
-
-namespace nfd {
-
-NFD_LOG_INIT("TablesConfigSection");
-
-const size_t TablesConfigSection::DEFAULT_CS_MAX_PACKETS = 65536;
-
-TablesConfigSection::TablesConfigSection(Cs& cs,
-                                         Pit& pit,
-                                         Fib& fib,
-                                         StrategyChoice& strategyChoice,
-                                         Measurements& measurements)
-  : m_cs(cs)
-  // , m_pit(pit)
-  // , m_fib(fib)
-  , m_strategyChoice(strategyChoice)
-  // , m_measurements(measurements)
-  , m_areTablesConfigured(false)
-{
-
-}
-
-void
-TablesConfigSection::setConfigFile(ConfigFile& configFile)
-{
-  configFile.addSectionHandler("tables",
-                               bind(&TablesConfigSection::onConfig, this, _1, _2, _3));
-}
-
-
-void
-TablesConfigSection::ensureTablesAreConfigured()
-{
-  if (m_areTablesConfigured)
-    {
-      return;
-    }
-
-  NFD_LOG_INFO("Setting CS max packets to " << DEFAULT_CS_MAX_PACKETS);
-  m_cs.setLimit(DEFAULT_CS_MAX_PACKETS);
-
-  m_areTablesConfigured = true;
-}
-
-void
-TablesConfigSection::onConfig(const ConfigSection& configSection,
-                              bool isDryRun,
-                              const std::string& filename)
-{
-  // tables
-  // {
-  //    cs_max_packets 65536
-  //
-  //    strategy_choice
-  //    {
-  //       /               /localhost/nfd/strategy/best-route
-  //       /localhost      /localhost/nfd/strategy/broadcast
-  //       /localhost/nfd  /localhost/nfd/strategy/best-route
-  //       /ndn/broadcast  /localhost/nfd/strategy/broadcast
-  //    }
-  // }
-
-  size_t nCsMaxPackets = DEFAULT_CS_MAX_PACKETS;
-
-  boost::optional<const ConfigSection&> csMaxPacketsNode =
-    configSection.get_child_optional("cs_max_packets");
-
-  if (csMaxPacketsNode)
-    {
-      boost::optional<size_t> valCsMaxPackets =
-        configSection.get_optional<size_t>("cs_max_packets");
-
-      if (!valCsMaxPackets)
-        {
-          throw ConfigFile::Error("Invalid value for option \"cs_max_packets\""
-                                  " in \"tables\" section");
-        }
-
-      nCsMaxPackets = *valCsMaxPackets;
-    }
-
-  boost::optional<const ConfigSection&> strategyChoiceSection =
-    configSection.get_child_optional("strategy_choice");
-
-  if (strategyChoiceSection)
-    {
-      processSectionStrategyChoice(*strategyChoiceSection, isDryRun);
-    }
-
-  if (!isDryRun)
-    {
-      NFD_LOG_INFO("Setting CS max packets to " << nCsMaxPackets);
-
-      m_cs.setLimit(nCsMaxPackets);
-      m_areTablesConfigured = true;
-    }
-}
-
-void
-TablesConfigSection::processSectionStrategyChoice(const ConfigSection& configSection,
-                                                  bool isDryRun)
-{
-  // strategy_choice
-  // {
-  //   /               /localhost/nfd/strategy/best-route
-  //   /localhost      /localhost/nfd/strategy/broadcast
-  //   /localhost/nfd  /localhost/nfd/strategy/best-route
-  //   /ndn/broadcast  /localhost/nfd/strategy/broadcast
-  // }
-
-  std::map<Name, Name> choices;
-
-  for (const auto& prefixAndStrategy : configSection)
-    {
-      const Name prefix(prefixAndStrategy.first);
-      if (choices.find(prefix) != choices.end())
-        {
-          throw ConfigFile::Error("Duplicate strategy choice for prefix \"" +
-                                  prefix.toUri() + "\" in \"strategy_choice\" section");
-        }
-
-      const std::string strategyString(prefixAndStrategy.second.get_value<std::string>());
-      if (strategyString.empty())
-        {
-          throw ConfigFile::Error("Invalid strategy choice \"\" for prefix \"" +
-                                  prefix.toUri() + "\" in \"strategy_choice\" section");
-        }
-
-      const Name strategyName(strategyString);
-      if (!m_strategyChoice.hasStrategy(strategyName))
-        {
-          throw ConfigFile::Error("Invalid strategy choice \"" +
-                                  strategyName.toUri() + "\" for prefix \"" +
-                                  prefix.toUri() + "\" in \"strategy_choice\" section");
-        }
-
-      choices[prefix] = strategyName;
-    }
-
-
-  for (const auto& prefixAndStrategy : choices)
-    {
-      if (!isDryRun && !m_strategyChoice.insert(prefixAndStrategy.first, prefixAndStrategy.second))
-        {
-          throw ConfigFile::Error("Failed to set strategy \"" +
-                                  prefixAndStrategy.second.toUri() + "\" for prefix \"" +
-                                  prefixAndStrategy.first.toUri() + "\" in \"strategy_choicev\"");
-        }
-    }
-}
-
-
-
-} // namespace nfd
diff --git a/NFD/daemon/mgmt/tables-config-section.hpp b/NFD/daemon/mgmt/tables-config-section.hpp
deleted file mode 100644
index 3f132f7..0000000
--- a/NFD/daemon/mgmt/tables-config-section.hpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_MGMT_TABLES_CONFIG_SECTION_HPP
-#define NFD_MGMT_TABLES_CONFIG_SECTION_HPP
-
-#include "table/fib.hpp"
-#include "table/pit.hpp"
-#include "table/cs.hpp"
-#include "table/measurements.hpp"
-#include "table/strategy-choice.hpp"
-
-#include "core/config-file.hpp"
-
-namespace nfd {
-
-class TablesConfigSection
-{
-public:
-  TablesConfigSection(Cs& cs,
-                      Pit& pit,
-                      Fib& fib,
-                      StrategyChoice& strategyChoice,
-                      Measurements& measurements);
-
-  void
-  setConfigFile(ConfigFile& configFile);
-
-  void
-  ensureTablesAreConfigured();
-
-private:
-
-  void
-  onConfig(const ConfigSection& configSection,
-           bool isDryRun,
-           const std::string& filename);
-
-  void
-  processSectionStrategyChoice(const ConfigSection& configSection,
-                               bool isDryRun);
-
-private:
-  Cs& m_cs;
-  // Pit& m_pit;
-  // Fib& m_fib;
-  StrategyChoice& m_strategyChoice;
-  // Measurements& m_measurements;
-
-  bool m_areTablesConfigured;
-
-private:
-
-  static const size_t DEFAULT_CS_MAX_PACKETS;
-};
-
-} // namespace nfd
-
-#endif // NFD_MGMT_TABLES_CONFIG_SECTION_HPP
diff --git a/NFD/daemon/table/cs-entry.cpp b/NFD/daemon/table/cs-entry.cpp
deleted file mode 100644
index 0bcdefc..0000000
--- a/NFD/daemon/table/cs-entry.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * \author Ilya Moiseenko <http://ilyamoiseenko.com/>
- * \author Junxiao Shi <http://www.cs.arizona.edu/people/shijunxiao/>
- * \author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#include "cs-entry.hpp"
-#include "core/logger.hpp"
-
-namespace nfd {
-namespace cs {
-
-NFD_LOG_INIT("CsEntry");
-
-Entry::Entry()
-  : m_isUnsolicited(false)
-{
-}
-
-void
-Entry::setData(const Data& data, bool isUnsolicited)
-{
-  m_isUnsolicited = isUnsolicited;
-  m_dataPacket = data.shared_from_this();
-
-  updateStaleTime();
-}
-
-void
-Entry::updateStaleTime()
-{
-  m_staleAt = time::steady_clock::now() + m_dataPacket->getFreshnessPeriod();
-}
-
-bool
-Entry::isStale() const
-{
-  return m_staleAt < time::steady_clock::now();
-}
-
-void
-Entry::reset()
-{
-  m_staleAt = time::steady_clock::TimePoint();
-  m_dataPacket.reset();
-  m_isUnsolicited = false;
-}
-
-} // namespace cs
-} // namespace nfd
diff --git a/NFD/daemon/table/cs-entry.hpp b/NFD/daemon/table/cs-entry.hpp
deleted file mode 100644
index e922ffd..0000000
--- a/NFD/daemon/table/cs-entry.hpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * \author Ilya Moiseenko <http://ilyamoiseenko.com/>
- * \author Junxiao Shi <http://www.cs.arizona.edu/people/shijunxiao/>
- * \author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#ifndef NFD_DAEMON_TABLE_CS_ENTRY_HPP
-#define NFD_DAEMON_TABLE_CS_ENTRY_HPP
-
-#include "common.hpp"
-
-namespace nfd {
-namespace cs {
-
-class Entry;
-
-/** \brief represents a base class for CS entry
- */
-class Entry : noncopyable
-{
-public:
-  Entry();
-
-  /** \brief returns the name of the Data packet stored in the CS entry
-   *  \return{ NDN name }
-   */
-  const Name&
-  getName() const;
-
-  /** \brief returns the full name (including implicit digest) of the Data packet stored
-   *         in the CS entry
-   *  \return{ NDN name }
-   */
-  const Name&
-  getFullName() const;
-
-  /** \brief Data packet is unsolicited if this particular NDN node
-   *  did not receive an Interest packet for it, or the Interest packet has already expired
-   *  \return{ True if the Data packet is unsolicited; otherwise False  }
-   */
-  bool
-  isUnsolicited() const;
-
-  /** \brief returns the Data packet stored in the CS entry
-   */
-  const Data&
-  getData() const;
-
-  /** \brief changes the content of CS entry and recomputes digest
-   */
-  void
-  setData(const Data& data, bool isUnsolicited);
-
-  /** \brief returns the absolute time when Data becomes expired
-   *  \return{ Time (resolution up to time::milliseconds) }
-   */
-  const time::steady_clock::TimePoint&
-  getStaleTime() const;
-
-  /** \brief refreshes the time when Data becomes expired
-   *  according to the current absolute time.
-   */
-  void
-  updateStaleTime();
-
-  /** \brief checks if the stored Data is stale
-   */
-  bool
-  isStale() const;
-
-  /** \brief clears CS entry
-   *  After reset, *this == Entry()
-   */
-  void
-  reset();
-
-private:
-  time::steady_clock::TimePoint m_staleAt;
-  shared_ptr<const Data> m_dataPacket;
-
-  bool m_isUnsolicited;
-};
-
-inline const Name&
-Entry::getName() const
-{
-  BOOST_ASSERT(m_dataPacket != nullptr);
-  return m_dataPacket->getName();
-}
-
-inline const Name&
-Entry::getFullName() const
-{
-  BOOST_ASSERT(m_dataPacket != nullptr);
-  return m_dataPacket->getFullName();
-}
-
-inline const Data&
-Entry::getData() const
-{
-  BOOST_ASSERT(m_dataPacket != nullptr);
-  return *m_dataPacket;
-}
-
-inline bool
-Entry::isUnsolicited() const
-{
-  return m_isUnsolicited;
-}
-
-inline const time::steady_clock::TimePoint&
-Entry::getStaleTime() const
-{
-  return m_staleAt;
-}
-
-} // namespace cs
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_CS_ENTRY_HPP
diff --git a/NFD/daemon/table/cs-skip-list-entry.cpp b/NFD/daemon/table/cs-skip-list-entry.cpp
deleted file mode 100644
index a05f0d1..0000000
--- a/NFD/daemon/table/cs-skip-list-entry.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * \author Ilya Moiseenko <http://ilyamoiseenko.com/>
- * \author Junxiao Shi <http://www.cs.arizona.edu/people/shijunxiao/>
- * \author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#include "cs-skip-list-entry.hpp"
-#include "core/logger.hpp"
-
-namespace nfd {
-namespace cs {
-namespace skip_list {
-
-NFD_LOG_INIT("CsSkipListEntry");
-
-void
-Entry::release()
-{
-  BOOST_ASSERT(m_layerIterators.empty());
-
-  reset();
-}
-
-void
-Entry::setIterator(int layer, const Entry::LayerIterators::mapped_type& layerIterator)
-{
-  m_layerIterators[layer] = layerIterator;
-}
-
-void
-Entry::removeIterator(int layer)
-{
-  m_layerIterators.erase(layer);
-}
-
-void
-Entry::printIterators() const
-{
-  for (LayerIterators::const_iterator it = m_layerIterators.begin();
-       it != m_layerIterators.end();
-       ++it)
-    {
-      NFD_LOG_TRACE("[" << it->first << "]" << " " << &(*it->second));
-    }
-}
-
-} // namespace skip_list
-} // namespace cs
-} // namespace nfd
diff --git a/NFD/daemon/table/cs-skip-list-entry.hpp b/NFD/daemon/table/cs-skip-list-entry.hpp
deleted file mode 100644
index 1328cc0..0000000
--- a/NFD/daemon/table/cs-skip-list-entry.hpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * \author Ilya Moiseenko <http://ilyamoiseenko.com/>
- * \author Junxiao Shi <http://www.cs.arizona.edu/people/shijunxiao/>
- * \author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#ifndef NFD_DAEMON_TABLE_CS_SKIP_LIST_ENTRY_HPP
-#define NFD_DAEMON_TABLE_CS_SKIP_LIST_ENTRY_HPP
-
-#include "common.hpp"
-#include "cs-entry.hpp"
-
-namespace nfd {
-namespace cs {
-namespace skip_list {
-
-/** \brief represents an entry in a CS with skip list implementation
- */
-class Entry : public cs::Entry
-{
-public:
-  typedef std::map<int, std::list<Entry*>::iterator > LayerIterators;
-
-  Entry() = default;
-
-  /** \brief releases reference counts on shared objects
-   */
-  void
-  release();
-
-  /** \brief saves the iterator pointing to the CS entry on a specific layer of skip list
-   */
-  void
-  setIterator(int layer, const LayerIterators::mapped_type& layerIterator);
-
-  /** \brief removes the iterator pointing to the CS entry on a specific layer of skip list
-   */
-  void
-  removeIterator(int layer);
-
-  /** \brief returns the table containing <layer, iterator> pairs.
-   */
-  const LayerIterators&
-  getIterators() const;
-
-private:
-  /** \brief prints <layer, iterator> pairs.
-   */
-  void
-  printIterators() const;
-
-private:
-  LayerIterators m_layerIterators;
-};
-
-inline const Entry::LayerIterators&
-Entry::getIterators() const
-{
-  return m_layerIterators;
-}
-
-} // namespace skip_list
-} // namespace cs
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_CS_SKIP_LIST_ENTRY_HPP
diff --git a/NFD/daemon/table/cs.cpp b/NFD/daemon/table/cs.cpp
deleted file mode 100644
index d976def..0000000
--- a/NFD/daemon/table/cs.cpp
+++ /dev/null
@@ -1,847 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * \author Ilya Moiseenko <http://ilyamoiseenko.com/>
- * \author Junxiao Shi <http://www.cs.arizona.edu/people/shijunxiao/>
- * \author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#include "cs.hpp"
-#include "core/logger.hpp"
-#include "core/random.hpp"
-
-#include <ndn-cxx/util/crypto.hpp>
-#include <ndn-cxx/security/signature-sha256-with-rsa.hpp>
-
-#include <boost/random/bernoulli_distribution.hpp>
-#include <boost/concept/assert.hpp>
-#include <boost/concept_check.hpp>
-#include <type_traits>
-
-/// max skip list layers
-static const size_t SKIPLIST_MAX_LAYERS = 32;
-/// probability for an entry in layer N to appear also in layer N+1
-static const double SKIPLIST_PROBABILITY = 0.25;
-
-NFD_LOG_INIT("ContentStore");
-
-namespace nfd {
-
-// http://en.cppreference.com/w/cpp/concept/ForwardIterator
-BOOST_CONCEPT_ASSERT((boost::ForwardIterator<Cs::const_iterator>));
-// boost::ForwardIterator follows SGI standard http://www.sgi.com/tech/stl/ForwardIterator.html,
-// which doesn't require DefaultConstructible
-#ifdef HAVE_IS_DEFAULT_CONSTRUCTIBLE
-static_assert(std::is_default_constructible<Cs::const_iterator>::value,
-              "Cs::const_iterator must be default-constructible");
-#else
-BOOST_CONCEPT_ASSERT((boost::DefaultConstructible<Cs::const_iterator>));
-#endif // HAVE_IS_DEFAULT_CONSTRUCTIBLE
-
-Cs::Cs(size_t nMaxPackets)
-  : m_nMaxPackets(nMaxPackets)
-  , m_nPackets(0)
-{
-  SkipListLayer* zeroLayer = new SkipListLayer();
-  m_skipList.push_back(zeroLayer);
-
-  for (size_t i = 0; i < m_nMaxPackets; i++)
-    m_freeCsEntries.push(new cs::skip_list::Entry());
-}
-
-Cs::~Cs()
-{
-  // evict all items from CS
-  while (evictItem())
-    ;
-
-  BOOST_ASSERT(m_freeCsEntries.size() == m_nMaxPackets);
-
-  while (!m_freeCsEntries.empty())
-    {
-      delete m_freeCsEntries.front();
-      m_freeCsEntries.pop();
-    }
-}
-
-size_t
-Cs::size() const
-{
-  return m_nPackets; // size of the first layer in a skip list
-}
-
-void
-Cs::setLimit(size_t nMaxPackets)
-{
-  size_t oldNMaxPackets = m_nMaxPackets;
-  m_nMaxPackets = nMaxPackets;
-
-  while (size() > m_nMaxPackets) {
-    evictItem();
-  }
-
-  if (m_nMaxPackets >= oldNMaxPackets) {
-    for (size_t i = oldNMaxPackets; i < m_nMaxPackets; i++) {
-      m_freeCsEntries.push(new cs::skip_list::Entry());
-    }
-  }
-  else {
-    for (size_t i = oldNMaxPackets; i > m_nMaxPackets; i--) {
-      delete m_freeCsEntries.front();
-      m_freeCsEntries.pop();
-    }
-  }
-}
-
-size_t
-Cs::getLimit() const
-{
-  return m_nMaxPackets;
-}
-
-//Reference: "Skip Lists: A Probabilistic Alternative to Balanced Trees" by W.Pugh
-std::pair<cs::skip_list::Entry*, bool>
-Cs::insertToSkipList(const Data& data, bool isUnsolicited)
-{
-  NFD_LOG_TRACE("insertToSkipList() " << data.getFullName() << ", "
-                << "skipList size " << size());
-
-  BOOST_ASSERT(m_cleanupIndex.size() <= size());
-  BOOST_ASSERT(m_freeCsEntries.size() > 0);
-
-  // take entry for the memory pool
-  cs::skip_list::Entry* entry = m_freeCsEntries.front();
-  m_freeCsEntries.pop();
-  m_nPackets++;
-  entry->setData(data, isUnsolicited);
-
-  bool insertInFront = false;
-  bool isIterated = false;
-  SkipList::reverse_iterator topLayer = m_skipList.rbegin();
-  SkipListLayer::iterator updateTable[SKIPLIST_MAX_LAYERS];
-  SkipListLayer::iterator head = (*topLayer)->begin();
-
-  if (!(*topLayer)->empty())
-    {
-      //start from the upper layer towards bottom
-      int layer = m_skipList.size() - 1;
-      for (SkipList::reverse_iterator rit = topLayer; rit != m_skipList.rend(); ++rit)
-        {
-          //if we didn't do any iterations on the higher layers, start from the begin() again
-          if (!isIterated)
-            head = (*rit)->begin();
-
-          updateTable[layer] = head;
-
-          if (head != (*rit)->end())
-            {
-              // it can happen when begin() contains the element in front of which we need to insert
-              if (!isIterated && ((*head)->getFullName() >= entry->getFullName()))
-                {
-                  --updateTable[layer];
-                  insertInFront = true;
-                }
-              else
-                {
-                  SkipListLayer::iterator it = head;
-
-                  while ((*it)->getFullName() < entry->getFullName())
-                    {
-                      head = it;
-                      updateTable[layer] = it;
-                      isIterated = true;
-
-                      ++it;
-                      if (it == (*rit)->end())
-                        break;
-                    }
-                }
-            }
-
-          if (layer > 0)
-            head = (*head)->getIterators().find(layer - 1)->second; // move HEAD to the lower layer
-
-          layer--;
-        }
-    }
-  else
-    {
-      updateTable[0] = (*topLayer)->begin(); //initialization
-    }
-
-  head = updateTable[0];
-  ++head; // look at the next slot to check if it contains a duplicate
-
-  bool isCsEmpty = (size() == 0);
-  bool isInBoundaries = (head != (*m_skipList.begin())->end());
-  bool isNameIdentical = false;
-  if (!isCsEmpty && isInBoundaries)
-    {
-      isNameIdentical = (*head)->getFullName() == entry->getFullName();
-    }
-
-  //check if this is a duplicate packet
-  if (isNameIdentical)
-    {
-      NFD_LOG_TRACE("Duplicate name (with digest)");
-
-      (*head)->setData(data, isUnsolicited); //updates stale time
-
-      // new entry not needed, returning to the pool
-      entry->release();
-      m_freeCsEntries.push(entry);
-      m_nPackets--;
-
-      return std::make_pair(*head, false);
-    }
-
-  NFD_LOG_TRACE("Not a duplicate");
-
-  size_t randomLayer = pickRandomLayer();
-
-  while (m_skipList.size() < randomLayer + 1)
-    {
-      SkipListLayer* newLayer = new SkipListLayer();
-      m_skipList.push_back(newLayer);
-
-      updateTable[(m_skipList.size() - 1)] = newLayer->begin();
-    }
-
-  size_t layer = 0;
-  for (SkipList::iterator i = m_skipList.begin();
-       i != m_skipList.end() && layer <= randomLayer; ++i)
-    {
-      if (updateTable[layer] == (*i)->end() && !insertInFront)
-        {
-          (*i)->push_back(entry);
-          SkipListLayer::iterator last = (*i)->end();
-          --last;
-          entry->setIterator(layer, last);
-
-          NFD_LOG_TRACE("pushback " << &(*last));
-        }
-      else if (updateTable[layer] == (*i)->end() && insertInFront)
-        {
-          (*i)->push_front(entry);
-          entry->setIterator(layer, (*i)->begin());
-
-          NFD_LOG_TRACE("pushfront ");
-        }
-      else
-        {
-          NFD_LOG_TRACE("insertafter");
-          ++updateTable[layer]; // insert after
-          SkipListLayer::iterator position = (*i)->insert(updateTable[layer], entry);
-          entry->setIterator(layer, position); // save iterator where item was inserted
-        }
-      layer++;
-    }
-
-  return std::make_pair(entry, true);
-}
-
-bool
-Cs::insert(const Data& data, bool isUnsolicited)
-{
-  NFD_LOG_TRACE("insert() " << data.getFullName());
-
-  if (isFull())
-    {
-      evictItem();
-    }
-
-  //pointer and insertion status
-  std::pair<cs::skip_list::Entry*, bool> entry = insertToSkipList(data, isUnsolicited);
-
-  //new entry
-  if (static_cast<bool>(entry.first) && (entry.second == true))
-    {
-      m_cleanupIndex.push_back(entry.first);
-      return true;
-    }
-
-  return false;
-}
-
-size_t
-Cs::pickRandomLayer() const
-{
-  static boost::random::bernoulli_distribution<> dist(SKIPLIST_PROBABILITY);
-  // TODO rewrite using geometry_distribution
-  size_t layer;
-  for (layer = 0; layer < SKIPLIST_MAX_LAYERS; ++layer) {
-    if (!dist(getGlobalRng())) {
-      break;
-    }
-  }
-  return layer;
-}
-
-bool
-Cs::isFull() const
-{
-  if (size() >= m_nMaxPackets) //size of the first layer vs. max size
-    return true;
-
-  return false;
-}
-
-bool
-Cs::eraseFromSkipList(cs::skip_list::Entry* entry)
-{
-  NFD_LOG_TRACE("eraseFromSkipList() "  << entry->getFullName());
-  NFD_LOG_TRACE("SkipList size " << size());
-
-  bool isErased = false;
-
-  const std::map<int, std::list<cs::skip_list::Entry*>::iterator>& iterators = entry->getIterators();
-
-  if (!iterators.empty())
-    {
-      int layer = 0;
-
-      for (SkipList::iterator it = m_skipList.begin(); it != m_skipList.end(); )
-        {
-          std::map<int, std::list<cs::skip_list::Entry*>::iterator>::const_iterator i = iterators.find(layer);
-
-          if (i != iterators.end())
-            {
-              (*it)->erase(i->second);
-              entry->removeIterator(layer);
-              isErased = true;
-
-              //remove layers that do not contain any elements (starting from the second layer)
-              if ((layer != 0) && (*it)->empty())
-                {
-                  delete *it;
-                  it = m_skipList.erase(it);
-                }
-              else
-                ++it;
-
-              layer++;
-            }
-          else
-            break;
-      }
-    }
-
-  //delete entry;
-  if (isErased)
-  {
-    entry->release();
-    m_freeCsEntries.push(entry);
-    m_nPackets--;
-  }
-
-  return isErased;
-}
-
-bool
-Cs::evictItem()
-{
-  NFD_LOG_TRACE("evictItem()");
-
-  if (!m_cleanupIndex.get<unsolicited>().empty()) {
-    CleanupIndex::index<unsolicited>::type::const_iterator firstSolicited =
-      m_cleanupIndex.get<unsolicited>().upper_bound(false);
-
-    if (firstSolicited != m_cleanupIndex.get<unsolicited>().begin()) {
-      --firstSolicited;
-      BOOST_ASSERT((*firstSolicited)->isUnsolicited());
-      NFD_LOG_TRACE("Evict from unsolicited queue");
-
-      eraseFromSkipList(*firstSolicited);
-      m_cleanupIndex.get<unsolicited>().erase(firstSolicited);
-      return true;
-    }
-    else {
-      BOOST_ASSERT(!(*m_cleanupIndex.get<unsolicited>().begin())->isUnsolicited());
-    }
-  }
-
-  if (!m_cleanupIndex.get<byStaleness>().empty() &&
-      (*m_cleanupIndex.get<byStaleness>().begin())->getStaleTime() < time::steady_clock::now())
-  {
-    NFD_LOG_TRACE("Evict from staleness queue");
-
-    eraseFromSkipList(*m_cleanupIndex.get<byStaleness>().begin());
-    m_cleanupIndex.get<byStaleness>().erase(m_cleanupIndex.get<byStaleness>().begin());
-    return true;
-  }
-
-  if (!m_cleanupIndex.get<byArrival>().empty())
-  {
-    NFD_LOG_TRACE("Evict from arrival queue");
-
-    eraseFromSkipList(*m_cleanupIndex.get<byArrival>().begin());
-    m_cleanupIndex.get<byArrival>().erase(m_cleanupIndex.get<byArrival>().begin());
-    return true;
-  }
-
-  return false;
-}
-
-const Data*
-Cs::find(const Interest& interest) const
-{
-  NFD_LOG_TRACE("find() " << interest.getName());
-
-  bool isIterated = false;
-  SkipList::const_reverse_iterator topLayer = m_skipList.rbegin();
-  SkipListLayer::iterator head = (*topLayer)->begin();
-
-  if (!(*topLayer)->empty())
-    {
-      //start from the upper layer towards bottom
-      int layer = m_skipList.size() - 1;
-      for (SkipList::const_reverse_iterator rit = topLayer; rit != m_skipList.rend(); ++rit)
-        {
-          //if we didn't do any iterations on the higher layers, start from the begin() again
-          if (!isIterated)
-            head = (*rit)->begin();
-
-          if (head != (*rit)->end())
-            {
-              // it happens when begin() contains the element we want to find
-              if (!isIterated && (interest.getName().isPrefixOf((*head)->getFullName())))
-                {
-                  if (layer > 0)
-                    {
-                      layer--;
-                      continue; // try lower layer
-                    }
-                  else
-                    {
-                      isIterated = true;
-                    }
-                }
-              else
-                {
-                  SkipListLayer::iterator it = head;
-
-                  while ((*it)->getFullName() < interest.getName())
-                    {
-                      NFD_LOG_TRACE((*it)->getFullName() << " < " << interest.getName());
-                      head = it;
-                      isIterated = true;
-
-                      ++it;
-                      if (it == (*rit)->end())
-                        break;
-                    }
-                }
-            }
-
-          if (layer > 0)
-            {
-              head = (*head)->getIterators().find(layer - 1)->second; // move HEAD to the lower layer
-            }
-          else //if we reached the first layer
-            {
-              if (isIterated)
-                return selectChild(interest, head);
-            }
-
-          layer--;
-        }
-    }
-
-  return 0;
-}
-
-const Data*
-Cs::selectChild(const Interest& interest, SkipListLayer::iterator startingPoint) const
-{
-  BOOST_ASSERT(startingPoint != (*m_skipList.begin())->end());
-
-  if (startingPoint != (*m_skipList.begin())->begin())
-    {
-      BOOST_ASSERT((*startingPoint)->getFullName() < interest.getName());
-    }
-
-  NFD_LOG_TRACE("selectChild() " << interest.getChildSelector() << " "
-                << (*startingPoint)->getFullName());
-
-  bool hasLeftmostSelector = (interest.getChildSelector() <= 0);
-  bool hasRightmostSelector = !hasLeftmostSelector;
-
-  if (hasLeftmostSelector)
-    {
-      bool doesInterestContainDigest = recognizeInterestWithDigest(interest, *startingPoint);
-      bool isInPrefix = false;
-
-      if (doesInterestContainDigest)
-        {
-          isInPrefix = interest.getName().getPrefix(-1).isPrefixOf((*startingPoint)->getFullName());
-        }
-      else
-        {
-          isInPrefix = interest.getName().isPrefixOf((*startingPoint)->getFullName());
-        }
-
-      if (isInPrefix)
-        {
-          if (doesComplyWithSelectors(interest, *startingPoint, doesInterestContainDigest))
-            {
-              return &(*startingPoint)->getData();
-            }
-        }
-    }
-
-  //iterate to the right
-  SkipListLayer::iterator rightmost = startingPoint;
-  if (startingPoint != (*m_skipList.begin())->end())
-    {
-      SkipListLayer::iterator rightmostCandidate = startingPoint;
-      Name currentChildPrefix("");
-
-      while (true)
-        {
-          ++rightmostCandidate;
-
-          bool isInBoundaries = (rightmostCandidate != (*m_skipList.begin())->end());
-          bool isInPrefix = false;
-          bool doesInterestContainDigest = false;
-          if (isInBoundaries)
-            {
-              doesInterestContainDigest = recognizeInterestWithDigest(interest,
-                                                                      *rightmostCandidate);
-
-              if (doesInterestContainDigest)
-                {
-                  isInPrefix = interest.getName().getPrefix(-1)
-                                 .isPrefixOf((*rightmostCandidate)->getFullName());
-                }
-              else
-                {
-                  isInPrefix = interest.getName().isPrefixOf((*rightmostCandidate)->getFullName());
-                }
-            }
-
-          if (isInPrefix)
-            {
-              if (doesComplyWithSelectors(interest, *rightmostCandidate, doesInterestContainDigest))
-                {
-                  if (hasLeftmostSelector)
-                    {
-                      return &(*rightmostCandidate)->getData();
-                    }
-
-                  if (hasRightmostSelector)
-                    {
-                      if (doesInterestContainDigest)
-                        {
-                          // get prefix which is one component longer than Interest name
-                          // (without digest)
-                          const Name& childPrefix = (*rightmostCandidate)->getFullName()
-                                                      .getPrefix(interest.getName().size());
-                          NFD_LOG_TRACE("Child prefix" << childPrefix);
-
-                          if (currentChildPrefix.empty() || (childPrefix != currentChildPrefix))
-                            {
-                              currentChildPrefix = childPrefix;
-                              rightmost = rightmostCandidate;
-                            }
-                        }
-                      else
-                        {
-                          // get prefix which is one component longer than Interest name
-                          const Name& childPrefix = (*rightmostCandidate)->getFullName()
-                                                      .getPrefix(interest.getName().size() + 1);
-                          NFD_LOG_TRACE("Child prefix" << childPrefix);
-
-                          if (currentChildPrefix.empty() || (childPrefix != currentChildPrefix))
-                            {
-                              currentChildPrefix = childPrefix;
-                              rightmost = rightmostCandidate;
-                            }
-                        }
-                    }
-                }
-            }
-          else
-            break;
-        }
-    }
-
-  if (rightmost != startingPoint)
-    {
-      return &(*rightmost)->getData();
-    }
-
-  if (hasRightmostSelector) // if rightmost was not found, try starting point
-    {
-      bool doesInterestContainDigest = recognizeInterestWithDigest(interest, *startingPoint);
-      bool isInPrefix = false;
-
-      if (doesInterestContainDigest)
-        {
-          isInPrefix = interest.getName().getPrefix(-1).isPrefixOf((*startingPoint)->getFullName());
-        }
-      else
-        {
-          isInPrefix = interest.getName().isPrefixOf((*startingPoint)->getFullName());
-        }
-
-      if (isInPrefix)
-        {
-          if (doesComplyWithSelectors(interest, *startingPoint, doesInterestContainDigest))
-            {
-              return &(*startingPoint)->getData();
-            }
-        }
-    }
-
-  return 0;
-}
-
-bool
-Cs::doesComplyWithSelectors(const Interest& interest,
-                            cs::skip_list::Entry* entry,
-                            bool doesInterestContainDigest) const
-{
-  NFD_LOG_TRACE("doesComplyWithSelectors()");
-
-  /// \todo The following detection is not correct
-  ///       1. If Interest name ends with 32-octet component doesn't mean that this component is
-  ///          digest
-  ///       2. Only min/max selectors (both 0) can be specified, all other selectors do not
-  ///          make sense for interests with digest (though not sure if we need to enforce this)
-
-  if (doesInterestContainDigest)
-    {
-      if (interest.getName().get(-1) != entry->getFullName().get(-1))
-        {
-          NFD_LOG_TRACE("violates implicit digest");
-          return false;
-        }
-    }
-
-  if (!doesInterestContainDigest)
-    {
-      if (interest.getMinSuffixComponents() >= 0)
-        {
-          size_t minDataNameLength = interest.getName().size() + interest.getMinSuffixComponents();
-
-          bool isSatisfied = (minDataNameLength <= entry->getFullName().size());
-          if (!isSatisfied)
-            {
-              NFD_LOG_TRACE("violates minComponents");
-              return false;
-            }
-        }
-
-      if (interest.getMaxSuffixComponents() >= 0)
-        {
-          size_t maxDataNameLength = interest.getName().size() + interest.getMaxSuffixComponents();
-
-          bool isSatisfied = (maxDataNameLength >= entry->getFullName().size());
-          if (!isSatisfied)
-            {
-              NFD_LOG_TRACE("violates maxComponents");
-              return false;
-            }
-        }
-    }
-
-  if (interest.getMustBeFresh() && entry->getStaleTime() < time::steady_clock::now())
-    {
-      NFD_LOG_TRACE("violates mustBeFresh");
-      return false;
-    }
-
-  if (!interest.getPublisherPublicKeyLocator().empty())
-    {
-      if (entry->getData().getSignature().getType() == ndn::Signature::Sha256WithRsa)
-        {
-          ndn::SignatureSha256WithRsa rsaSignature(entry->getData().getSignature());
-          if (rsaSignature.getKeyLocator() != interest.getPublisherPublicKeyLocator())
-            {
-              NFD_LOG_TRACE("violates publisher key selector");
-              return false;
-            }
-        }
-      else
-        {
-          NFD_LOG_TRACE("violates publisher key selector");
-          return false;
-        }
-    }
-
-  if (doesInterestContainDigest)
-    {
-      const ndn::name::Component& lastComponent = entry->getFullName().get(-1);
-
-      if (!lastComponent.empty())
-        {
-          if (interest.getExclude().isExcluded(lastComponent))
-            {
-              NFD_LOG_TRACE("violates exclusion");
-              return false;
-            }
-        }
-    }
-  else
-    {
-      if (entry->getFullName().size() >= interest.getName().size() + 1)
-        {
-          const ndn::name::Component& nextComponent = entry->getFullName()
-                                                        .get(interest.getName().size());
-          if (!nextComponent.empty())
-            {
-              if (interest.getExclude().isExcluded(nextComponent))
-                {
-                  NFD_LOG_TRACE("violates exclusion");
-                  return false;
-                }
-            }
-        }
-    }
-
-  NFD_LOG_TRACE("complies");
-  return true;
-}
-
-bool
-Cs::recognizeInterestWithDigest(const Interest& interest, cs::skip_list::Entry* entry) const
-{
-  // only when min selector is not specified or specified with value of 0
-  // and Interest's name length is exactly the length of the name of CS entry
-  if (interest.getMinSuffixComponents() <= 0 &&
-      interest.getName().size() == (entry->getFullName().size()))
-    {
-      const ndn::name::Component& last = interest.getName().get(-1);
-      if (last.value_size() == ndn::crypto::SHA256_DIGEST_SIZE)
-        {
-          NFD_LOG_TRACE("digest recognized");
-          return true;
-        }
-    }
-
-  return false;
-}
-
-void
-Cs::erase(const Name& exactName)
-{
-  NFD_LOG_TRACE("insert() " << exactName << ", "
-                << "skipList size " << size());
-
-  bool isIterated = false;
-  SkipListLayer::iterator updateTable[SKIPLIST_MAX_LAYERS];
-  SkipList::reverse_iterator topLayer = m_skipList.rbegin();
-  SkipListLayer::iterator head = (*topLayer)->begin();
-
-  if (!(*topLayer)->empty())
-    {
-      //start from the upper layer towards bottom
-      int layer = m_skipList.size() - 1;
-      for (SkipList::reverse_iterator rit = topLayer; rit != m_skipList.rend(); ++rit)
-        {
-          //if we didn't do any iterations on the higher layers, start from the begin() again
-          if (!isIterated)
-            head = (*rit)->begin();
-
-          updateTable[layer] = head;
-
-          if (head != (*rit)->end())
-            {
-              // it can happen when begin() contains the element we want to remove
-              if (!isIterated && ((*head)->getFullName() == exactName))
-                {
-                  cs::skip_list::Entry* entryToDelete = *head;
-                  NFD_LOG_TRACE("Found target " << entryToDelete->getFullName());
-                  eraseFromSkipList(entryToDelete);
-                  // head can become invalid after eraseFromSkipList
-                  m_cleanupIndex.remove(entryToDelete);
-                  return;
-                }
-              else
-                {
-                  SkipListLayer::iterator it = head;
-
-                  while ((*it)->getFullName() < exactName)
-                    {
-                      head = it;
-                      updateTable[layer] = it;
-                      isIterated = true;
-
-                      ++it;
-                      if (it == (*rit)->end())
-                        break;
-                    }
-                }
-            }
-
-          if (layer > 0)
-            head = (*head)->getIterators().find(layer - 1)->second; // move HEAD to the lower layer
-
-          layer--;
-        }
-    }
-  else
-    {
-      return;
-    }
-
-  head = updateTable[0];
-  ++head; // look at the next slot to check if it contains the item we want to remove
-
-  bool isCsEmpty = (size() == 0);
-  bool isInBoundaries = (head != (*m_skipList.begin())->end());
-  bool isNameIdentical = false;
-  if (!isCsEmpty && isInBoundaries)
-    {
-      NFD_LOG_TRACE("Identical? " << (*head)->getFullName());
-      isNameIdentical = (*head)->getFullName() == exactName;
-    }
-
-  if (isNameIdentical)
-    {
-      cs::skip_list::Entry* entryToDelete = *head;
-      NFD_LOG_TRACE("Found target " << entryToDelete->getFullName());
-      eraseFromSkipList(entryToDelete);
-      // head can become invalid after eraseFromSkipList
-      m_cleanupIndex.remove(entryToDelete);
-    }
-}
-
-void
-Cs::printSkipList() const
-{
-  NFD_LOG_TRACE("print()");
-  //start from the upper layer towards bottom
-  int layer = m_skipList.size() - 1;
-  for (SkipList::const_reverse_iterator rit = m_skipList.rbegin(); rit != m_skipList.rend(); ++rit)
-    {
-      for (SkipListLayer::iterator it = (*rit)->begin(); it != (*rit)->end(); ++it)
-        {
-          NFD_LOG_TRACE("Layer " << layer << " " << (*it)->getFullName());
-        }
-      layer--;
-    }
-}
-
-} //namespace nfd
diff --git a/NFD/daemon/table/cs.hpp b/NFD/daemon/table/cs.hpp
deleted file mode 100644
index 0d989cd..0000000
--- a/NFD/daemon/table/cs.hpp
+++ /dev/null
@@ -1,348 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * \author Ilya Moiseenko <http://ilyamoiseenko.com/>
- * \author Junxiao Shi <http://www.cs.arizona.edu/people/shijunxiao/>
- * \author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#ifndef NFD_DAEMON_TABLE_CS_HPP
-#define NFD_DAEMON_TABLE_CS_HPP
-
-#include "common.hpp"
-#include "cs-skip-list-entry.hpp"
-
-#include <boost/multi_index/member.hpp>
-#include <boost/multi_index_container.hpp>
-#include <boost/multi_index/ordered_index.hpp>
-#include <boost/multi_index/sequenced_index.hpp>
-#include <boost/multi_index/identity.hpp>
-
-#include <queue>
-
-namespace nfd {
-
-typedef std::list<cs::skip_list::Entry*> SkipListLayer;
-typedef std::list<SkipListLayer*> SkipList;
-
-class StalenessComparator
-{
-public:
-  bool
-  operator()(const cs::skip_list::Entry* entry1, const cs::skip_list::Entry* entry2) const
-  {
-    return entry1->getStaleTime() < entry2->getStaleTime();
-  }
-};
-
-class UnsolicitedComparator
-{
-public:
-  bool
-  operator()(const cs::skip_list::Entry* entry1, const cs::skip_list::Entry* entry2) const
-  {
-    return entry1->isUnsolicited();
-  }
-
-  bool
-  operator()(bool isUnsolicited, const cs::skip_list::Entry* entry) const
-  {
-    if (isUnsolicited)
-      return true;
-    else
-      return !entry->isUnsolicited();
-  }
-};
-
-// tags
-class unsolicited;
-class byStaleness;
-class byArrival;
-
-typedef boost::multi_index_container<
-  cs::skip_list::Entry*,
-  boost::multi_index::indexed_by<
-
-    // by arrival (FIFO)
-    boost::multi_index::sequenced<
-      boost::multi_index::tag<byArrival>
-    >,
-
-    // index by staleness time
-    boost::multi_index::ordered_non_unique<
-      boost::multi_index::tag<byStaleness>,
-      boost::multi_index::identity<cs::skip_list::Entry*>,
-      StalenessComparator
-    >,
-
-    // unsolicited Data is in the front
-    boost::multi_index::ordered_non_unique<
-      boost::multi_index::tag<unsolicited>,
-      boost::multi_index::identity<cs::skip_list::Entry*>,
-      UnsolicitedComparator
-    >
-
-  >
-> CleanupIndex;
-
-/** \brief represents Content Store
- */
-class Cs : noncopyable
-{
-public:
-  explicit
-  Cs(size_t nMaxPackets = 10);
-
-  ~Cs();
-
-  /** \brief inserts a Data packet
-   *  This method does not consider the payload of the Data packet.
-   *
-   *  Packets are considered duplicate if the name matches.
-   *  The new Data packet with the identical name, but a different payload
-   *  is not placed in the Content Store
-   *  \return{ whether the Data is added }
-   */
-  bool
-  insert(const Data& data, bool isUnsolicited = false);
-
-  /** \brief finds the best match Data for an Interest
-   *  \return{ the best match, if any; otherwise 0 }
-   */
-  const Data*
-  find(const Interest& interest) const;
-
-  /** \brief deletes CS entry by the exact name
-   */
-  void
-  erase(const Name& exactName);
-
-  /** \brief sets maximum allowed size of Content Store (in packets)
-   */
-  void
-  setLimit(size_t nMaxPackets);
-
-  /** \brief returns maximum allowed size of Content Store (in packets)
-   *  \return{ number of packets that can be stored in Content Store }
-   */
-  size_t
-  getLimit() const;
-
-  /** \brief returns current size of Content Store measured in packets
-   *  \return{ number of packets located in Content Store }
-   */
-  size_t
-  size() const;
-
-public: // enumeration
-  class const_iterator;
-
-  /** \brief returns an iterator pointing to the first CS entry
-   *  \note Iteration order is implementation-specific and is undefined
-   *  \note The returned iterator may get invalidated if CS is modified
-   */
-  const_iterator
-  begin() const;
-
-  /** \brief returns an iterator referring to the past-the-end CS entry
-   *  \note The returned iterator may get invalidated if CS is modified
-   */
-  const_iterator
-  end() const;
-
-  class const_iterator : public std::iterator<std::forward_iterator_tag, const cs::Entry>
-  {
-  public:
-    const_iterator() = default;
-
-    const_iterator(SkipListLayer::const_iterator it);
-
-    ~const_iterator();
-
-    reference
-    operator*() const;
-
-    pointer
-    operator->() const;
-
-    const_iterator&
-    operator++();
-
-    const_iterator
-    operator++(int);
-
-    bool
-    operator==(const const_iterator& other) const;
-
-    bool
-    operator!=(const const_iterator& other) const;
-
-  private:
-    SkipListLayer::const_iterator m_skipListIterator;
-  };
-
-protected:
-  /** \brief removes one Data packet from Content Store based on replacement policy
-   *  \return{ whether the Data was removed }
-   */
-  bool
-  evictItem();
-
-private:
-  /** \brief returns True if the Content Store is at its maximum capacity
-   *  \return{ True if Content Store is full; otherwise False}
-   */
-  bool
-  isFull() const;
-
-  /** \brief Computes the layer where new Content Store Entry is placed
-   *
-   *  Reference: "Skip Lists: A Probabilistic Alternative to Balanced Trees" by W.Pugh
-   *  \return{ returns random layer (number) in a skip list}
-   */
-  size_t
-  pickRandomLayer() const;
-
-  /** \brief Inserts a new Content Store Entry in a skip list
-   *  \return{ returns a pair containing a pointer to the CS Entry,
-   *  and a flag indicating if the entry was newly created (True) or refreshed (False) }
-   */
-  std::pair<cs::skip_list::Entry*, bool>
-  insertToSkipList(const Data& data, bool isUnsolicited = false);
-
-  /** \brief Removes a specific CS Entry from all layers of a skip list
-   *  \return{ returns True if CS Entry was succesfully removed and False if CS Entry was not found}
-   */
-  bool
-  eraseFromSkipList(cs::skip_list::Entry* entry);
-
-  /** \brief Prints contents of the skip list, starting from the top layer
-   */
-  void
-  printSkipList() const;
-
-  /** \brief Implements child selector (leftmost, rightmost, undeclared).
-   *  Operates on the first layer of a skip list.
-   *
-   *  startingPoint must be less than Interest Name.
-   *  startingPoint can be equal to Interest Name only when the item is in the begin() position.
-   *
-   *  Iterates toward greater Names, terminates when CS entry falls out of Interest prefix.
-   *  When childSelector = leftmost, returns first CS entry that satisfies other selectors.
-   *  When childSelector = rightmost, it goes till the end, and returns CS entry that satisfies
-   *  other selectors. Returned CS entry is the leftmost child of the rightmost child.
-   *  \return{ the best match, if any; otherwise 0 }
-   */
-  const Data*
-  selectChild(const Interest& interest, SkipListLayer::iterator startingPoint) const;
-
-  /** \brief checks if Content Store entry satisfies Interest selectors (MinSuffixComponents,
-   *  MaxSuffixComponents, Implicit Digest, MustBeFresh)
-   *  \return{ true if satisfies all selectors; false otherwise }
-   */
-  bool
-  doesComplyWithSelectors(const Interest& interest,
-                          cs::skip_list::Entry* entry,
-                          bool doesInterestContainDigest) const;
-
-  /** \brief interprets minSuffixComponent and name lengths to understand if Interest contains
-   *  implicit digest of the data
-   *  \return{ True if Interest name contains digest; False otherwise }
-   */
-  bool
-  recognizeInterestWithDigest(const Interest& interest, cs::skip_list::Entry* entry) const;
-
-private:
-  SkipList m_skipList;
-  CleanupIndex m_cleanupIndex;
-  size_t m_nMaxPackets; // user defined maximum size of the Content Store in packets
-  size_t m_nPackets;    // current number of packets in Content Store
-  std::queue<cs::skip_list::Entry*> m_freeCsEntries; // memory pool
-};
-
-inline Cs::const_iterator
-Cs::begin() const
-{
-  return const_iterator(m_skipList.front()->begin());
-}
-
-inline Cs::const_iterator
-Cs::end() const
-{
-  return const_iterator(m_skipList.front()->end());
-}
-
-inline
-Cs::const_iterator::const_iterator(SkipListLayer::const_iterator it)
-  : m_skipListIterator(it)
-{
-}
-
-inline
-Cs::const_iterator::~const_iterator()
-{
-}
-
-inline Cs::const_iterator&
-Cs::const_iterator::operator++()
-{
-  ++m_skipListIterator;
-  return *this;
-}
-
-inline Cs::const_iterator
-Cs::const_iterator::operator++(int)
-{
-  Cs::const_iterator temp(*this);
-  ++(*this);
-  return temp;
-}
-
-inline Cs::const_iterator::reference
-Cs::const_iterator::operator*() const
-{
-  return *(this->operator->());
-}
-
-inline Cs::const_iterator::pointer
-Cs::const_iterator::operator->() const
-{
-  return *m_skipListIterator;
-}
-
-inline bool
-Cs::const_iterator::operator==(const Cs::const_iterator& other) const
-{
-  return m_skipListIterator == other.m_skipListIterator;
-}
-
-inline bool
-Cs::const_iterator::operator!=(const Cs::const_iterator& other) const
-{
-  return !(*this == other);
-}
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_CS_HPP
diff --git a/NFD/daemon/table/dead-nonce-list.cpp b/NFD/daemon/table/dead-nonce-list.cpp
deleted file mode 100644
index be6afd8..0000000
--- a/NFD/daemon/table/dead-nonce-list.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "dead-nonce-list.hpp"
-#include "core/city-hash.hpp"
-#include "core/logger.hpp"
-
-NFD_LOG_INIT("DeadNonceList");
-
-namespace nfd {
-
-const time::nanoseconds DeadNonceList::DEFAULT_LIFETIME = time::seconds(6);
-const time::nanoseconds DeadNonceList::MIN_LIFETIME = time::milliseconds(1);
-const size_t DeadNonceList::INITIAL_CAPACITY = (1 << 7);
-const size_t DeadNonceList::MIN_CAPACITY = (1 << 3);
-const size_t DeadNonceList::MAX_CAPACITY = (1 << 24);
-const DeadNonceList::Entry DeadNonceList::MARK = 0;
-const size_t DeadNonceList::EXPECTED_MARK_COUNT = 5;
-const double DeadNonceList::CAPACITY_UP = 1.2;
-const double DeadNonceList::CAPACITY_DOWN = 0.9;
-const size_t DeadNonceList::EVICT_LIMIT = (1 << 6);
-
-DeadNonceList::DeadNonceList(const time::nanoseconds& lifetime)
-  : m_lifetime(lifetime)
-  , m_queue(m_index.get<0>())
-  , m_ht(m_index.get<1>())
-  , m_capacity(INITIAL_CAPACITY)
-  , m_markInterval(m_lifetime / EXPECTED_MARK_COUNT)
-  , m_adjustCapacityInterval(m_lifetime)
-{
-  if (m_lifetime < MIN_LIFETIME) {
-    throw std::invalid_argument("lifetime is less than MIN_LIFETIME");
-  }
-
-  for (size_t i = 0; i < EXPECTED_MARK_COUNT; ++i) {
-    m_queue.push_back(MARK);
-  }
-
-  m_markEvent = scheduler::schedule(m_markInterval, bind(&DeadNonceList::mark, this));
-  m_adjustCapacityEvent = scheduler::schedule(m_adjustCapacityInterval,
-                                              bind(&DeadNonceList::adjustCapacity, this));
-}
-
-DeadNonceList::~DeadNonceList()
-{
-  scheduler::cancel(m_markEvent);
-  scheduler::cancel(m_adjustCapacityEvent);
-
-  BOOST_ASSERT_MSG(DEFAULT_LIFETIME >= MIN_LIFETIME, "DEFAULT_LIFETIME is too small");
-  static_assert(INITIAL_CAPACITY >= MIN_CAPACITY, "INITIAL_CAPACITY is too small");
-  static_assert(INITIAL_CAPACITY <= MAX_CAPACITY, "INITIAL_CAPACITY is too large");
-  BOOST_ASSERT_MSG(static_cast<size_t>(MIN_CAPACITY * CAPACITY_UP) > MIN_CAPACITY,
-                   "CAPACITY_UP must be able to increase from MIN_CAPACITY");
-  BOOST_ASSERT_MSG(static_cast<size_t>(MAX_CAPACITY * CAPACITY_DOWN) < MAX_CAPACITY,
-                   "CAPACITY_DOWN must be able to decrease from MAX_CAPACITY");
-  BOOST_ASSERT_MSG(CAPACITY_UP > 1.0, "CAPACITY_UP must adjust up");
-  BOOST_ASSERT_MSG(CAPACITY_DOWN < 1.0, "CAPACITY_DOWN must adjust down");
-  static_assert(EVICT_LIMIT >= 1, "EVICT_LIMIT must be at least 1");
-}
-
-size_t
-DeadNonceList::size() const
-{
-  return m_queue.size() - this->countMarks();
-}
-
-bool
-DeadNonceList::has(const Name& name, uint32_t nonce) const
-{
-  Entry entry = DeadNonceList::makeEntry(name, nonce);
-  return m_ht.find(entry) != m_ht.end();
-}
-
-void
-DeadNonceList::add(const Name& name, uint32_t nonce)
-{
-  Entry entry = DeadNonceList::makeEntry(name, nonce);
-  m_queue.push_back(entry);
-
-  this->evictEntries();
-}
-
-DeadNonceList::Entry
-DeadNonceList::makeEntry(const Name& name, uint32_t nonce)
-{
-  Block nameWire = name.wireEncode();
-  return CityHash64WithSeed(reinterpret_cast<const char*>(nameWire.wire()), nameWire.size(),
-                            static_cast<uint64_t>(nonce));
-}
-
-size_t
-DeadNonceList::countMarks() const
-{
-  return m_ht.count(MARK);
-}
-
-void
-DeadNonceList::mark()
-{
-  m_queue.push_back(MARK);
-  size_t nMarks = this->countMarks();
-  m_actualMarkCounts.insert(nMarks);
-
-  NFD_LOG_DEBUG("mark nMarks=" << nMarks);
-
-  scheduler::schedule(m_markInterval, bind(&DeadNonceList::mark, this));
-}
-
-void
-DeadNonceList::adjustCapacity()
-{
-  std::pair<std::multiset<size_t>::iterator, std::multiset<size_t>::iterator> equalRange =
-    m_actualMarkCounts.equal_range(EXPECTED_MARK_COUNT);
-
-  if (equalRange.second == m_actualMarkCounts.begin()) {
-    // all counts are above expected count, adjust down
-    m_capacity = std::max(MIN_CAPACITY,
-                          static_cast<size_t>(m_capacity * CAPACITY_DOWN));
-    NFD_LOG_DEBUG("adjustCapacity DOWN capacity=" << m_capacity);
-  }
-  else if (equalRange.first == m_actualMarkCounts.end()) {
-    // all counts are below expected count, adjust up
-    m_capacity = std::min(MAX_CAPACITY,
-                          static_cast<size_t>(m_capacity * CAPACITY_UP));
-    NFD_LOG_DEBUG("adjustCapacity UP capacity=" << m_capacity);
-  }
-
-  m_actualMarkCounts.clear();
-
-  this->evictEntries();
-
-  m_adjustCapacityEvent = scheduler::schedule(m_adjustCapacityInterval,
-                                              bind(&DeadNonceList::adjustCapacity, this));
-}
-
-void
-DeadNonceList::evictEntries()
-{
-  ssize_t nOverCapacity = m_queue.size() - m_capacity;
-  if (nOverCapacity <= 0) // not over capacity
-    return;
-
-  for (ssize_t nEvict = std::min<ssize_t>(nOverCapacity, EVICT_LIMIT); nEvict > 0; --nEvict) {
-    m_queue.erase(m_queue.begin());
-  }
-  BOOST_ASSERT(m_queue.size() >= m_capacity);
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/table/dead-nonce-list.hpp b/NFD/daemon/table/dead-nonce-list.hpp
deleted file mode 100644
index 1c7f7cc..0000000
--- a/NFD/daemon/table/dead-nonce-list.hpp
+++ /dev/null
@@ -1,222 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_TABLE_DEAD_NONCE_LIST_HPP
-#define NFD_DAEMON_TABLE_DEAD_NONCE_LIST_HPP
-
-#include "common.hpp"
-#include <boost/multi_index_container.hpp>
-#include <boost/multi_index/sequenced_index.hpp>
-#include <boost/multi_index/hashed_index.hpp>
-#include "core/scheduler.hpp"
-
-namespace nfd {
-
-/** \brief represents the Dead Nonce list
- *
- *  The Dead Nonce List is a global table that supplements PIT for loop detection.
- *  When a Nonce is erased (dead) from PIT entry, the Nonce and the Interest Name is added to
- *  Dead Nonce List, and kept for a duration in which most loops are expected to have occured.
- *
- *  To reduce memory usage, the Interest Name and Nonce are stored as a 64-bit hash.
- *  There could be false positives (non-looping Interest could be considered looping),
- *  but the probability is small, and the error is recoverable when consumer retransmits
- *  with a different Nonce.
- *
- *  To reduce memory usage, entries do not have associated timestamps. Instead,
- *  lifetime of entries is controlled by dynamically adjusting the capacity of the container.
- *  At fixed intervals, the MARK, an entry with a special value, is inserted into the container.
- *  The number of MARKs stored in the container reflects the lifetime of entries,
- *  because MARKs are inserted at fixed intervals.
- */
-class DeadNonceList : noncopyable
-{
-public:
-  /** \brief constructs the Dead Nonce List
-   *  \param lifetime duration of the expected lifetime of each nonce,
-   *         must be no less than MIN_LIFETIME.
-   *         This should be set to the duration in which most loops would have occured.
-   *         A loop cannot be detected if delay of the cycle is greater than lifetime.
-   *  \throw std::invalid_argument if lifetime is less than MIN_LIFETIME
-   */
-  explicit
-  DeadNonceList(const time::nanoseconds& lifetime = DEFAULT_LIFETIME);
-
-  ~DeadNonceList();
-
-  /** \brief determines if name+nonce exists
-   *  \return true if name+nonce exists
-   */
-  bool
-  has(const Name& name, uint32_t nonce) const;
-
-  /** \brief records name+nonce
-   */
-  void
-  add(const Name& name, uint32_t nonce);
-
-  /** \return number of stored Nonces
-   *  \note The return value does not contain non-Nonce entries in the index, if any.
-   */
-  size_t
-  size() const;
-
-  /** \return expected lifetime
-   */
-  const time::nanoseconds&
-  getLifetime() const;
-
-private: // Entry and Index
-  typedef uint64_t Entry;
-
-  static Entry
-  makeEntry(const Name& name, uint32_t nonce);
-
-  typedef boost::multi_index_container<
-    Entry,
-    boost::multi_index::indexed_by<
-      boost::multi_index::sequenced<>,
-      boost::multi_index::hashed_non_unique<
-        boost::multi_index::identity<Entry>
-      >
-    >
-  > Index;
-
-  typedef Index::nth_index<0>::type Queue;
-  typedef Index::nth_index<1>::type Hashtable;
-
-private: // actual lifetime estimation and capacity control
-  /** \return number of MARKs in the index
-   */
-  size_t
-  countMarks() const;
-
-  /** \brief add a MARK, then record number of MARKs in m_actualMarkCounts
-   */
-  void
-  mark();
-
-  /** \brief adjust capacity according to m_actualMarkCounts
-   *
-   *  If all counts are above EXPECTED_MARK_COUNT, reduce capacity to m_capacity * CAPACITY_DOWN.
-   *  If all counts are below EXPECTED_MARK_COUNT, increase capacity to m_capacity * CAPACITY_UP.
-   */
-  void
-  adjustCapacity();
-
-  /** \brief evict some entries if index is over capacity
-   */
-  void
-  evictEntries();
-
-public:
-  /// default entry lifetime
-  static const time::nanoseconds DEFAULT_LIFETIME;
-
-  /// minimum entry lifetime
-  static const time::nanoseconds MIN_LIFETIME;
-
-private:
-  time::nanoseconds m_lifetime;
-  Index m_index;
-  Queue& m_queue;
-  Hashtable& m_ht;
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE: // actual lifetime estimation and capacity control
-
-  // ---- current capacity and hard limits
-
-  /** \brief current capacity of index
-   *
-   *  The index size is maintained to be near this capacity.
-   *
-   *  The capacity is adjusted so that every Entry is expected to be kept for m_lifetime.
-   *  This is achieved by mark() and adjustCapacity().
-   */
-  size_t m_capacity;
-
-  static const size_t INITIAL_CAPACITY;
-
-  /** \brief minimum capacity
-   *
-   *  This is to ensure correct algorithm operations.
-   */
-  static const size_t MIN_CAPACITY;
-
-  /** \brief maximum capacity
-   *
-   *  This is to limit memory usage.
-   */
-  static const size_t MAX_CAPACITY;
-
-  // ---- actual entry lifetime estimation
-
-  /** \brief the MARK for capacity
-   *
-   *  The MARK doesn't have a distinct type.
-   *  Entry is a hash. The hash function should have non-invertible property,
-   *  so it's unlikely for a usual Entry to have collision with the MARK.
-   */
-  static const Entry MARK;
-
-  /** \brief expected number of MARKs in the index
-   */
-  static const size_t EXPECTED_MARK_COUNT;
-
-  /** \brief number of MARKs in the index after each MARK insertion
-   *
-   *  adjustCapacity uses this to determine whether and how to adjust capcity,
-   *  and then clears this list.
-   */
-  std::multiset<size_t> m_actualMarkCounts;
-
-  time::nanoseconds m_markInterval;
-
-  scheduler::EventId m_markEvent;
-
-  // ---- capacity adjustments
-
-  static const double CAPACITY_UP;
-
-  static const double CAPACITY_DOWN;
-
-  time::nanoseconds m_adjustCapacityInterval;
-
-  scheduler::EventId m_adjustCapacityEvent;
-
-  /** \brief maximum number of entries to evict at each operation if index is over capacity
-   */
-  static const size_t EVICT_LIMIT;
-};
-
-inline const time::nanoseconds&
-DeadNonceList::getLifetime() const
-{
-  return m_lifetime;
-}
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_DEAD_NONCE_LIST_HPP
diff --git a/NFD/daemon/table/fib-entry.cpp b/NFD/daemon/table/fib-entry.cpp
deleted file mode 100644
index b2ea76c..0000000
--- a/NFD/daemon/table/fib-entry.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "fib-entry.hpp"
-
-namespace nfd {
-namespace fib {
-
-Entry::Entry(const Name& prefix)
-  : m_prefix(prefix)
-{
-}
-
-NextHopList::iterator
-Entry::findNextHop(Face& face)
-{
-  return std::find_if(m_nextHops.begin(), m_nextHops.end(),
-                      [&face] (const NextHop& nexthop) {
-                        return nexthop.getFace().get() == &face;
-                      });
-}
-
-bool
-Entry::hasNextHop(shared_ptr<Face> face) const
-{
-  return const_cast<Entry*>(this)->findNextHop(*face) != m_nextHops.end();
-}
-
-void
-Entry::addNextHop(shared_ptr<Face> face, uint64_t cost)
-{
-  auto it = this->findNextHop(*face);
-  if (it == m_nextHops.end()) {
-    m_nextHops.push_back(fib::NextHop(face));
-    it = m_nextHops.end();
-    --it;
-  }
-  // now it refers to the NextHop for face
-
-  it->setCost(cost);
-
-  this->sortNextHops();
-}
-
-void
-Entry::removeNextHop(shared_ptr<Face> face)
-{
-  auto it = this->findNextHop(*face);
-  if (it != m_nextHops.end()) {
-    m_nextHops.erase(it);
-  }
-}
-
-void
-Entry::sortNextHops()
-{
-  std::sort(m_nextHops.begin(), m_nextHops.end(),
-            [] (const NextHop& a, const NextHop& b) { return a.getCost() < b.getCost(); });
-}
-
-
-} // namespace fib
-} // namespace nfd
diff --git a/NFD/daemon/table/fib-entry.hpp b/NFD/daemon/table/fib-entry.hpp
deleted file mode 100644
index 4a6116e..0000000
--- a/NFD/daemon/table/fib-entry.hpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_TABLE_FIB_ENTRY_HPP
-#define NFD_DAEMON_TABLE_FIB_ENTRY_HPP
-
-#include "fib-nexthop.hpp"
-
-namespace nfd {
-
-class NameTree;
-namespace name_tree {
-class Entry;
-}
-
-namespace fib {
-
-/** \class NextHopList
- *  \brief represents a collection of nexthops
- *
- *  This type has these methods as public API:
- *    iterator<NextHop> begin()
- *    iterator<NextHop> end()
- *    size_t size()
- */
-typedef std::vector<fib::NextHop> NextHopList;
-
-/** \class Entry
- *  \brief represents a FIB entry
- */
-class Entry : noncopyable
-{
-public:
-  explicit
-  Entry(const Name& prefix);
-
-  const Name&
-  getPrefix() const;
-
-  const NextHopList&
-  getNextHops() const;
-
-  /** \return whether this Entry has any NextHop record
-   */
-  bool
-  hasNextHops() const;
-
-  /** \return whether there is a NextHop record for face
-   *
-   *  \todo change parameter type to Face&
-   */
-  bool
-  hasNextHop(shared_ptr<Face> face) const;
-
-  /** \brief adds a NextHop record
-   *
-   *  If a NextHop record for face already exists, its cost is updated.
-   *  \note shared_ptr is passed by value because this function will take shared ownership
-   */
-  void
-  addNextHop(shared_ptr<Face> face, uint64_t cost);
-
-  /** \brief removes a NextHop record
-   *
-   *  If no NextHop record for face exists, do nothing.
-   *
-   *  \todo change parameter type to Face&
-   */
-  void
-  removeNextHop(shared_ptr<Face> face);
-
-private:
-  /** @note This method is non-const because normal iterator is needed by callers.
-   */
-  NextHopList::iterator
-  findNextHop(Face& face);
-
-  /// sorts the nexthop list
-  void
-  sortNextHops();
-
-private:
-  Name m_prefix;
-  NextHopList m_nextHops;
-
-  shared_ptr<name_tree::Entry> m_nameTreeEntry;
-  friend class nfd::NameTree;
-  friend class nfd::name_tree::Entry;
-};
-
-
-inline const Name&
-Entry::getPrefix() const
-{
-  return m_prefix;
-}
-
-inline const NextHopList&
-Entry::getNextHops() const
-{
-  return m_nextHops;
-}
-
-inline bool
-Entry::hasNextHops() const
-{
-  return !m_nextHops.empty();
-}
-
-} // namespace fib
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_FIB_ENTRY_HPP
diff --git a/NFD/daemon/table/fib-nexthop.cpp b/NFD/daemon/table/fib-nexthop.cpp
deleted file mode 100644
index 235fc79..0000000
--- a/NFD/daemon/table/fib-nexthop.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "fib-nexthop.hpp"
-
-namespace nfd {
-namespace fib {
-
-NextHop::NextHop(shared_ptr<Face> face)
-  : m_face(face)
-  , m_cost(0)
-{
-}
-
-const shared_ptr<Face>&
-NextHop::getFace() const
-{
-  return m_face;
-}
-
-void
-NextHop::setCost(uint64_t cost)
-{
-  m_cost = cost;
-}
-
-uint64_t
-NextHop::getCost() const
-{
-  return m_cost;
-}
-
-} // namespace fib
-} // namespace nfd
diff --git a/NFD/daemon/table/fib-nexthop.hpp b/NFD/daemon/table/fib-nexthop.hpp
deleted file mode 100644
index 9f7ed93..0000000
--- a/NFD/daemon/table/fib-nexthop.hpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_TABLE_FIB_NEXTHOP_HPP
-#define NFD_DAEMON_TABLE_FIB_NEXTHOP_HPP
-
-#include "common.hpp"
-#include "face/face.hpp"
-
-namespace nfd {
-namespace fib {
-
-/** \class NextHop
- *  \brief represents a nexthop record in FIB entry
- */
-class NextHop
-{
-public:
-  explicit
-  NextHop(shared_ptr<Face> face);
-
-  const shared_ptr<Face>&
-  getFace() const;
-
-  void
-  setCost(uint64_t cost);
-
-  uint64_t
-  getCost() const;
-
-private:
-  shared_ptr<Face> m_face;
-  uint64_t m_cost;
-};
-
-} // namespace fib
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_FIB_NEXTHOP_HPP
diff --git a/NFD/daemon/table/fib.cpp b/NFD/daemon/table/fib.cpp
deleted file mode 100644
index ee9e733..0000000
--- a/NFD/daemon/table/fib.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "fib.hpp"
-#include "pit-entry.hpp"
-#include "measurements-entry.hpp"
-
-#include <boost/concept/assert.hpp>
-#include <boost/concept_check.hpp>
-#include <type_traits>
-
-namespace nfd {
-
-const shared_ptr<fib::Entry> Fib::s_emptyEntry = make_shared<fib::Entry>(Name());
-
-// http://en.cppreference.com/w/cpp/concept/ForwardIterator
-BOOST_CONCEPT_ASSERT((boost::ForwardIterator<Fib::const_iterator>));
-// boost::ForwardIterator follows SGI standard http://www.sgi.com/tech/stl/ForwardIterator.html,
-// which doesn't require DefaultConstructible
-#ifdef HAVE_IS_DEFAULT_CONSTRUCTIBLE
-static_assert(std::is_default_constructible<Fib::const_iterator>::value,
-              "Fib::const_iterator must be default-constructible");
-#else
-BOOST_CONCEPT_ASSERT((boost::DefaultConstructible<Fib::const_iterator>));
-#endif // HAVE_IS_DEFAULT_CONSTRUCTIBLE
-
-Fib::Fib(NameTree& nameTree)
-  : m_nameTree(nameTree)
-  , m_nItems(0)
-{
-}
-
-Fib::~Fib()
-{
-}
-
-static inline bool
-predicate_NameTreeEntry_hasFibEntry(const name_tree::Entry& entry)
-{
-  return static_cast<bool>(entry.getFibEntry());
-}
-
-shared_ptr<fib::Entry>
-Fib::findLongestPrefixMatch(const Name& prefix) const
-{
-  shared_ptr<name_tree::Entry> nameTreeEntry =
-    m_nameTree.findLongestPrefixMatch(prefix, &predicate_NameTreeEntry_hasFibEntry);
-  if (static_cast<bool>(nameTreeEntry)) {
-    return nameTreeEntry->getFibEntry();
-  }
-  return s_emptyEntry;
-}
-
-shared_ptr<fib::Entry>
-Fib::findLongestPrefixMatch(shared_ptr<name_tree::Entry> nameTreeEntry) const
-{
-  shared_ptr<fib::Entry> entry = nameTreeEntry->getFibEntry();
-  if (static_cast<bool>(entry))
-    return entry;
-  nameTreeEntry = m_nameTree.findLongestPrefixMatch(nameTreeEntry,
-                                                    &predicate_NameTreeEntry_hasFibEntry);
-  if (static_cast<bool>(nameTreeEntry)) {
-    return nameTreeEntry->getFibEntry();
-  }
-  return s_emptyEntry;
-}
-
-shared_ptr<fib::Entry>
-Fib::findLongestPrefixMatch(const pit::Entry& pitEntry) const
-{
-  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.get(pitEntry);
-
-  BOOST_ASSERT(static_cast<bool>(nameTreeEntry));
-
-  return findLongestPrefixMatch(nameTreeEntry);
-}
-
-shared_ptr<fib::Entry>
-Fib::findLongestPrefixMatch(const measurements::Entry& measurementsEntry) const
-{
-  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.get(measurementsEntry);
-
-  BOOST_ASSERT(static_cast<bool>(nameTreeEntry));
-
-  return findLongestPrefixMatch(nameTreeEntry);
-}
-
-shared_ptr<fib::Entry>
-Fib::findExactMatch(const Name& prefix) const
-{
-  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.findExactMatch(prefix);
-  if (static_cast<bool>(nameTreeEntry))
-    return nameTreeEntry->getFibEntry();
-  return shared_ptr<fib::Entry>();
-}
-
-std::pair<shared_ptr<fib::Entry>, bool>
-Fib::insert(const Name& prefix)
-{
-  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.lookup(prefix);
-  shared_ptr<fib::Entry> entry = nameTreeEntry->getFibEntry();
-  if (static_cast<bool>(entry))
-    return std::make_pair(entry, false);
-  entry = make_shared<fib::Entry>(prefix);
-  nameTreeEntry->setFibEntry(entry);
-  ++m_nItems;
-  return std::make_pair(entry, true);
-}
-
-void
-Fib::erase(shared_ptr<name_tree::Entry> nameTreeEntry)
-{
-  nameTreeEntry->setFibEntry(shared_ptr<fib::Entry>());
-  m_nameTree.eraseEntryIfEmpty(nameTreeEntry);
-  --m_nItems;
-}
-
-void
-Fib::erase(const Name& prefix)
-{
-  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.findExactMatch(prefix);
-  if (static_cast<bool>(nameTreeEntry)) {
-    this->erase(nameTreeEntry);
-  }
-}
-
-void
-Fib::erase(const fib::Entry& entry)
-{
-  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.get(entry);
-  if (static_cast<bool>(nameTreeEntry)) {
-    this->erase(nameTreeEntry);
-  }
-}
-
-void
-Fib::removeNextHopFromAllEntries(shared_ptr<Face> face)
-{
-  std::list<fib::Entry*> toErase;
-
-  auto&& enumerable = m_nameTree.fullEnumerate(&predicate_NameTreeEntry_hasFibEntry);
-  for (const name_tree::Entry& nte : enumerable) {
-    shared_ptr<fib::Entry> entry = nte.getFibEntry();
-    entry->removeNextHop(face);
-    if (!entry->hasNextHops()) {
-      toErase.push_back(entry.get());
-      // entry needs to be erased, but we must wait until the enumeration ends,
-      // because otherwise NameTree iterator would be invalidated
-    }
-  }
-
-  for (fib::Entry* entry : toErase) {
-    this->erase(*entry);
-  }
-}
-
-Fib::const_iterator
-Fib::begin() const
-{
-  return const_iterator(m_nameTree.fullEnumerate(&predicate_NameTreeEntry_hasFibEntry).begin());
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/table/fib.hpp b/NFD/daemon/table/fib.hpp
deleted file mode 100644
index 34a2009..0000000
--- a/NFD/daemon/table/fib.hpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_TABLE_FIB_HPP
-#define NFD_DAEMON_TABLE_FIB_HPP
-
-#include "fib-entry.hpp"
-#include "name-tree.hpp"
-
-namespace nfd {
-
-namespace measurements {
-class Entry;
-}
-namespace pit {
-class Entry;
-}
-
-/** \class Fib
- *  \brief represents the FIB
- */
-class Fib : noncopyable
-{
-public:
-  explicit
-  Fib(NameTree& nameTree);
-
-  ~Fib();
-
-  size_t
-  size() const;
-
-public: // lookup
-  /// performs a longest prefix match
-  shared_ptr<fib::Entry>
-  findLongestPrefixMatch(const Name& prefix) const;
-
-  /// performs a longest prefix match
-  shared_ptr<fib::Entry>
-  findLongestPrefixMatch(const pit::Entry& pitEntry) const;
-
-  /// performs a longest prefix match
-  shared_ptr<fib::Entry>
-  findLongestPrefixMatch(const measurements::Entry& measurementsEntry) const;
-
-  shared_ptr<fib::Entry>
-  findExactMatch(const Name& prefix) const;
-
-public: // mutation
-  /** \brief inserts a FIB entry for prefix
-   *  If an entry for exact same prefix exists, that entry is returned.
-   *  \return{ the entry, and true for new entry, false for existing entry }
-   */
-  std::pair<shared_ptr<fib::Entry>, bool>
-  insert(const Name& prefix);
-
-  void
-  erase(const Name& prefix);
-
-  void
-  erase(const fib::Entry& entry);
-
-  /** \brief removes the NextHop record for face in all entrites
-   *
-   *  This is usually invoked when face goes away.
-   *  Removing the last NextHop in a FIB entry will erase the FIB entry.
-   *
-   *  \todo change parameter type to Face&
-   */
-  void
-  removeNextHopFromAllEntries(shared_ptr<Face> face);
-
-public: // enumeration
-  class const_iterator;
-
-  /** \brief returns an iterator pointing to the first FIB entry
-   *  \note Iteration order is implementation-specific and is undefined
-   *  \note The returned iterator may get invalidated if FIB or another NameTree-based
-   *        table is modified
-   */
-  const_iterator
-  begin() const;
-
-  /** \brief returns an iterator referring to the past-the-end FIB entry
-   *  \note The returned iterator may get invalidated if FIB or another NameTree-based
-   *        table is modified
-   */
-  const_iterator
-  end() const;
-
-  class const_iterator : public std::iterator<std::forward_iterator_tag, const fib::Entry>
-  {
-  public:
-    const_iterator() = default;
-
-    explicit
-    const_iterator(const NameTree::const_iterator& it);
-
-    ~const_iterator();
-
-    const fib::Entry&
-    operator*() const;
-
-    shared_ptr<fib::Entry>
-    operator->() const;
-
-    const_iterator&
-    operator++();
-
-    const_iterator
-    operator++(int);
-
-    bool
-    operator==(const const_iterator& other) const;
-
-    bool
-    operator!=(const const_iterator& other) const;
-
-  private:
-    NameTree::const_iterator m_nameTreeIterator;
-  };
-
-private:
-  shared_ptr<fib::Entry>
-  findLongestPrefixMatch(shared_ptr<name_tree::Entry> nameTreeEntry) const;
-
-  void
-  erase(shared_ptr<name_tree::Entry> nameTreeEntry);
-
-private:
-  NameTree& m_nameTree;
-  size_t m_nItems;
-
-  /** \brief The empty FIB entry.
-   *
-   *  This entry has no nexthops.
-   *  It is returned by findLongestPrefixMatch if nothing is matched.
-   *  Returning empty entry instead of nullptr makes forwarding and strategy implementation easier.
-   */
-  static const shared_ptr<fib::Entry> s_emptyEntry;
-};
-
-inline size_t
-Fib::size() const
-{
-  return m_nItems;
-}
-
-inline Fib::const_iterator
-Fib::end() const
-{
-  return const_iterator(m_nameTree.end());
-}
-
-inline
-Fib::const_iterator::const_iterator(const NameTree::const_iterator& it)
-  : m_nameTreeIterator(it)
-{
-}
-
-inline
-Fib::const_iterator::~const_iterator()
-{
-}
-
-inline
-Fib::const_iterator
-Fib::const_iterator::operator++(int)
-{
-  Fib::const_iterator temp(*this);
-  ++(*this);
-  return temp;
-}
-
-inline Fib::const_iterator&
-Fib::const_iterator::operator++()
-{
-  ++m_nameTreeIterator;
-  return *this;
-}
-
-inline const fib::Entry&
-Fib::const_iterator::operator*() const
-{
-  return *this->operator->();
-}
-
-inline shared_ptr<fib::Entry>
-Fib::const_iterator::operator->() const
-{
-  return m_nameTreeIterator->getFibEntry();
-}
-
-inline bool
-Fib::const_iterator::operator==(const Fib::const_iterator& other) const
-{
-  return m_nameTreeIterator == other.m_nameTreeIterator;
-}
-
-inline bool
-Fib::const_iterator::operator!=(const Fib::const_iterator& other) const
-{
-  return m_nameTreeIterator != other.m_nameTreeIterator;
-}
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_FIB_HPP
diff --git a/NFD/daemon/table/measurements-accessor.cpp b/NFD/daemon/table/measurements-accessor.cpp
deleted file mode 100644
index 81b1432..0000000
--- a/NFD/daemon/table/measurements-accessor.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "measurements-accessor.hpp"
-
-namespace nfd {
-
-using fw::Strategy;
-
-MeasurementsAccessor::MeasurementsAccessor(Measurements& measurements,
-                                           StrategyChoice& strategyChoice,
-                                           Strategy* strategy)
-  : m_measurements(measurements)
-  , m_strategyChoice(strategyChoice)
-  , m_strategy(strategy)
-{
-}
-
-MeasurementsAccessor::~MeasurementsAccessor()
-{
-}
-
-shared_ptr<measurements::Entry>
-MeasurementsAccessor::filter(const shared_ptr<measurements::Entry>& entry)
-{
-  if (!static_cast<bool>(entry)) {
-    return entry;
-  }
-
-  Strategy& effectiveStrategy = m_strategyChoice.findEffectiveStrategy(*entry);
-  if (&effectiveStrategy == m_strategy) {
-    return entry;
-  }
-  return shared_ptr<measurements::Entry>();
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/table/measurements-accessor.hpp b/NFD/daemon/table/measurements-accessor.hpp
deleted file mode 100644
index 872cff2..0000000
--- a/NFD/daemon/table/measurements-accessor.hpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_TABLE_MEASUREMENTS_ACCESSOR_HPP
-#define NFD_DAEMON_TABLE_MEASUREMENTS_ACCESSOR_HPP
-
-#include "measurements.hpp"
-#include "strategy-choice.hpp"
-
-namespace nfd {
-
-namespace fw {
-class Strategy;
-}
-
-/** \brief allows Strategy to access portion of Measurements table under its namespace
- */
-class MeasurementsAccessor : noncopyable
-{
-public:
-  MeasurementsAccessor(Measurements& measurements, StrategyChoice& strategyChoice,
-                       fw::Strategy* strategy);
-
-  ~MeasurementsAccessor();
-
-  /** \brief find or insert a Measurements entry for name
-   */
-  shared_ptr<measurements::Entry>
-  get(const Name& name);
-
-  /** \brief find or insert a Measurements entry for fibEntry->getPrefix()
-   */
-  shared_ptr<measurements::Entry>
-  get(const fib::Entry& fibEntry);
-
-  /** \brief find or insert a Measurements entry for pitEntry->getName()
-   */
-  shared_ptr<measurements::Entry>
-  get(const pit::Entry& pitEntry);
-
-  /** \brief find or insert a Measurements entry for child's parent
-   *  \retval nullptr if child is the root entry
-   */
-  shared_ptr<measurements::Entry>
-  getParent(const measurements::Entry& child);
-
-  /** \brief extend lifetime of an entry
-   *
-   *  The entry will be kept until at least now()+lifetime.
-   */
-  void
-  extendLifetime(measurements::Entry& entry, const time::nanoseconds& lifetime);
-
-private:
-  /** \brief perform access control to Measurements entry
-   *  \return entry if strategy has access to namespace, otherwise nullptr
-   */
-  shared_ptr<measurements::Entry>
-  filter(const shared_ptr<measurements::Entry>& entry);
-
-private:
-  Measurements& m_measurements;
-  StrategyChoice& m_strategyChoice;
-  fw::Strategy* m_strategy;
-};
-
-inline shared_ptr<measurements::Entry>
-MeasurementsAccessor::get(const Name& name)
-{
-  return this->filter(m_measurements.get(name));
-}
-
-inline shared_ptr<measurements::Entry>
-MeasurementsAccessor::get(const fib::Entry& fibEntry)
-{
-  return this->filter(m_measurements.get(fibEntry));
-}
-
-inline shared_ptr<measurements::Entry>
-MeasurementsAccessor::get(const pit::Entry& pitEntry)
-{
-  return this->filter(m_measurements.get(pitEntry));
-}
-
-inline shared_ptr<measurements::Entry>
-MeasurementsAccessor::getParent(const measurements::Entry& child)
-{
-  return this->filter(m_measurements.getParent(child));
-}
-
-inline void
-MeasurementsAccessor::extendLifetime(measurements::Entry& entry,
-                                     const time::nanoseconds& lifetime)
-{
-  m_measurements.extendLifetime(entry, lifetime);
-}
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_MEASUREMENTS_ACCESSOR_HPP
diff --git a/NFD/daemon/table/measurements-entry.cpp b/NFD/daemon/table/measurements-entry.cpp
deleted file mode 100644
index 6858399..0000000
--- a/NFD/daemon/table/measurements-entry.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "measurements-entry.hpp"
-
-namespace nfd {
-namespace measurements {
-
-Entry::Entry(const Name& name)
-  : m_name(name)
-  , m_expiry(time::steady_clock::TimePoint::min())
-{
-}
-
-} // namespace measurements
-} // namespace nfd
diff --git a/NFD/daemon/table/measurements-entry.hpp b/NFD/daemon/table/measurements-entry.hpp
deleted file mode 100644
index 6593ee9..0000000
--- a/NFD/daemon/table/measurements-entry.hpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#ifndef NFD_DAEMON_TABLE_MEASUREMENTS_ENTRY_HPP
-#define NFD_DAEMON_TABLE_MEASUREMENTS_ENTRY_HPP
-
-#include "common.hpp"
-#include "strategy-info-host.hpp"
-#include "core/scheduler.hpp"
-
-namespace nfd {
-
-class NameTree;
-
-namespace name_tree {
-class Entry;
-}
-
-class Measurements;
-
-namespace measurements {
-
-/** \class Entry
- *  \brief represents a Measurements entry
- */
-class Entry : public StrategyInfoHost, noncopyable
-{
-public:
-  explicit
-  Entry(const Name& name);
-
-  const Name&
-  getName() const;
-
-private:
-  Name m_name;
-
-private: // lifetime
-  time::steady_clock::TimePoint m_expiry;
-  EventId m_cleanup;
-  shared_ptr<name_tree::Entry> m_nameTreeEntry;
-
-  friend class nfd::NameTree;
-  friend class nfd::name_tree::Entry;
-  friend class nfd::Measurements;
-};
-
-inline const Name&
-Entry::getName() const
-{
-  return m_name;
-}
-
-} // namespace measurements
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_MEASUREMENTS_ENTRY_HPP
diff --git a/NFD/daemon/table/measurements.cpp b/NFD/daemon/table/measurements.cpp
deleted file mode 100644
index 8a24306..0000000
--- a/NFD/daemon/table/measurements.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "measurements.hpp"
-#include "name-tree.hpp"
-#include "pit-entry.hpp"
-#include "fib-entry.hpp"
-
-namespace nfd {
-
-Measurements::Measurements(NameTree& nameTree)
-  : m_nameTree(nameTree)
-  , m_nItems(0)
-{
-}
-
-shared_ptr<measurements::Entry>
-Measurements::get(name_tree::Entry& nte)
-{
-  shared_ptr<measurements::Entry> entry = nte.getMeasurementsEntry();
-  if (entry != nullptr)
-    return entry;
-
-  entry = make_shared<measurements::Entry>(nte.getPrefix());
-  nte.setMeasurementsEntry(entry);
-  ++m_nItems;
-
-  entry->m_expiry = time::steady_clock::now() + getInitialLifetime();
-  entry->m_cleanup = scheduler::schedule(getInitialLifetime(),
-                                         bind(&Measurements::cleanup, this, ref(*entry)));
-
-  return entry;
-}
-
-shared_ptr<measurements::Entry>
-Measurements::get(const Name& name)
-{
-  shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(name);
-  return this->get(*nte);
-}
-
-shared_ptr<measurements::Entry>
-Measurements::get(const fib::Entry& fibEntry)
-{
-  shared_ptr<name_tree::Entry> nte = m_nameTree.get(fibEntry);
-  return this->get(*nte);
-}
-
-shared_ptr<measurements::Entry>
-Measurements::get(const pit::Entry& pitEntry)
-{
-  shared_ptr<name_tree::Entry> nte = m_nameTree.get(pitEntry);
-  return this->get(*nte);
-}
-
-shared_ptr<measurements::Entry>
-Measurements::getParent(const measurements::Entry& child)
-{
-  if (child.getName().size() == 0) { // the root entry
-    return nullptr;
-  }
-
-  shared_ptr<name_tree::Entry> nteChild = m_nameTree.get(child);
-  shared_ptr<name_tree::Entry> nte = nteChild->getParent();
-  BOOST_ASSERT(nte != nullptr);
-  return this->get(*nte);
-}
-
-shared_ptr<measurements::Entry>
-Measurements::findLongestPrefixMatch(const Name& name) const
-{
-  shared_ptr<name_tree::Entry> nte = m_nameTree.findLongestPrefixMatch(name,
-      [] (const name_tree::Entry& nte) { return nte.getMeasurementsEntry() != nullptr; });
-  if (nte != nullptr) {
-    return nte->getMeasurementsEntry();
-  }
-  return nullptr;
-}
-
-shared_ptr<measurements::Entry>
-Measurements::findExactMatch(const Name& name) const
-{
-  shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(name);
-  if (nte != nullptr)
-    return nte->getMeasurementsEntry();
-  return nullptr;
-}
-
-void
-Measurements::extendLifetime(measurements::Entry& entry,
-                             const time::nanoseconds& lifetime)
-{
-  shared_ptr<name_tree::Entry> nte = m_nameTree.get(entry);
-  if (nte == nullptr ||
-      nte->getMeasurementsEntry().get() != &entry) {
-    // entry is already gone; it is a dangling reference
-    return;
-  }
-
-  time::steady_clock::TimePoint expiry = time::steady_clock::now() + lifetime;
-  if (entry.m_expiry >= expiry) {
-    // has longer lifetime, not extending
-    return;
-  }
-
-  scheduler::cancel(entry.m_cleanup);
-  entry.m_expiry = expiry;
-  entry.m_cleanup = scheduler::schedule(lifetime, bind(&Measurements::cleanup, this, ref(entry)));
-}
-
-void
-Measurements::cleanup(measurements::Entry& entry)
-{
-  shared_ptr<name_tree::Entry> nte = m_nameTree.get(entry);
-  if (nte != nullptr) {
-    nte->setMeasurementsEntry(nullptr);
-    m_nameTree.eraseEntryIfEmpty(nte);
-    m_nItems--;
-  }
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/table/measurements.hpp b/NFD/daemon/table/measurements.hpp
deleted file mode 100644
index 71d8db5..0000000
--- a/NFD/daemon/table/measurements.hpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_TABLE_MEASUREMENTS_HPP
-#define NFD_DAEMON_TABLE_MEASUREMENTS_HPP
-
-#include "measurements-entry.hpp"
-#include "name-tree.hpp"
-
-namespace nfd {
-
-namespace fib {
-class Entry;
-}
-
-namespace pit {
-class Entry;
-}
-
-
-/** \class Measurement
- *  \brief represents the Measurements table
- */
-class Measurements : noncopyable
-{
-public:
-  explicit
-  Measurements(NameTree& nametree);
-
-  /** \brief find or insert a Measurements entry for name
-   */
-  shared_ptr<measurements::Entry>
-  get(const Name& name);
-
-  /** \brief find or insert a Measurements entry for fibEntry->getPrefix()
-   */
-  shared_ptr<measurements::Entry>
-  get(const fib::Entry& fibEntry);
-
-  /** \brief find or insert a Measurements entry for pitEntry->getName()
-   */
-  shared_ptr<measurements::Entry>
-  get(const pit::Entry& pitEntry);
-
-  /** \brief find or insert a Measurements entry for child's parent
-   *  \retval nullptr if child is the root entry
-   */
-  shared_ptr<measurements::Entry>
-  getParent(const measurements::Entry& child);
-
-  /** \brief perform a longest prefix match
-   */
-  shared_ptr<measurements::Entry>
-  findLongestPrefixMatch(const Name& name) const;
-
-  /** \brief perform an exact match
-   */
-  shared_ptr<measurements::Entry>
-  findExactMatch(const Name& name) const;
-
-  static time::nanoseconds
-  getInitialLifetime();
-
-  /** \brief extend lifetime of an entry
-   *
-   *  The entry will be kept until at least now()+lifetime.
-   */
-  void
-  extendLifetime(measurements::Entry& entry, const time::nanoseconds& lifetime);
-
-  size_t
-  size() const;
-
-private:
-  void
-  cleanup(measurements::Entry& entry);
-
-  shared_ptr<measurements::Entry>
-  get(name_tree::Entry& nte);
-
-private:
-  NameTree& m_nameTree;
-  size_t m_nItems;
-  static const time::nanoseconds s_defaultLifetime;
-};
-
-inline time::nanoseconds
-Measurements::getInitialLifetime()
-{
-  return time::seconds(4);
-}
-
-inline size_t
-Measurements::size() const
-{
-  return m_nItems;
-}
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_MEASUREMENTS_HPP
diff --git a/NFD/daemon/table/name-tree-entry.cpp b/NFD/daemon/table/name-tree-entry.cpp
deleted file mode 100644
index 017dbfe..0000000
--- a/NFD/daemon/table/name-tree-entry.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "name-tree-entry.hpp"
-
-namespace nfd {
-namespace name_tree {
-
-Node::Node()
-  : m_prev(0)
-  , m_next(0)
-{
-}
-
-Node::~Node()
-{
-  // erase the Name Tree Nodes that were created to
-  // resolve hash collisions
-  // So before erasing a single node, make sure its m_next == 0
-  // See eraseEntryIfEmpty in name-tree.cpp
-  if (m_next != 0)
-    delete m_next;
-}
-
-Entry::Entry(const Name& name)
-  : m_hash(0)
-  , m_prefix(name)
-{
-}
-
-Entry::~Entry()
-{
-}
-
-bool
-Entry::isEmpty() const
-{
-  return m_children.empty() &&
-         !static_cast<bool>(m_fibEntry) &&
-         m_pitEntries.empty() &&
-         !static_cast<bool>(m_measurementsEntry) &&
-         !static_cast<bool>(m_strategyChoiceEntry);
-}
-
-void
-Entry::setFibEntry(shared_ptr<fib::Entry> fibEntry)
-{
-  if (static_cast<bool>(fibEntry)) {
-    BOOST_ASSERT(!static_cast<bool>(fibEntry->m_nameTreeEntry));
-  }
-
-  if (static_cast<bool>(m_fibEntry)) {
-    m_fibEntry->m_nameTreeEntry.reset();
-  }
-  m_fibEntry = fibEntry;
-  if (static_cast<bool>(m_fibEntry)) {
-    m_fibEntry->m_nameTreeEntry = this->shared_from_this();
-  }
-}
-
-void
-Entry::insertPitEntry(shared_ptr<pit::Entry> pitEntry)
-{
-  BOOST_ASSERT(static_cast<bool>(pitEntry));
-  BOOST_ASSERT(!static_cast<bool>(pitEntry->m_nameTreeEntry));
-
-  m_pitEntries.push_back(pitEntry);
-  pitEntry->m_nameTreeEntry = this->shared_from_this();
-}
-
-void
-Entry::erasePitEntry(shared_ptr<pit::Entry> pitEntry)
-{
-  BOOST_ASSERT(static_cast<bool>(pitEntry));
-  BOOST_ASSERT(pitEntry->m_nameTreeEntry.get() == this);
-
-  std::vector<shared_ptr<pit::Entry> >::iterator it =
-    std::find(m_pitEntries.begin(), m_pitEntries.end(), pitEntry);
-  BOOST_ASSERT(it != m_pitEntries.end());
-
-  *it = m_pitEntries.back();
-  m_pitEntries.pop_back();
-  pitEntry->m_nameTreeEntry.reset();
-}
-
-void
-Entry::setMeasurementsEntry(shared_ptr<measurements::Entry> measurementsEntry)
-{
-  if (static_cast<bool>(measurementsEntry)) {
-    BOOST_ASSERT(!static_cast<bool>(measurementsEntry->m_nameTreeEntry));
-  }
-
-  if (static_cast<bool>(m_measurementsEntry)) {
-    m_measurementsEntry->m_nameTreeEntry.reset();
-  }
-  m_measurementsEntry = measurementsEntry;
-  if (static_cast<bool>(m_measurementsEntry)) {
-    m_measurementsEntry->m_nameTreeEntry = this->shared_from_this();
-  }
-}
-
-void
-Entry::setStrategyChoiceEntry(shared_ptr<strategy_choice::Entry> strategyChoiceEntry)
-{
-  if (static_cast<bool>(strategyChoiceEntry)) {
-    BOOST_ASSERT(!static_cast<bool>(strategyChoiceEntry->m_nameTreeEntry));
-  }
-
-  if (static_cast<bool>(m_strategyChoiceEntry)) {
-    m_strategyChoiceEntry->m_nameTreeEntry.reset();
-  }
-  m_strategyChoiceEntry = strategyChoiceEntry;
-  if (static_cast<bool>(m_strategyChoiceEntry)) {
-    m_strategyChoiceEntry->m_nameTreeEntry = this->shared_from_this();
-  }
-}
-
-} // namespace name_tree
-} // namespace nfd
diff --git a/NFD/daemon/table/name-tree-entry.hpp b/NFD/daemon/table/name-tree-entry.hpp
deleted file mode 100644
index d0e3587..0000000
--- a/NFD/daemon/table/name-tree-entry.hpp
+++ /dev/null
@@ -1,223 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_TABLE_NAME_TREE_ENTRY_HPP
-#define NFD_DAEMON_TABLE_NAME_TREE_ENTRY_HPP
-
-#include "common.hpp"
-#include "table/fib-entry.hpp"
-#include "table/pit-entry.hpp"
-#include "table/measurements-entry.hpp"
-#include "table/strategy-choice-entry.hpp"
-
-namespace nfd {
-
-class NameTree;
-
-namespace name_tree {
-
-// Forward declarations
-class Node;
-class Entry;
-
-/**
- * \brief Name Tree Node Class
- */
-class Node
-{
-public:
-  Node();
-
-  ~Node();
-
-public:
-  // variables are in public as this is just a data structure
-  shared_ptr<Entry> m_entry; // Name Tree Entry (i.e., Name Prefix Entry)
-  Node* m_prev; // Previous Name Tree Node (to resolve hash collision)
-  Node* m_next; // Next Name Tree Node (to resolve hash collision)
-};
-
-/**
- * \brief Name Tree Entry Class
- */
-class Entry : public enable_shared_from_this<Entry>, noncopyable
-{
-public:
-  explicit
-  Entry(const Name& prefix);
-
-  ~Entry();
-
-  const Name&
-  getPrefix() const;
-
-  void
-  setHash(size_t hash);
-
-  size_t
-  getHash() const;
-
-  void
-  setParent(shared_ptr<Entry> parent);
-
-  shared_ptr<Entry>
-  getParent() const;
-
-  std::vector<shared_ptr<Entry> >&
-  getChildren();
-
-  bool
-  hasChildren() const;
-
-  bool
-  isEmpty() const;
-
-public: // attached table entries
-  void
-  setFibEntry(shared_ptr<fib::Entry> fibEntry);
-
-  shared_ptr<fib::Entry>
-  getFibEntry() const;
-
-  void
-  insertPitEntry(shared_ptr<pit::Entry> pitEntry);
-
-  void
-  erasePitEntry(shared_ptr<pit::Entry> pitEntry);
-
-  bool
-  hasPitEntries() const;
-
-  const std::vector<shared_ptr<pit::Entry> >&
-  getPitEntries() const;
-
-  void
-  setMeasurementsEntry(shared_ptr<measurements::Entry> measurementsEntry);
-
-  shared_ptr<measurements::Entry>
-  getMeasurementsEntry() const;
-
-  void
-  setStrategyChoiceEntry(shared_ptr<strategy_choice::Entry> strategyChoiceEntry);
-
-  shared_ptr<strategy_choice::Entry>
-  getStrategyChoiceEntry() const;
-
-private:
-  // Benefits of storing m_hash
-  // 1. m_hash is compared before m_prefix is compared
-  // 2. fast hash table resize support
-  size_t m_hash;
-  Name m_prefix;
-  shared_ptr<Entry> m_parent;     // Pointing to the parent entry.
-  std::vector<shared_ptr<Entry> > m_children; // Children pointers.
-  shared_ptr<fib::Entry> m_fibEntry;
-  std::vector<shared_ptr<pit::Entry> > m_pitEntries;
-  shared_ptr<measurements::Entry> m_measurementsEntry;
-  shared_ptr<strategy_choice::Entry> m_strategyChoiceEntry;
-
-  // get the Name Tree Node that is associated with this Name Tree Entry
-  Node* m_node;
-
-  // Make private members accessible by Name Tree
-  friend class nfd::NameTree;
-};
-
-inline const Name&
-Entry::getPrefix() const
-{
-  return m_prefix;
-}
-
-inline size_t
-Entry::getHash() const
-{
-  return m_hash;
-}
-
-inline void
-Entry::setHash(size_t hash)
-{
-  m_hash = hash;
-}
-
-inline shared_ptr<Entry>
-Entry::getParent() const
-{
-  return m_parent;
-}
-
-inline void
-Entry::setParent(shared_ptr<Entry> parent)
-{
-  m_parent = parent;
-}
-
-inline std::vector<shared_ptr<name_tree::Entry> >&
-Entry::getChildren()
-{
-  return m_children;
-}
-
-inline bool
-Entry::hasChildren() const
-{
-  return !m_children.empty();
-}
-
-inline shared_ptr<fib::Entry>
-Entry::getFibEntry() const
-{
-  return m_fibEntry;
-}
-
-inline bool
-Entry::hasPitEntries() const
-{
-  return !m_pitEntries.empty();
-}
-
-inline const std::vector<shared_ptr<pit::Entry> >&
-Entry::getPitEntries() const
-{
-  return m_pitEntries;
-}
-
-inline shared_ptr<measurements::Entry>
-Entry::getMeasurementsEntry() const
-{
-  return m_measurementsEntry;
-}
-
-inline shared_ptr<strategy_choice::Entry>
-Entry::getStrategyChoiceEntry() const
-{
-  return m_strategyChoiceEntry;
-}
-
-} // namespace name_tree
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_NAME_TREE_ENTRY_HPP
diff --git a/NFD/daemon/table/name-tree.cpp b/NFD/daemon/table/name-tree.cpp
deleted file mode 100644
index 3ac469d..0000000
--- a/NFD/daemon/table/name-tree.cpp
+++ /dev/null
@@ -1,776 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "name-tree.hpp"
-#include "core/logger.hpp"
-#include "core/city-hash.hpp"
-
-#include <boost/concept/assert.hpp>
-#include <boost/concept_check.hpp>
-#include <type_traits>
-
-namespace nfd {
-
-NFD_LOG_INIT("NameTree");
-
-// http://en.cppreference.com/w/cpp/concept/ForwardIterator
-BOOST_CONCEPT_ASSERT((boost::ForwardIterator<NameTree::const_iterator>));
-// boost::ForwardIterator follows SGI standard http://www.sgi.com/tech/stl/ForwardIterator.html,
-// which doesn't require DefaultConstructible
-#ifdef HAVE_IS_DEFAULT_CONSTRUCTIBLE
-static_assert(std::is_default_constructible<NameTree::const_iterator>::value,
-              "NameTree::const_iterator must be default-constructible");
-#else
-BOOST_CONCEPT_ASSERT((boost::DefaultConstructible<NameTree::const_iterator>));
-#endif // HAVE_IS_DEFAULT_CONSTRUCTIBLE
-
-namespace name_tree {
-
-class Hash32
-{
-public:
-  static size_t
-  compute(const char* buffer, size_t length)
-  {
-    return static_cast<size_t>(CityHash32(buffer, length));
-  }
-};
-
-class Hash64
-{
-public:
-  static size_t
-  compute(const char* buffer, size_t length)
-  {
-    return static_cast<size_t>(CityHash64(buffer, length));
-  }
-};
-
-typedef boost::mpl::if_c<sizeof(size_t) >= 8, Hash64, Hash32>::type CityHash;
-
-// Interface of different hash functions
-size_t
-computeHash(const Name& prefix)
-{
-  prefix.wireEncode();  // guarantees prefix's wire buffer is not empty
-
-  size_t hashValue = 0;
-  size_t hashUpdate = 0;
-
-  for (Name::const_iterator it = prefix.begin(); it != prefix.end(); it++)
-    {
-      const char* wireFormat = reinterpret_cast<const char*>( it->wire() );
-      hashUpdate = CityHash::compute(wireFormat, it->size());
-      hashValue ^= hashUpdate;
-    }
-
-  return hashValue;
-}
-
-std::vector<size_t>
-computeHashSet(const Name& prefix)
-{
-  prefix.wireEncode();  // guarantees prefix's wire buffer is not empty
-
-  size_t hashValue = 0;
-  size_t hashUpdate = 0;
-
-  std::vector<size_t> hashValueSet;
-  hashValueSet.push_back(hashValue);
-
-  for (Name::const_iterator it = prefix.begin(); it != prefix.end(); it++)
-    {
-      const char* wireFormat = reinterpret_cast<const char*>( it->wire() );
-      hashUpdate = CityHash::compute(wireFormat, it->size());
-      hashValue ^= hashUpdate;
-      hashValueSet.push_back(hashValue);
-    }
-
-  return hashValueSet;
-}
-
-} // namespace name_tree
-
-NameTree::NameTree(size_t nBuckets)
-  : m_nItems(0)
-  , m_nBuckets(nBuckets)
-  , m_minNBuckets(nBuckets)
-  , m_enlargeLoadFactor(0.5)       // more than 50% buckets loaded
-  , m_enlargeFactor(2)       // double the hash table size
-  , m_shrinkLoadFactor(0.1) // less than 10% buckets loaded
-  , m_shrinkFactor(0.5)     // reduce the number of buckets by half
-  , m_endIterator(FULL_ENUMERATE_TYPE, *this, m_end)
-{
-  m_enlargeThreshold = static_cast<size_t>(m_enlargeLoadFactor *
-                                          static_cast<double>(m_nBuckets));
-
-  m_shrinkThreshold = static_cast<size_t>(m_shrinkLoadFactor *
-                                          static_cast<double>(m_nBuckets));
-
-  // array of node pointers
-  m_buckets = new name_tree::Node*[m_nBuckets];
-  // Initialize the pointer array
-  for (size_t i = 0; i < m_nBuckets; i++)
-    m_buckets[i] = 0;
-}
-
-NameTree::~NameTree()
-{
-  for (size_t i = 0; i < m_nBuckets; i++)
-    {
-      if (m_buckets[i] != 0) {
-        delete m_buckets[i];
-      }
-    }
-
-  delete [] m_buckets;
-}
-
-// insert() is a private function, and called by only lookup()
-std::pair<shared_ptr<name_tree::Entry>, bool>
-NameTree::insert(const Name& prefix)
-{
-  NFD_LOG_TRACE("insert " << prefix);
-
-  size_t hashValue = name_tree::computeHash(prefix);
-  size_t loc = hashValue % m_nBuckets;
-
-  NFD_LOG_TRACE("Name " << prefix << " hash value = " << hashValue << "  location = " << loc);
-
-  // Check if this Name has been stored
-  name_tree::Node* node = m_buckets[loc];
-  name_tree::Node* nodePrev = node;  // initialize nodePrev to node
-
-  for (node = m_buckets[loc]; node != 0; node = node->m_next)
-    {
-      if (static_cast<bool>(node->m_entry))
-        {
-          if (prefix == node->m_entry->m_prefix)
-            {
-              return std::make_pair(node->m_entry, false); // false: old entry
-            }
-        }
-      nodePrev = node;
-    }
-
-  NFD_LOG_TRACE("Did not find " << prefix << ", need to insert it to the table");
-
-  // If no bucket is empty occupied, we need to create a new node, and it is
-  // linked from nodePrev
-  node = new name_tree::Node();
-  node->m_prev = nodePrev;
-
-  if (nodePrev == 0)
-    {
-      m_buckets[loc] = node;
-    }
-  else
-    {
-      nodePrev->m_next = node;
-    }
-
-  // Create a new Entry
-  shared_ptr<name_tree::Entry> entry(make_shared<name_tree::Entry>(prefix));
-  entry->setHash(hashValue);
-  node->m_entry = entry; // link the Entry to its Node
-  entry->m_node = node; // link the node to Entry. Used in eraseEntryIfEmpty.
-
-  return std::make_pair(entry, true); // true: new entry
-}
-
-// Name Prefix Lookup. Create Name Tree Entry if not found
-shared_ptr<name_tree::Entry>
-NameTree::lookup(const Name& prefix)
-{
-  NFD_LOG_TRACE("lookup " << prefix);
-
-  shared_ptr<name_tree::Entry> entry;
-  shared_ptr<name_tree::Entry> parent;
-
-  for (size_t i = 0; i <= prefix.size(); i++)
-    {
-      Name temp = prefix.getPrefix(i);
-
-      // insert() will create the entry if it does not exist.
-      std::pair<shared_ptr<name_tree::Entry>, bool> ret = insert(temp);
-      entry = ret.first;
-
-      if (ret.second == true)
-        {
-          m_nItems++; // Increase the counter
-          entry->m_parent = parent;
-
-          if (static_cast<bool>(parent))
-            {
-              parent->m_children.push_back(entry);
-            }
-        }
-
-      if (m_nItems > m_enlargeThreshold)
-        {
-          resize(m_enlargeFactor * m_nBuckets);
-        }
-
-      parent = entry;
-    }
-  return entry;
-}
-
-// Exact Match
-shared_ptr<name_tree::Entry>
-NameTree::findExactMatch(const Name& prefix) const
-{
-  NFD_LOG_TRACE("findExactMatch " << prefix);
-
-  size_t hashValue = name_tree::computeHash(prefix);
-  size_t loc = hashValue % m_nBuckets;
-
-  NFD_LOG_TRACE("Name " << prefix << " hash value = " << hashValue <<
-                "  location = " << loc);
-
-  shared_ptr<name_tree::Entry> entry;
-  name_tree::Node* node = 0;
-
-  for (node = m_buckets[loc]; node != 0; node = node->m_next)
-    {
-      entry = node->m_entry;
-      if (static_cast<bool>(entry))
-        {
-          if (hashValue == entry->getHash() && prefix == entry->getPrefix())
-            {
-              return entry;
-            }
-        } // if entry
-    } // for node
-
-  // if not found, the default value of entry (null pointer) will be returned
-  entry.reset();
-  return entry;
-}
-
-// Longest Prefix Match
-shared_ptr<name_tree::Entry>
-NameTree::findLongestPrefixMatch(const Name& prefix, const name_tree::EntrySelector& entrySelector) const
-{
-  NFD_LOG_TRACE("findLongestPrefixMatch " << prefix);
-
-  shared_ptr<name_tree::Entry> entry;
-  std::vector<size_t> hashValueSet = name_tree::computeHashSet(prefix);
-
-  size_t hashValue = 0;
-  size_t loc = 0;
-
-  for (int i = static_cast<int>(prefix.size()); i >= 0; i--)
-    {
-      hashValue = hashValueSet[i];
-      loc = hashValue % m_nBuckets;
-
-      name_tree::Node* node = 0;
-      for (node = m_buckets[loc]; node != 0; node = node->m_next)
-        {
-          entry = node->m_entry;
-          if (static_cast<bool>(entry))
-            {
-              // isPrefixOf() is used to avoid making a copy of the name
-              if (hashValue == entry->getHash() &&
-                  entry->getPrefix().isPrefixOf(prefix) &&
-                  entrySelector(*entry))
-                {
-                  return entry;
-                }
-            } // if entry
-        } // for node
-    }
-
-  // if not found, the default value of entry (null pointer) will be returned
-  entry.reset();
-  return entry;
-}
-
-shared_ptr<name_tree::Entry>
-NameTree::findLongestPrefixMatch(shared_ptr<name_tree::Entry> entry,
-                                 const name_tree::EntrySelector& entrySelector) const
-{
-  while (static_cast<bool>(entry))
-    {
-      if (entrySelector(*entry))
-        return entry;
-      entry = entry->getParent();
-    }
-  return shared_ptr<name_tree::Entry>();
-}
-
-// return {false: this entry is not empty, true: this entry is empty and erased}
-bool
-NameTree::eraseEntryIfEmpty(shared_ptr<name_tree::Entry> entry)
-{
-  BOOST_ASSERT(static_cast<bool>(entry));
-
-  NFD_LOG_TRACE("eraseEntryIfEmpty " << entry->getPrefix());
-
-  // first check if this Entry can be erased
-  if (entry->isEmpty())
-    {
-      // update child-related info in the parent
-      shared_ptr<name_tree::Entry> parent = entry->getParent();
-
-      if (static_cast<bool>(parent))
-        {
-          std::vector<shared_ptr<name_tree::Entry> >& parentChildrenList =
-            parent->getChildren();
-
-          bool isFound = false;
-          size_t size = parentChildrenList.size();
-          for (size_t i = 0; i < size; i++)
-            {
-              if (parentChildrenList[i] == entry)
-                {
-                  parentChildrenList[i] = parentChildrenList[size - 1];
-                  parentChildrenList.pop_back();
-                  isFound = true;
-                  break;
-                }
-            }
-
-          BOOST_VERIFY(isFound == true);
-        }
-
-      // remove this Entry and its Name Tree Node
-      name_tree::Node* node = entry->m_node;
-      name_tree::Node* nodePrev = node->m_prev;
-
-      // configure the previous node
-      if (nodePrev != 0)
-        {
-          // link the previous node to the next node
-          nodePrev->m_next = node->m_next;
-        }
-      else
-        {
-          m_buckets[entry->getHash() % m_nBuckets] = node->m_next;
-        }
-
-      // link the previous node with the next node (skip the erased one)
-      if (node->m_next != 0)
-        {
-          node->m_next->m_prev = nodePrev;
-          node->m_next = 0;
-        }
-
-      BOOST_ASSERT(node->m_next == 0);
-
-      m_nItems--;
-      delete node;
-
-      if (static_cast<bool>(parent))
-        eraseEntryIfEmpty(parent);
-
-      size_t newNBuckets = static_cast<size_t>(m_shrinkFactor *
-                                     static_cast<double>(m_nBuckets));
-
-      if (newNBuckets >= m_minNBuckets && m_nItems < m_shrinkThreshold)
-        {
-          resize(newNBuckets);
-        }
-
-      return true;
-
-    } // if this entry is empty
-
-  return false; // if this entry is not empty
-}
-
-boost::iterator_range<NameTree::const_iterator>
-NameTree::fullEnumerate(const name_tree::EntrySelector& entrySelector) const
-{
-  NFD_LOG_TRACE("fullEnumerate");
-
-  // find the first eligible entry
-  for (size_t i = 0; i < m_nBuckets; i++) {
-    for (name_tree::Node* node = m_buckets[i]; node != 0; node = node->m_next) {
-      if (static_cast<bool>(node->m_entry) && entrySelector(*node->m_entry)) {
-        const_iterator it(FULL_ENUMERATE_TYPE, *this, node->m_entry, entrySelector);
-        return {it, end()};
-      }
-    }
-  }
-
-  // If none of the entry satisfies the requirements, then return the end() iterator.
-  return {end(), end()};
-}
-
-boost::iterator_range<NameTree::const_iterator>
-NameTree::partialEnumerate(const Name& prefix,
-                           const name_tree::EntrySubTreeSelector& entrySubTreeSelector) const
-{
-  // the first step is to process the root node
-  shared_ptr<name_tree::Entry> entry = findExactMatch(prefix);
-  if (!static_cast<bool>(entry)) {
-    return {end(), end()};
-  }
-
-  std::pair<bool, bool>result = entrySubTreeSelector(*entry);
-  const_iterator it(PARTIAL_ENUMERATE_TYPE,
-                    *this,
-                    entry,
-                    name_tree::AnyEntry(),
-                    entrySubTreeSelector);
-
-  it.m_shouldVisitChildren = (result.second && entry->hasChildren());
-
-  if (result.first) {
-    // root node is acceptable
-  }
-  else {
-    // let the ++ operator handle it
-    ++it;
-  }
-  return {it, end()};
-}
-
-boost::iterator_range<NameTree::const_iterator>
-NameTree::findAllMatches(const Name& prefix,
-                         const name_tree::EntrySelector& entrySelector) const
-{
-  NFD_LOG_TRACE("NameTree::findAllMatches" << prefix);
-
-  // As we are using Name Prefix Hash Table, and the current LPM() is
-  // implemented as starting from full name, and reduce the number of
-  // components by 1 each time, we could use it here.
-  // For trie-like design, it could be more efficient by walking down the
-  // trie from the root node.
-
-  shared_ptr<name_tree::Entry> entry = findLongestPrefixMatch(prefix, entrySelector);
-
-  if (static_cast<bool>(entry)) {
-    const_iterator begin(FIND_ALL_MATCHES_TYPE, *this, entry, entrySelector);
-    return {begin, end()};
-  }
-  // If none of the entry satisfies the requirements, then return the end() iterator.
-  return {end(), end()};
-}
-
-// Hash Table Resize
-void
-NameTree::resize(size_t newNBuckets)
-{
-  NFD_LOG_TRACE("resize");
-
-  name_tree::Node** newBuckets = new name_tree::Node*[newNBuckets];
-  size_t count = 0;
-
-  // referenced ccnx hashtb.c hashtb_rehash()
-  name_tree::Node** pp = 0;
-  name_tree::Node* p = 0;
-  name_tree::Node* pre = 0;
-  name_tree::Node* q = 0; // record p->m_next
-  size_t i;
-  uint32_t h;
-  uint32_t b;
-
-  for (i = 0; i < newNBuckets; i++)
-    {
-      newBuckets[i] = 0;
-    }
-
-  for (i = 0; i < m_nBuckets; i++)
-    {
-      for (p = m_buckets[i]; p != 0; p = q)
-        {
-          count++;
-          q = p->m_next;
-          BOOST_ASSERT(static_cast<bool>(p->m_entry));
-          h = p->m_entry->m_hash;
-          b = h % newNBuckets;
-          pre = 0;
-          for (pp = &newBuckets[b]; *pp != 0; pp = &((*pp)->m_next))
-            {
-              pre = *pp;
-              continue;
-            }
-          p->m_prev = pre;
-          p->m_next = *pp; // Actually *pp always == 0 in this case
-          *pp = p;
-        }
-    }
-
-  BOOST_ASSERT(count == m_nItems);
-
-  name_tree::Node** oldBuckets = m_buckets;
-  m_buckets = newBuckets;
-  delete [] oldBuckets;
-
-  m_nBuckets = newNBuckets;
-
-  m_enlargeThreshold = static_cast<size_t>(m_enlargeLoadFactor *
-                                              static_cast<double>(m_nBuckets));
-  m_shrinkThreshold = static_cast<size_t>(m_shrinkLoadFactor *
-                                              static_cast<double>(m_nBuckets));
-}
-
-// For debugging
-void
-NameTree::dump(std::ostream& output) const
-{
-  NFD_LOG_TRACE("dump()");
-
-  name_tree::Node* node = 0;
-  shared_ptr<name_tree::Entry> entry;
-
-  using std::endl;
-
-  for (size_t i = 0; i < m_nBuckets; i++)
-    {
-      for (node = m_buckets[i]; node != 0; node = node->m_next)
-        {
-          entry = node->m_entry;
-
-          // if the Entry exist, dump its information
-          if (static_cast<bool>(entry))
-            {
-              output << "Bucket" << i << "\t" << entry->m_prefix.toUri() << endl;
-              output << "\t\tHash " << entry->m_hash << endl;
-
-              if (static_cast<bool>(entry->m_parent))
-                {
-                  output << "\t\tparent->" << entry->m_parent->m_prefix.toUri();
-                }
-              else
-                {
-                  output << "\t\tROOT";
-                }
-              output << endl;
-
-              if (entry->m_children.size() != 0)
-                {
-                  output << "\t\tchildren = " << entry->m_children.size() << endl;
-
-                  for (size_t j = 0; j < entry->m_children.size(); j++)
-                    {
-                      output << "\t\t\tChild " << j << " " <<
-                        entry->m_children[j]->getPrefix() << endl;
-                    }
-                }
-
-            } // if (static_cast<bool>(entry))
-
-        } // for node
-    } // for int i
-
-  output << "Bucket count = " << m_nBuckets << endl;
-  output << "Stored item = " << m_nItems << endl;
-  output << "--------------------------\n";
-}
-
-NameTree::const_iterator::const_iterator()
-  : m_nameTree(nullptr)
-{
-}
-
-NameTree::const_iterator::const_iterator(NameTree::IteratorType type,
-                            const NameTree& nameTree,
-                            shared_ptr<name_tree::Entry> entry,
-                            const name_tree::EntrySelector& entrySelector,
-                            const name_tree::EntrySubTreeSelector& entrySubTreeSelector)
-  : m_nameTree(&nameTree)
-  , m_entry(entry)
-  , m_subTreeRoot(entry)
-  , m_entrySelector(make_shared<name_tree::EntrySelector>(entrySelector))
-  , m_entrySubTreeSelector(make_shared<name_tree::EntrySubTreeSelector>(entrySubTreeSelector))
-  , m_type(type)
-  , m_shouldVisitChildren(true)
-{
-}
-
-// operator++()
-NameTree::const_iterator
-NameTree::const_iterator::operator++()
-{
-  NFD_LOG_TRACE("const_iterator::operator++()");
-
-  BOOST_ASSERT(m_entry != m_nameTree->m_end);
-
-  if (m_type == FULL_ENUMERATE_TYPE) // fullEnumerate
-    {
-      bool isFound = false;
-      // process the entries in the same bucket first
-      while (m_entry->m_node->m_next != 0)
-        {
-          m_entry = m_entry->m_node->m_next->m_entry;
-          if ((*m_entrySelector)(*m_entry))
-            {
-              isFound = true;
-              return *this;
-            }
-        }
-
-      // process other buckets
-
-      for (int newLocation = m_entry->m_hash % m_nameTree->m_nBuckets + 1;
-           newLocation < static_cast<int>(m_nameTree->m_nBuckets);
-           ++newLocation)
-        {
-          // process each bucket
-          name_tree::Node* node = m_nameTree->m_buckets[newLocation];
-          while (node != 0)
-            {
-              m_entry = node->m_entry;
-              if ((*m_entrySelector)(*m_entry))
-                {
-                  isFound = true;
-                  return *this;
-                }
-              node = node->m_next;
-            }
-        }
-      BOOST_VERIFY(isFound == false);
-      // Reach to the end()
-      m_entry = m_nameTree->m_end;
-      return *this;
-    }
-
-  if (m_type == PARTIAL_ENUMERATE_TYPE) // partialEnumerate
-    {
-      // We use pre-order traversal.
-      // if at the root, it could have already been accepted, or this
-      // iterator was just declared, and root doesn't satisfy the
-      // requirement
-      // The if() section handles this special case
-      // Essentially, we need to check root's fist child, and the rest will
-      // be the same as normal process
-      if (m_entry == m_subTreeRoot)
-        {
-          if (m_shouldVisitChildren)
-            {
-              m_entry = m_entry->getChildren()[0];
-              std::pair<bool, bool> result = ((*m_entrySubTreeSelector)(*m_entry));
-              m_shouldVisitChildren = (result.second && m_entry->hasChildren());
-              if(result.first)
-                {
-                  return *this;
-                }
-              else
-                {
-                  // the first child did not meet the requirement
-                  // the rest of the process can just fall through the while loop
-                  // as normal
-                }
-            }
-          else
-            {
-              // no children, should return end();
-              // just fall through
-            }
-        }
-
-      // The first thing to do is to visit its child, or go to find its possible
-      // siblings
-      while (m_entry != m_subTreeRoot)
-        {
-          if (m_shouldVisitChildren)
-            {
-              // If this subtree should be visited
-              m_entry = m_entry->getChildren()[0];
-              std::pair<bool, bool> result = ((*m_entrySubTreeSelector)(*m_entry));
-              m_shouldVisitChildren = (result.second && m_entry->hasChildren());
-              if (result.first) // if this node is acceptable
-                {
-                  return *this;
-                }
-              else
-                {
-                  // do nothing, as this node is essentially ignored
-                  // send this node to the while loop.
-                }
-            }
-          else
-            {
-              // Should try to find its sibling
-              shared_ptr<name_tree::Entry> parent = m_entry->getParent();
-
-              std::vector<shared_ptr<name_tree::Entry> >& parentChildrenList = parent->getChildren();
-              bool isFound = false;
-              size_t i = 0;
-              for (i = 0; i < parentChildrenList.size(); i++)
-                {
-                  if (parentChildrenList[i] == m_entry)
-                    {
-                      isFound = true;
-                      break;
-                    }
-                }
-
-              BOOST_VERIFY(isFound == true);
-              if (i < parentChildrenList.size() - 1) // m_entry not the last child
-                {
-                  m_entry = parentChildrenList[i + 1];
-                  std::pair<bool, bool> result = ((*m_entrySubTreeSelector)(*m_entry));
-                  m_shouldVisitChildren = (result.second && m_entry->hasChildren());
-                  if (result.first) // if this node is acceptable
-                    {
-                      return *this;
-                    }
-                  else
-                    {
-                      // do nothing, as this node is essentially ignored
-                      // send this node to the while loop.
-                    }
-                }
-              else
-                {
-                  // m_entry is the last child, no more sibling, should try to find parent's sibling
-                  m_shouldVisitChildren = false;
-                  m_entry = parent;
-                }
-            }
-        }
-
-      m_entry = m_nameTree->m_end;
-      return *this;
-    }
-
-  if (m_type == FIND_ALL_MATCHES_TYPE) // findAllMatches
-    {
-      // Assumption: at the beginning, m_entry was initialized with the first
-      // eligible Name Tree entry (i.e., has a PIT entry that can be satisfied
-      // by the Data packet)
-
-      while (static_cast<bool>(m_entry->getParent()))
-        {
-          m_entry = m_entry->getParent();
-          if ((*m_entrySelector)(*m_entry))
-            return *this;
-        }
-
-      // Reach to the end (Root)
-      m_entry = m_nameTree->m_end;
-      return *this;
-    }
-
-  BOOST_ASSERT(false); // unknown type
-  return *this;
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/table/name-tree.hpp b/NFD/daemon/table/name-tree.hpp
deleted file mode 100644
index 8d4e437..0000000
--- a/NFD/daemon/table/name-tree.hpp
+++ /dev/null
@@ -1,417 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_TABLE_NAME_TREE_HPP
-#define NFD_DAEMON_TABLE_NAME_TREE_HPP
-
-#include "common.hpp"
-#include "name-tree-entry.hpp"
-
-namespace nfd {
-namespace name_tree {
-
-/**
- * \brief Compute the hash value of the given name prefix's WIRE FORMAT
- */
-size_t
-computeHash(const Name& prefix);
-
-/**
- * \brief Incrementally compute hash values
- * \return Return a vector of hash values, starting from the root prefix
- */
-std::vector<size_t>
-computeHashSet(const Name& prefix);
-
-/// a predicate to accept or reject an Entry in find operations
-typedef function<bool (const Entry& entry)> EntrySelector;
-
-/**
- * \brief a predicate to accept or reject an Entry and its children
- * \return .first indicates whether entry should be accepted;
- *         .second indicates whether entry's children should be visited
- */
-typedef function<std::pair<bool,bool> (const Entry& entry)> EntrySubTreeSelector;
-
-struct AnyEntry {
-  bool
-  operator()(const Entry& entry)
-  {
-    return true;
-  }
-};
-
-struct AnyEntrySubTree {
-  std::pair<bool, bool>
-  operator()(const Entry& entry)
-  {
-    return std::make_pair(true, true);
-  }
-};
-
-} // namespace name_tree
-
-/**
- * \brief Class Name Tree
- */
-class NameTree : noncopyable
-{
-public:
-  class const_iterator;
-
-  explicit
-  NameTree(size_t nBuckets = 1024);
-
-  ~NameTree();
-
-public: // information
-  /**
-   * \brief Get the number of occupied entries in the Name Tree
-   */
-  size_t
-  size() const;
-
-  /**
-   * \brief Get the number of buckets in the Name Tree (NPHT)
-   * \details The number of buckets is the one that used to create the hash
-   * table, i.e., m_nBuckets.
-   */
-  size_t
-  getNBuckets() const;
-
-  /**
-   * \brief Dump all the information stored in the Name Tree for debugging.
-   */
-  void
-  dump(std::ostream& output) const;
-
-public: // mutation
-  /**
-   * \brief Look for the Name Tree Entry that contains this name prefix.
-   * \details Starts from the shortest name prefix, and then increase the
-   * number of name components by one each time. All non-existing Name Tree
-   * Entries will be created.
-   * \param prefix The querying name prefix.
-   * \return The pointer to the Name Tree Entry that contains this full name
-   * prefix.
-   * \note Existing iterators are unaffected.
-   */
-  shared_ptr<name_tree::Entry>
-  lookup(const Name& prefix);
-
-  /**
-   * \brief Delete a Name Tree Entry if this entry is empty.
-   * \param entry The entry to be deleted if empty.
-   * \note This function must be called after a table entry is detached from Name Tree
-   *       entry. The function deletes a Name Tree entry if nothing is attached to it and
-   *       it has no children, then repeats the same process on its ancestors.
-   * \note Existing iterators, except those pointing to deleted entries, are unaffected.
-   */
-  bool
-  eraseEntryIfEmpty(shared_ptr<name_tree::Entry> entry);
-
-public: // shortcut access
-  /// get NameTree entry from attached FIB entry
-  shared_ptr<name_tree::Entry>
-  get(const fib::Entry& fibEntry) const;
-
-  /// get NameTree entry from attached PIT entry
-  shared_ptr<name_tree::Entry>
-  get(const pit::Entry& pitEntry) const;
-
-  /// get NameTree entry from attached Measurements entry
-  shared_ptr<name_tree::Entry>
-  get(const measurements::Entry& measurementsEntry) const;
-
-  /// get NameTree entry from attached StrategyChoice entry
-  shared_ptr<name_tree::Entry>
-  get(const strategy_choice::Entry& strategyChoiceEntry) const;
-
-public: // matching
-  /**
-   * \brief Exact match lookup for the given name prefix.
-   * \return a null shared_ptr if this prefix is not found;
-   * otherwise return the Name Tree Entry address
-   */
-  shared_ptr<name_tree::Entry>
-  findExactMatch(const Name& prefix) const;
-
-  /**
-   * \brief Longest prefix matching for the given name
-   * \details Starts from the full name string, reduce the number of name component
-   * by one each time, until an Entry is found.
-   */
-  shared_ptr<name_tree::Entry>
-  findLongestPrefixMatch(const Name& prefix,
-                         const name_tree::EntrySelector& entrySelector =
-                         name_tree::AnyEntry()) const;
-
-  shared_ptr<name_tree::Entry>
-  findLongestPrefixMatch(shared_ptr<name_tree::Entry> entry,
-                         const name_tree::EntrySelector& entrySelector =
-                         name_tree::AnyEntry()) const;
-
-  /** \brief Enumerate all the name prefixes that satisfy the prefix and entrySelector
-   *  \return an unspecified type that have .begin() and .end() methods
-   *          and is usable with range-based for
-   *
-   *  Example:
-   *  \code{.cpp}
-   *  auto&& allMatches = nt.findAllMatches(Name("/A/B/C"));
-   *  for (const name_tree::Entry& nte : allMatches) {
-   *    ...
-   *  }
-   *  \endcode
-   *  \note Iteration order is implementation-specific and is undefined
-   *  \note The returned iterator may get invalidated when NameTree is modified
-   */
-  boost::iterator_range<const_iterator>
-  findAllMatches(const Name& prefix,
-                 const name_tree::EntrySelector& entrySelector = name_tree::AnyEntry()) const;
-
-public: // enumeration
-  /** \brief Enumerate all entries, optionally filtered by an EntrySelector.
-   *  \return an unspecified type that have .begin() and .end() methods
-   *          and is usable with range-based for
-   *
-   *  Example:
-   *  \code{.cpp}
-   *  auto&& enumerable = nt.fullEnumerate();
-   *  for (const name_tree::Entry& nte : enumerable) {
-   *    ...
-   *  }
-   *  \endcode
-   *  \note Iteration order is implementation-specific and is undefined
-   *  \note The returned iterator may get invalidated when NameTree is modified
-   */
-  boost::iterator_range<const_iterator>
-  fullEnumerate(const name_tree::EntrySelector& entrySelector = name_tree::AnyEntry()) const;
-
-  /** \brief Enumerate all entries under a prefix, optionally filtered by an EntrySubTreeSelector.
-   *  \return an unspecified type that have .begin() and .end() methods
-   *          and is usable with range-based for
-   *
-   *  Example:
-   *  \code{.cpp}
-   *  auto&& enumerable = nt.partialEnumerate(Name("/A/B/C"));
-   *  for (const name_tree::Entry& nte : enumerable) {
-   *    ...
-   *  }
-   *  \endcode
-   *  \note Iteration order is implementation-specific and is undefined
-   *  \note The returned iterator may get invalidated when NameTree is modified
-   */
-  boost::iterator_range<const_iterator>
-  partialEnumerate(const Name& prefix,
-                   const name_tree::EntrySubTreeSelector& entrySubTreeSelector =
-                         name_tree::AnyEntrySubTree()) const;
-
-  /** \brief Get an iterator pointing to the first NameTree entry
-   *  \note Iteration order is implementation-specific and is undefined
-   *  \note The returned iterator may get invalidated when NameTree is modified
-   */
-  const_iterator
-  begin() const;
-
-  /** \brief Get an iterator referring to the past-the-end FIB entry
-   *  \note Iteration order is implementation-specific and is undefined
-   *  \note The returned iterator may get invalidated when NameTree is modified
-   */
-  const_iterator
-  end() const;
-
-  enum IteratorType {
-    FULL_ENUMERATE_TYPE,
-    PARTIAL_ENUMERATE_TYPE,
-    FIND_ALL_MATCHES_TYPE
-  };
-
-  class const_iterator : public std::iterator<std::forward_iterator_tag, const name_tree::Entry>
-  {
-  public:
-    friend class NameTree;
-
-    const_iterator();
-
-    const_iterator(NameTree::IteratorType type,
-      const NameTree& nameTree,
-      shared_ptr<name_tree::Entry> entry,
-      const name_tree::EntrySelector& entrySelector = name_tree::AnyEntry(),
-      const name_tree::EntrySubTreeSelector& entrySubTreeSelector = name_tree::AnyEntrySubTree());
-
-    ~const_iterator();
-
-    const name_tree::Entry&
-    operator*() const;
-
-    shared_ptr<name_tree::Entry>
-    operator->() const;
-
-    const_iterator
-    operator++();
-
-    const_iterator
-    operator++(int);
-
-    bool
-    operator==(const const_iterator& other) const;
-
-    bool
-    operator!=(const const_iterator& other) const;
-
-  private:
-    const NameTree*                             m_nameTree;
-    shared_ptr<name_tree::Entry>                m_entry;
-    shared_ptr<name_tree::Entry>                m_subTreeRoot;
-    shared_ptr<name_tree::EntrySelector>        m_entrySelector;
-    shared_ptr<name_tree::EntrySubTreeSelector> m_entrySubTreeSelector;
-    NameTree::IteratorType                      m_type;
-    bool                                        m_shouldVisitChildren;
-  };
-
-private:
-  /**
-   * \brief Resize the hash table size when its load factor reaches a threshold.
-   * \details As we are currently using a hand-written hash table implementation
-   * for the Name Tree, the hash table resize() function should be kept in the
-   * name-tree.hpp file.
-   * \param newNBuckets The number of buckets for the new hash table.
-   */
-  void
-  resize(size_t newNBuckets);
-
-private:
-  size_t                        m_nItems;  // Number of items being stored
-  size_t                        m_nBuckets; // Number of hash buckets
-  size_t                        m_minNBuckets; // Minimum number of hash buckets
-  double                        m_enlargeLoadFactor;
-  size_t                        m_enlargeThreshold;
-  int                           m_enlargeFactor;
-  double                        m_shrinkLoadFactor;
-  size_t                        m_shrinkThreshold;
-  double                        m_shrinkFactor;
-  name_tree::Node**             m_buckets; // Name Tree Buckets in the NPHT
-  shared_ptr<name_tree::Entry>  m_end;
-  const_iterator                m_endIterator;
-
-  /**
-   * \brief Create a Name Tree Entry if it does not exist, or return the existing
-   * Name Tree Entry address.
-   * \details Called by lookup() only.
-   * \return The first item is the Name Tree Entry address, the second item is
-   * a bool value indicates whether this is an old entry (false) or a new
-   * entry (true).
-   */
-  std::pair<shared_ptr<name_tree::Entry>, bool>
-  insert(const Name& prefix);
-};
-
-inline NameTree::const_iterator::~const_iterator()
-{
-}
-
-inline size_t
-NameTree::size() const
-{
-  return m_nItems;
-}
-
-inline size_t
-NameTree::getNBuckets() const
-{
-  return m_nBuckets;
-}
-
-inline shared_ptr<name_tree::Entry>
-NameTree::get(const fib::Entry& fibEntry) const
-{
-  return fibEntry.m_nameTreeEntry;
-}
-
-inline shared_ptr<name_tree::Entry>
-NameTree::get(const pit::Entry& pitEntry) const
-{
-  return pitEntry.m_nameTreeEntry;
-}
-
-inline shared_ptr<name_tree::Entry>
-NameTree::get(const measurements::Entry& measurementsEntry) const
-{
-  return measurementsEntry.m_nameTreeEntry;
-}
-
-inline shared_ptr<name_tree::Entry>
-NameTree::get(const strategy_choice::Entry& strategyChoiceEntry) const
-{
-  return strategyChoiceEntry.m_nameTreeEntry;
-}
-
-inline NameTree::const_iterator
-NameTree::begin() const
-{
-  return fullEnumerate().begin();
-}
-
-inline NameTree::const_iterator
-NameTree::end() const
-{
-  return m_endIterator;
-}
-
-inline const name_tree::Entry&
-NameTree::const_iterator::operator*() const
-{
-  return *m_entry;
-}
-
-inline shared_ptr<name_tree::Entry>
-NameTree::const_iterator::operator->() const
-{
-  return m_entry;
-}
-
-inline NameTree::const_iterator
-NameTree::const_iterator::operator++(int)
-{
-  NameTree::const_iterator temp(*this);
-  ++(*this);
-  return temp;
-}
-
-inline bool
-NameTree::const_iterator::operator==(const NameTree::const_iterator& other) const
-{
-  return m_entry == other.m_entry;
-}
-
-inline bool
-NameTree::const_iterator::operator!=(const NameTree::const_iterator& other) const
-{
-  return m_entry != other.m_entry;
-}
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_NAME_TREE_HPP
diff --git a/NFD/daemon/table/pit-entry.cpp b/NFD/daemon/table/pit-entry.cpp
deleted file mode 100644
index da7c6ed..0000000
--- a/NFD/daemon/table/pit-entry.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "pit-entry.hpp"
-#include <algorithm>
-
-namespace nfd {
-namespace pit {
-
-const Name Entry::LOCALHOST_NAME("ndn:/localhost");
-const Name Entry::LOCALHOP_NAME("ndn:/localhop");
-
-Entry::Entry(const Interest& interest)
-  : m_interest(interest.shared_from_this())
-{
-}
-
-const Name&
-Entry::getName() const
-{
-  return m_interest->getName();
-}
-
-bool
-Entry::hasLocalInRecord() const
-{
-  return std::any_of(m_inRecords.begin(), m_inRecords.end(),
-                     [] (const InRecord& inRecord) { return inRecord.getFace()->isLocal(); });
-}
-
-bool
-Entry::canForwardTo(const Face& face) const
-{
-  time::steady_clock::TimePoint now = time::steady_clock::now();
-
-  bool hasUnexpiredOutRecord = std::any_of(m_outRecords.begin(), m_outRecords.end(),
-    [&face, &now] (const OutRecord& outRecord) {
-      return outRecord.getFace().get() == &face && outRecord.getExpiry() >= now;
-    });
-  if (hasUnexpiredOutRecord) {
-    return false;
-  }
-
-  bool hasUnexpiredOtherInRecord = std::any_of(m_inRecords.begin(), m_inRecords.end(),
-    [&face, &now] (const InRecord& inRecord) {
-      return inRecord.getFace().get() != &face && inRecord.getExpiry() >= now;
-    });
-  if (!hasUnexpiredOtherInRecord) {
-    return false;
-  }
-
-  return !this->violatesScope(face);
-}
-
-bool
-Entry::violatesScope(const Face& face) const
-{
-  // /localhost scope
-  bool isViolatingLocalhost = !face.isLocal() &&
-                              LOCALHOST_NAME.isPrefixOf(this->getName());
-  if (isViolatingLocalhost) {
-    return true;
-  }
-
-  // /localhop scope
-  bool isViolatingLocalhop = !face.isLocal() &&
-                             LOCALHOP_NAME.isPrefixOf(this->getName()) &&
-                             !this->hasLocalInRecord();
-  if (isViolatingLocalhop) {
-    return true;
-  }
-
-  return false;
-}
-
-int
-Entry::findNonce(uint32_t nonce, const Face& face) const
-{
-  // TODO should we ignore expired in/out records?
-
-  int dnw = DUPLICATE_NONCE_NONE;
-
-  for (const InRecord& inRecord : m_inRecords) {
-    if (inRecord.getLastNonce() == nonce) {
-      if (inRecord.getFace().get() == &face) {
-        dnw |= DUPLICATE_NONCE_IN_SAME;
-      }
-      else {
-        dnw |= DUPLICATE_NONCE_IN_OTHER;
-      }
-    }
-  }
-
-  for (const OutRecord& outRecord : m_outRecords) {
-    if (outRecord.getLastNonce() == nonce) {
-      if (outRecord.getFace().get() == &face) {
-        dnw |= DUPLICATE_NONCE_OUT_SAME;
-      }
-      else {
-        dnw |= DUPLICATE_NONCE_OUT_OTHER;
-      }
-    }
-  }
-
-  return dnw;
-}
-
-InRecordCollection::iterator
-Entry::insertOrUpdateInRecord(shared_ptr<Face> face, const Interest& interest)
-{
-  auto it = std::find_if(m_inRecords.begin(), m_inRecords.end(),
-    [&face] (const InRecord& inRecord) { return inRecord.getFace() == face; });
-  if (it == m_inRecords.end()) {
-    m_inRecords.emplace_front(face);
-    it = m_inRecords.begin();
-  }
-
-  it->update(interest);
-  return it;
-}
-
-InRecordCollection::const_iterator
-Entry::getInRecord(const Face& face) const
-{
-  return std::find_if(m_inRecords.begin(), m_inRecords.end(),
-    [&face] (const InRecord& inRecord) { return inRecord.getFace().get() == &face; });
-}
-
-void
-Entry::deleteInRecords()
-{
-  m_inRecords.clear();
-}
-
-OutRecordCollection::iterator
-Entry::insertOrUpdateOutRecord(shared_ptr<Face> face, const Interest& interest)
-{
-  auto it = std::find_if(m_outRecords.begin(), m_outRecords.end(),
-    [&face] (const OutRecord& outRecord) { return outRecord.getFace() == face; });
-  if (it == m_outRecords.end()) {
-    m_outRecords.emplace_front(face);
-    it = m_outRecords.begin();
-  }
-
-  it->update(interest);
-  return it;
-}
-
-OutRecordCollection::const_iterator
-Entry::getOutRecord(const Face& face) const
-{
-  return std::find_if(m_outRecords.begin(), m_outRecords.end(),
-    [&face] (const OutRecord& outRecord) { return outRecord.getFace().get() == &face; });
-}
-
-void
-Entry::deleteOutRecord(const Face& face)
-{
-  auto it = std::find_if(m_outRecords.begin(), m_outRecords.end(),
-    [&face] (const OutRecord& outRecord) { return outRecord.getFace().get() == &face; });
-  if (it != m_outRecords.end()) {
-    m_outRecords.erase(it);
-  }
-}
-
-bool
-Entry::hasUnexpiredOutRecords() const
-{
-  time::steady_clock::TimePoint now = time::steady_clock::now();
-
-  return std::any_of(m_outRecords.begin(), m_outRecords.end(),
-    [&now] (const OutRecord& outRecord) { return outRecord.getExpiry() >= now; });
-}
-
-} // namespace pit
-} // namespace nfd
diff --git a/NFD/daemon/table/pit-entry.hpp b/NFD/daemon/table/pit-entry.hpp
deleted file mode 100644
index 8fcf4a7..0000000
--- a/NFD/daemon/table/pit-entry.hpp
+++ /dev/null
@@ -1,205 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_TABLE_PIT_ENTRY_HPP
-#define NFD_DAEMON_TABLE_PIT_ENTRY_HPP
-
-#include "pit-in-record.hpp"
-#include "pit-out-record.hpp"
-#include "core/scheduler.hpp"
-
-namespace nfd {
-
-class NameTree;
-
-namespace name_tree {
-class Entry;
-}
-
-namespace pit {
-
-/** \brief represents an unordered collection of InRecords
- */
-typedef std::list< InRecord>  InRecordCollection;
-
-/** \brief represents an unordered collection of OutRecords
- */
-typedef std::list<OutRecord> OutRecordCollection;
-
-/** \brief indicates where duplicate Nonces are found
- */
-enum DuplicateNonceWhere {
-  DUPLICATE_NONCE_NONE      = 0,
-  /// in-record of same face
-  DUPLICATE_NONCE_IN_SAME   = (1 << 0),
-  /// in-record of other face
-  DUPLICATE_NONCE_IN_OTHER  = (1 << 1),
-  /// out-record of same face
-  DUPLICATE_NONCE_OUT_SAME  = (1 << 2),
-  /// out-record of other face
-  DUPLICATE_NONCE_OUT_OTHER = (1 << 3)
-};
-
-/** \brief represents a PIT entry
- */
-class Entry : public StrategyInfoHost, noncopyable
-{
-public:
-  explicit
-  Entry(const Interest& interest);
-
-  const Interest&
-  getInterest() const;
-
-  /** \return Interest Name
-   */
-  const Name&
-  getName() const;
-
-  /** \brief decides whether Interest can be forwarded to face
-   *
-   *  \return true if OutRecord of this face does not exist or has expired,
-   *          and there is an InRecord not of this face,
-   *          and scope is not violated
-   */
-  bool
-  canForwardTo(const Face& face) const;
-
-  /** \brief decides whether forwarding Interest to face would violate scope
-   *
-   *  \return true if scope control would be violated
-   *  \note canForwardTo has more comprehensive checks (including scope control)
-   *        and should be used by most strategies. Outgoing Interest pipeline
-   *        should only check scope because some strategy (eg. vehicular) needs
-   *        to retransmit sooner than OutRecord expiry, or forward Interest
-   *        back to incoming face
-   */
-  bool
-  violatesScope(const Face& face) const;
-
-  /** \brief finds where a duplicate Nonce appears
-   *  \return OR'ed DuplicateNonceWhere
-   */
-  int
-  findNonce(uint32_t nonce, const Face& face) const;
-
-public: // InRecord
-  const InRecordCollection&
-  getInRecords() const;
-
-  /** \brief determines whether any InRecord is a local Face
-   *
-   *  \return true if any InRecord is a local Face,
-   *          false if all InRecords are non-local Faces
-   */
-  bool
-  hasLocalInRecord() const;
-
-  /** \brief inserts a InRecord for face, and updates it with interest
-   *
-   *  If InRecord for face exists, the existing one is updated.
-   *  This method does not add the Nonce as a seen Nonce.
-   *  \return an iterator to the InRecord
-   */
-  InRecordCollection::iterator
-  insertOrUpdateInRecord(shared_ptr<Face> face, const Interest& interest);
-
-  /** \brief get the InRecord for face
-   *  \return an iterator to the InRecord, or .end if it does not exist
-   */
-  InRecordCollection::const_iterator
-  getInRecord(const Face& face) const;
-
-  /// deletes all InRecords
-  void
-  deleteInRecords();
-
-public: // OutRecord
-  const OutRecordCollection&
-  getOutRecords() const;
-
-  /** \brief inserts a OutRecord for face, and updates it with interest
-   *
-   *  If OutRecord for face exists, the existing one is updated.
-   *  \return an iterator to the OutRecord
-   */
-  OutRecordCollection::iterator
-  insertOrUpdateOutRecord(shared_ptr<Face> face, const Interest& interest);
-
-  /** \brief get the OutRecord for face
-   *  \return an iterator to the OutRecord, or .end if it does not exist
-   */
-  OutRecordCollection::const_iterator
-  getOutRecord(const Face& face) const;
-
-  /// deletes one OutRecord for face if exists
-  void
-  deleteOutRecord(const Face& face);
-
-  /** \return true if there is one or more unexpired OutRecords
-   */
-  bool
-  hasUnexpiredOutRecords() const;
-
-public:
-  EventId m_unsatisfyTimer;
-  EventId m_stragglerTimer;
-
-private:
-  shared_ptr<const Interest> m_interest;
-  InRecordCollection m_inRecords;
-  OutRecordCollection m_outRecords;
-
-  static const Name LOCALHOST_NAME;
-  static const Name LOCALHOP_NAME;
-
-  shared_ptr<name_tree::Entry> m_nameTreeEntry;
-
-  friend class nfd::NameTree;
-  friend class nfd::name_tree::Entry;
-};
-
-inline const Interest&
-Entry::getInterest() const
-{
-  return *m_interest;
-}
-
-inline const InRecordCollection&
-Entry::getInRecords() const
-{
-  return m_inRecords;
-}
-
-inline const OutRecordCollection&
-Entry::getOutRecords() const
-{
-  return m_outRecords;
-}
-
-} // namespace pit
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_PIT_ENTRY_HPP
diff --git a/NFD/daemon/table/pit-face-record.cpp b/NFD/daemon/table/pit-face-record.cpp
deleted file mode 100644
index c62a1b5..0000000
--- a/NFD/daemon/table/pit-face-record.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "pit-face-record.hpp"
-
-namespace nfd {
-namespace pit {
-
-FaceRecord::FaceRecord(shared_ptr<Face> face)
-  : m_face(face)
-  , m_lastNonce(0)
-  , m_lastRenewed(time::steady_clock::TimePoint::min())
-  , m_expiry(time::steady_clock::TimePoint::min())
-{
-}
-
-void
-FaceRecord::update(const Interest& interest)
-{
-  m_lastNonce = interest.getNonce();
-  m_lastRenewed = time::steady_clock::now();
-
-  time::milliseconds lifetime = interest.getInterestLifetime();
-  if (lifetime < time::milliseconds::zero()) {
-    lifetime = ndn::DEFAULT_INTEREST_LIFETIME;
-  }
-  m_expiry = m_lastRenewed + lifetime;
-}
-
-
-} // namespace pit
-} // namespace nfd
diff --git a/NFD/daemon/table/pit-face-record.hpp b/NFD/daemon/table/pit-face-record.hpp
deleted file mode 100644
index c1d6c77..0000000
--- a/NFD/daemon/table/pit-face-record.hpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_TABLE_PIT_FACE_RECORD_HPP
-#define NFD_DAEMON_TABLE_PIT_FACE_RECORD_HPP
-
-#include "face/face.hpp"
-#include "strategy-info-host.hpp"
-
-namespace nfd {
-namespace pit {
-
-/** \brief contains information about an Interest
- *         on an incoming or outgoing face
- *  \note This is an implementation detail to extract common functionality
- *        of InRecord and OutRecord
- */
-class FaceRecord : public StrategyInfoHost
-{
-public:
-  explicit
-  FaceRecord(shared_ptr<Face> face);
-
-  shared_ptr<Face>
-  getFace() const;
-
-  uint32_t
-  getLastNonce() const;
-
-  time::steady_clock::TimePoint
-  getLastRenewed() const;
-
-  /** \brief gives the time point this record expires
-   *  \return getLastRenewed() + InterestLifetime
-   */
-  time::steady_clock::TimePoint
-  getExpiry() const;
-
-  /** \brief updates lastNonce, lastRenewed, expiry fields
-   */
-  void
-  update(const Interest& interest);
-
-private:
-  shared_ptr<Face> m_face;
-  uint32_t m_lastNonce;
-  time::steady_clock::TimePoint m_lastRenewed;
-  time::steady_clock::TimePoint m_expiry;
-};
-
-inline shared_ptr<Face>
-FaceRecord::getFace() const
-{
-  return m_face;
-}
-
-inline uint32_t
-FaceRecord::getLastNonce() const
-{
-  return m_lastNonce;
-}
-
-inline time::steady_clock::TimePoint
-FaceRecord::getLastRenewed() const
-{
-  return m_lastRenewed;
-}
-
-inline time::steady_clock::TimePoint
-FaceRecord::getExpiry() const
-{
-  return m_expiry;
-}
-
-} // namespace pit
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_PIT_FACE_RECORD_HPP
diff --git a/NFD/daemon/table/pit-in-record.cpp b/NFD/daemon/table/pit-in-record.cpp
deleted file mode 100644
index b7f0edf..0000000
--- a/NFD/daemon/table/pit-in-record.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "pit-in-record.hpp"
-
-namespace nfd {
-namespace pit {
-
-InRecord::InRecord(shared_ptr<Face> face)
-  : FaceRecord(face)
-{
-}
-
-void
-InRecord::update(const Interest& interest)
-{
-  this->FaceRecord::update(interest);
-  m_interest = const_cast<Interest&>(interest).shared_from_this();
-}
-
-} // namespace pit
-} // namespace nfd
diff --git a/NFD/daemon/table/pit-in-record.hpp b/NFD/daemon/table/pit-in-record.hpp
deleted file mode 100644
index da56d1f..0000000
--- a/NFD/daemon/table/pit-in-record.hpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_TABLE_PIT_IN_RECORD_HPP
-#define NFD_DAEMON_TABLE_PIT_IN_RECORD_HPP
-
-#include "pit-face-record.hpp"
-
-namespace nfd {
-namespace pit {
-
-/** \class InRecord
- *  \brief contains information about an Interest from an incoming face
- */
-class InRecord : public FaceRecord
-{
-public:
-  explicit
-  InRecord(shared_ptr<Face> face);
-
-  void
-  update(const Interest& interest);
-
-  const Interest&
-  getInterest() const;
-
-private:
-  shared_ptr<const Interest> m_interest;
-};
-
-inline const Interest&
-InRecord::getInterest() const
-{
-  BOOST_ASSERT(static_cast<bool>(m_interest));
-  return *m_interest;
-}
-
-} // namespace pit
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_PIT_IN_RECORD_HPP
diff --git a/NFD/daemon/table/pit-out-record.cpp b/NFD/daemon/table/pit-out-record.cpp
deleted file mode 100644
index 268b67b..0000000
--- a/NFD/daemon/table/pit-out-record.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "pit-out-record.hpp"
-
-namespace nfd {
-namespace pit {
-
-OutRecord::OutRecord(shared_ptr<Face> face)
-  : FaceRecord(face)
-{
-}
-
-} // namespace pit
-} // namespace nfd
diff --git a/NFD/daemon/table/pit-out-record.hpp b/NFD/daemon/table/pit-out-record.hpp
deleted file mode 100644
index c75e005..0000000
--- a/NFD/daemon/table/pit-out-record.hpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#ifndef NFD_DAEMON_TABLE_PIT_OUT_RECORD_HPP
-#define NFD_DAEMON_TABLE_PIT_OUT_RECORD_HPP
-
-#include "pit-face-record.hpp"
-
-namespace nfd {
-namespace pit {
-
-/** \class OutRecord
- *  \brief contains information about an Interest toward an outgoing face
- */
-class OutRecord : public FaceRecord
-{
-public:
-  explicit
-  OutRecord(shared_ptr<Face> face);
-};
-
-} // namespace pit
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_PIT_IN_RECORD_HPP
diff --git a/NFD/daemon/table/pit.cpp b/NFD/daemon/table/pit.cpp
deleted file mode 100644
index 5e333aa..0000000
--- a/NFD/daemon/table/pit.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "pit.hpp"
-#include <type_traits>
-
-#include <boost/concept/assert.hpp>
-#include <boost/concept_check.hpp>
-#include <type_traits>
-
-namespace nfd {
-namespace pit {
-
-#if HAVE_IS_MOVE_CONSTRUCTIBLE
-static_assert(std::is_move_constructible<DataMatchResult>::value,
-              "DataMatchResult must be MoveConstructible");
-#endif // HAVE_IS_MOVE_CONSTRUCTIBLE
-
-} // namespace pit
-
-// http://en.cppreference.com/w/cpp/concept/ForwardIterator
-BOOST_CONCEPT_ASSERT((boost::ForwardIterator<Pit::const_iterator>));
-// boost::ForwardIterator follows SGI standard http://www.sgi.com/tech/stl/ForwardIterator.html,
-// which doesn't require DefaultConstructible
-#ifdef HAVE_IS_DEFAULT_CONSTRUCTIBLE
-static_assert(std::is_default_constructible<Pit::const_iterator>::value,
-              "Pit::const_iterator must be default-constructible");
-#else
-BOOST_CONCEPT_ASSERT((boost::DefaultConstructible<Pit::const_iterator>));
-#endif // HAVE_IS_DEFAULT_CONSTRUCTIBLE
-
-Pit::Pit(NameTree& nameTree)
-  : m_nameTree(nameTree)
-  , m_nItems(0)
-{
-}
-
-Pit::~Pit()
-{
-}
-
-std::pair<shared_ptr<pit::Entry>, bool>
-Pit::insert(const Interest& interest)
-{
-  // first lookup() the Interest Name in the NameTree, which will creates all
-  // the intermedia nodes, starting from the shortest prefix.
-  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.lookup(interest.getName());
-  BOOST_ASSERT(static_cast<bool>(nameTreeEntry));
-
-  const std::vector<shared_ptr<pit::Entry>>& pitEntries = nameTreeEntry->getPitEntries();
-
-  // then check if this Interest is already in the PIT entries
-  auto it = std::find_if(pitEntries.begin(), pitEntries.end(),
-                         [&interest] (const shared_ptr<pit::Entry>& entry) {
-                           return entry->getInterest().getName() == interest.getName() &&
-                                  entry->getInterest().getSelectors() == interest.getSelectors();
-                         });
-  if (it != pitEntries.end()) {
-    return { *it, false };
-  }
-
-  shared_ptr<pit::Entry> entry = make_shared<pit::Entry>(interest);
-  nameTreeEntry->insertPitEntry(entry);
-  m_nItems++;
-  return { entry, true };
-}
-
-pit::DataMatchResult
-Pit::findAllDataMatches(const Data& data) const
-{
-  auto&& ntMatches = m_nameTree.findAllMatches(data.getName(),
-    [] (const name_tree::Entry& entry) { return entry.hasPitEntries(); });
-
-  pit::DataMatchResult matches;
-  for (const name_tree::Entry& nte : ntMatches) {
-    for (const shared_ptr<pit::Entry>& pitEntry : nte.getPitEntries()) {
-      if (pitEntry->getInterest().matchesData(data))
-        matches.emplace_back(pitEntry);
-    }
-  }
-
-  return matches;
-}
-
-void
-Pit::erase(shared_ptr<pit::Entry> pitEntry)
-{
-  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.get(*pitEntry);
-  BOOST_ASSERT(static_cast<bool>(nameTreeEntry));
-
-  nameTreeEntry->erasePitEntry(pitEntry);
-  m_nameTree.eraseEntryIfEmpty(nameTreeEntry);
-
-  --m_nItems;
-}
-
-Pit::const_iterator
-Pit::begin() const
-{
-  return const_iterator(m_nameTree.fullEnumerate(
-    [] (const name_tree::Entry& entry) { return entry.hasPitEntries(); }).begin());
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/table/pit.hpp b/NFD/daemon/table/pit.hpp
deleted file mode 100644
index 3bdf44f..0000000
--- a/NFD/daemon/table/pit.hpp
+++ /dev/null
@@ -1,220 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_TABLE_PIT_HPP
-#define NFD_DAEMON_TABLE_PIT_HPP
-
-#include "name-tree.hpp"
-#include "pit-entry.hpp"
-
-namespace nfd {
-namespace pit {
-
-/** \class DataMatchResult
- *  \brief an unordered iterable of all PIT entries matching Data
- *
- *  This type shall support:
- *    iterator<shared_ptr<pit::Entry>> begin()
- *    iterator<shared_ptr<pit::Entry>> end()
- */
-typedef std::vector<shared_ptr<pit::Entry>> DataMatchResult;
-
-} // namespace pit
-
-/** \brief represents the Interest Table
- */
-class Pit : noncopyable
-{
-public:
-  explicit
-  Pit(NameTree& nameTree);
-
-  ~Pit();
-
-  /** \return number of entries
-   */
-  size_t
-  size() const;
-
-  /** \brief inserts a PIT entry for Interest
-   *
-   *  If an entry for exact same name and selectors exists, that entry is returned.
-   *  \return the entry, and true for new entry, false for existing entry
-   */
-  std::pair<shared_ptr<pit::Entry>, bool>
-  insert(const Interest& interest);
-
-  /** \brief performs a Data match
-   *  \return an iterable of all PIT entries matching data
-   */
-  pit::DataMatchResult
-  findAllDataMatches(const Data& data) const;
-
-  /**
-   *  \brief erases a PIT Entry
-   */
-  void
-  erase(shared_ptr<pit::Entry> pitEntry);
-
-public: // enumeration
-  class const_iterator;
-
-  /** \brief returns an iterator pointing to the first PIT entry
-   *  \note Iteration order is implementation-specific and is undefined
-   *  \note The returned iterator may get invalidated if PIT or another NameTree-based
-   *        table is modified
-   */
-  const_iterator
-  begin() const;
-
-  /** \brief returns an iterator referring to the past-the-end PIT entry
-   *  \note The returned iterator may get invalidated if PIT or another NameTree-based
-   *        table is modified
-   */
-  const_iterator
-  end() const;
-
-  class const_iterator : public std::iterator<std::forward_iterator_tag, const pit::Entry>
-  {
-  public:
-    const_iterator();
-
-    explicit
-    const_iterator(const NameTree::const_iterator& it);
-
-    ~const_iterator();
-
-    const pit::Entry&
-    operator*() const;
-
-    shared_ptr<pit::Entry>
-    operator->() const;
-
-    const_iterator&
-    operator++();
-
-    const_iterator
-    operator++(int);
-
-    bool
-    operator==(const const_iterator& other) const;
-
-    bool
-    operator!=(const const_iterator& other) const;
-
-  private:
-    NameTree::const_iterator m_nameTreeIterator;
-    /** \brief Index of the current visiting PIT entry in NameTree node
-     *
-     * Index is used to ensure that dereferencing of m_nameTreeIterator happens only when
-     * const_iterator is dereferenced or advanced.
-     */
-    size_t m_iPitEntry;
-  };
-
-private:
-  NameTree& m_nameTree;
-  size_t m_nItems;
-};
-
-inline size_t
-Pit::size() const
-{
-  return m_nItems;
-}
-
-inline Pit::const_iterator
-Pit::end() const
-{
-  return const_iterator(m_nameTree.end());
-}
-
-inline
-Pit::const_iterator::const_iterator()
-  : m_iPitEntry(0)
-{
-}
-
-inline
-Pit::const_iterator::const_iterator(const NameTree::const_iterator& it)
-  : m_nameTreeIterator(it)
-  , m_iPitEntry(0)
-{
-}
-
-inline
-Pit::const_iterator::~const_iterator()
-{
-}
-
-inline Pit::const_iterator
-Pit::const_iterator::operator++(int)
-{
-  Pit::const_iterator temp(*this);
-  ++(*this);
-  return temp;
-}
-
-inline Pit::const_iterator&
-Pit::const_iterator::operator++()
-{
-  ++m_iPitEntry;
-  if (m_iPitEntry < m_nameTreeIterator->getPitEntries().size()) {
-    return *this;
-  }
-
-  ++m_nameTreeIterator;
-  m_iPitEntry = 0;
-  return *this;
-}
-
-inline const pit::Entry&
-Pit::const_iterator::operator*() const
-{
-  return *(this->operator->());
-}
-
-inline shared_ptr<pit::Entry>
-Pit::const_iterator::operator->() const
-{
-  return m_nameTreeIterator->getPitEntries().at(m_iPitEntry);
-}
-
-inline bool
-Pit::const_iterator::operator==(const Pit::const_iterator& other) const
-{
-  return m_nameTreeIterator == other.m_nameTreeIterator &&
-         m_iPitEntry == other.m_iPitEntry;
-}
-
-inline bool
-Pit::const_iterator::operator!=(const Pit::const_iterator& other) const
-{
-  return !(*this == other);
-}
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_PIT_HPP
diff --git a/NFD/daemon/table/strategy-choice-entry.cpp b/NFD/daemon/table/strategy-choice-entry.cpp
deleted file mode 100644
index 2b7a257..0000000
--- a/NFD/daemon/table/strategy-choice-entry.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "strategy-choice-entry.hpp"
-#include "core/logger.hpp"
-#include "fw/strategy.hpp"
-
-namespace nfd {
-namespace strategy_choice {
-
-Entry::Entry(const Name& prefix)
-  : m_prefix(prefix)
-  , m_strategy(nullptr)
-{
-}
-
-const Name&
-Entry::getStrategyName() const
-{
-  return m_strategy->getName();
-}
-
-} // namespace strategy_choice
-} // namespace nfd
diff --git a/NFD/daemon/table/strategy-choice-entry.hpp b/NFD/daemon/table/strategy-choice-entry.hpp
deleted file mode 100644
index 857a313..0000000
--- a/NFD/daemon/table/strategy-choice-entry.hpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#ifndef NFD_DAEMON_TABLE_STRATEGY_CHOICE_ENTRY_HPP
-#define NFD_DAEMON_TABLE_STRATEGY_CHOICE_ENTRY_HPP
-
-#include "common.hpp"
-
-namespace nfd {
-
-class NameTree;
-namespace name_tree {
-class Entry;
-}
-namespace fw {
-class Strategy;
-}
-
-namespace strategy_choice {
-
-/** \brief represents a Strategy Choice entry
- */
-class Entry : noncopyable
-{
-public:
-  Entry(const Name& prefix);
-
-  const Name&
-  getPrefix() const;
-
-  const Name&
-  getStrategyName() const;
-
-  fw::Strategy&
-  getStrategy() const;
-
-  void
-  setStrategy(fw::Strategy& strategy);
-
-private:
-  Name m_prefix;
-  fw::Strategy* m_strategy;
-
-  shared_ptr<name_tree::Entry> m_nameTreeEntry;
-  friend class nfd::NameTree;
-  friend class nfd::name_tree::Entry;
-};
-
-
-inline const Name&
-Entry::getPrefix() const
-{
-  return m_prefix;
-}
-
-inline fw::Strategy&
-Entry::getStrategy() const
-{
-  BOOST_ASSERT(m_strategy != nullptr);
-  return *m_strategy;
-}
-
-inline void
-Entry::setStrategy(fw::Strategy& strategy)
-{
-  m_strategy = &strategy;
-}
-
-} // namespace strategy_choice
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_STRATEGY_CHOICE_ENTRY_HPP
diff --git a/NFD/daemon/table/strategy-choice.cpp b/NFD/daemon/table/strategy-choice.cpp
deleted file mode 100644
index 85aade6..0000000
--- a/NFD/daemon/table/strategy-choice.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "strategy-choice.hpp"
-#include "core/logger.hpp"
-#include "fw/strategy.hpp"
-#include "pit-entry.hpp"
-#include "measurements-entry.hpp"
-
-namespace nfd {
-
-using strategy_choice::Entry;
-using fw::Strategy;
-
-NFD_LOG_INIT("StrategyChoice");
-
-StrategyChoice::StrategyChoice(NameTree& nameTree, shared_ptr<Strategy> defaultStrategy)
-  : m_nameTree(nameTree)
-  , m_nItems(0)
-{
-  this->setDefaultStrategy(defaultStrategy);
-}
-
-bool
-StrategyChoice::hasStrategy(const Name& strategyName, bool isExact) const
-{
-  if (isExact) {
-    return m_strategyInstances.count(strategyName) > 0;
-  }
-  else {
-    return static_cast<bool>(this->getStrategy(strategyName));
-  }
-}
-
-bool
-StrategyChoice::install(shared_ptr<Strategy> strategy)
-{
-  BOOST_ASSERT(static_cast<bool>(strategy));
-  const Name& strategyName = strategy->getName();
-
-  if (this->hasStrategy(strategyName, true)) {
-    NFD_LOG_ERROR("install(" << strategyName << ") duplicate strategyName");
-    return false;
-  }
-
-  m_strategyInstances[strategyName] = strategy;
-  return true;
-}
-
-fw::Strategy*
-StrategyChoice::getStrategy(const Name& strategyName) const
-{
-  fw::Strategy* candidate = nullptr;
-  for (auto it = m_strategyInstances.lower_bound(strategyName);
-       it != m_strategyInstances.end() && strategyName.isPrefixOf(it->first); ++it) {
-    switch (it->first.size() - strategyName.size()) {
-    case 0: // exact match
-      return it->second.get();
-    case 1: // unversioned strategyName matches versioned strategy
-      candidate = it->second.get();
-      break;
-    }
-  }
-  return candidate;
-}
-
-bool
-StrategyChoice::insert(const Name& prefix, const Name& strategyName)
-{
-  Strategy* strategy = this->getStrategy(strategyName);
-  if (strategy == nullptr) {
-    NFD_LOG_ERROR("insert(" << prefix << "," << strategyName << ") strategy not installed");
-    return false;
-  }
-
-  shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(prefix);
-  shared_ptr<Entry> entry = nte->getStrategyChoiceEntry();
-  Strategy* oldStrategy = nullptr;
-  if (static_cast<bool>(entry)) {
-    if (entry->getStrategy().getName() == strategy->getName()) {
-      NFD_LOG_TRACE("insert(" << prefix << ") not changing " << strategy->getName());
-      return true;
-    }
-    oldStrategy = &entry->getStrategy();
-    NFD_LOG_TRACE("insert(" << prefix << ") changing from " << oldStrategy->getName() <<
-                  " to " << strategy->getName());
-  }
-
-  if (!static_cast<bool>(entry)) {
-    oldStrategy = &this->findEffectiveStrategy(prefix);
-    entry = make_shared<Entry>(prefix);
-    nte->setStrategyChoiceEntry(entry);
-    ++m_nItems;
-    NFD_LOG_TRACE("insert(" << prefix << ") new entry " << strategy->getName());
-  }
-
-  this->changeStrategy(*entry, *oldStrategy, *strategy);
-  entry->setStrategy(*strategy);
-  return true;
-}
-
-void
-StrategyChoice::erase(const Name& prefix)
-{
-  BOOST_ASSERT(prefix.size() > 0);
-
-  shared_ptr<name_tree::Entry> nte = m_nameTree.findExactMatch(prefix);
-  if (!static_cast<bool>(nte)) {
-    return;
-  }
-
-  shared_ptr<Entry> entry = nte->getStrategyChoiceEntry();
-  if (!static_cast<bool>(entry)) {
-    return;
-  }
-
-  Strategy& oldStrategy = entry->getStrategy();
-
-  Strategy& parentStrategy = this->findEffectiveStrategy(prefix.getPrefix(-1));
-  this->changeStrategy(*entry, oldStrategy, parentStrategy);
-
-  nte->setStrategyChoiceEntry(shared_ptr<Entry>());
-  m_nameTree.eraseEntryIfEmpty(nte);
-  --m_nItems;
-}
-
-std::pair<bool, Name>
-StrategyChoice::get(const Name& prefix) const
-{
-  shared_ptr<name_tree::Entry> nte = m_nameTree.findExactMatch(prefix);
-  if (!static_cast<bool>(nte)) {
-    return { false, Name() };
-  }
-
-  shared_ptr<Entry> entry = nte->getStrategyChoiceEntry();
-  if (!static_cast<bool>(entry)) {
-    return { false, Name() };
-  }
-
-  return { true, entry->getStrategy().getName() };
-}
-
-Strategy&
-StrategyChoice::findEffectiveStrategy(const Name& prefix) const
-{
-  shared_ptr<name_tree::Entry> nte = m_nameTree.findLongestPrefixMatch(prefix,
-    [] (const name_tree::Entry& entry) {
-      return static_cast<bool>(entry.getStrategyChoiceEntry());
-    });
-
-  BOOST_ASSERT(static_cast<bool>(nte));
-  return nte->getStrategyChoiceEntry()->getStrategy();
-}
-
-Strategy&
-StrategyChoice::findEffectiveStrategy(shared_ptr<name_tree::Entry> nte) const
-{
-  shared_ptr<strategy_choice::Entry> entry = nte->getStrategyChoiceEntry();
-  if (static_cast<bool>(entry))
-    return entry->getStrategy();
-
-  nte = m_nameTree.findLongestPrefixMatch(nte,
-    [] (const name_tree::Entry& entry) {
-      return static_cast<bool>(entry.getStrategyChoiceEntry());
-    });
-
-  BOOST_ASSERT(static_cast<bool>(nte));
-  return nte->getStrategyChoiceEntry()->getStrategy();
-}
-
-Strategy&
-StrategyChoice::findEffectiveStrategy(const pit::Entry& pitEntry) const
-{
-  shared_ptr<name_tree::Entry> nte = m_nameTree.get(pitEntry);
-
-  BOOST_ASSERT(static_cast<bool>(nte));
-  return this->findEffectiveStrategy(nte);
-}
-
-Strategy&
-StrategyChoice::findEffectiveStrategy(const measurements::Entry& measurementsEntry) const
-{
-  shared_ptr<name_tree::Entry> nte = m_nameTree.get(measurementsEntry);
-
-  BOOST_ASSERT(static_cast<bool>(nte));
-  return this->findEffectiveStrategy(nte);
-}
-
-void
-StrategyChoice::setDefaultStrategy(shared_ptr<Strategy> strategy)
-{
-  this->install(strategy);
-
-  // don't use .insert here, because it will invoke findEffectiveStrategy
-  // which expects an existing root entry
-  shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(Name());
-  shared_ptr<Entry> entry = make_shared<Entry>(Name());
-  nte->setStrategyChoiceEntry(entry);
-  ++m_nItems;
-  NFD_LOG_INFO("setDefaultStrategy " << strategy->getName());
-
-  entry->setStrategy(*strategy);
-}
-
-static inline void
-clearStrategyInfo(const name_tree::Entry& nte)
-{
-  NFD_LOG_TRACE("clearStrategyInfo " << nte.getPrefix());
-
-  for (const shared_ptr<pit::Entry>& pitEntry : nte.getPitEntries()) {
-    pitEntry->clearStrategyInfo();
-    for (const pit::InRecord& inRecord : pitEntry->getInRecords()) {
-      const_cast<pit::InRecord&>(inRecord).clearStrategyInfo();
-    }
-    for (const pit::OutRecord& outRecord : pitEntry->getOutRecords()) {
-      const_cast<pit::OutRecord&>(outRecord).clearStrategyInfo();
-    }
-  }
-  if (static_cast<bool>(nte.getMeasurementsEntry())) {
-    nte.getMeasurementsEntry()->clearStrategyInfo();
-  }
-}
-
-void
-StrategyChoice::changeStrategy(strategy_choice::Entry& entry,
-                               fw::Strategy& oldStrategy,
-                               fw::Strategy& newStrategy)
-{
-  if (&oldStrategy == &newStrategy) {
-    return;
-  }
-
-  NFD_LOG_INFO("changeStrategy(" << entry.getPrefix() << ")"
-               << " from " << oldStrategy.getName()
-               << " to " << newStrategy.getName());
-
-  // reset StrategyInfo on a portion of NameTree,
-  // where entry's effective strategy is covered by the changing StrategyChoice entry
-  const name_tree::Entry* rootNte = m_nameTree.get(entry).get();
-  auto&& ntChanged = m_nameTree.partialEnumerate(entry.getPrefix(),
-    [&rootNte] (const name_tree::Entry& nte) -> std::pair<bool, bool> {
-      if (&nte == rootNte) {
-        return {true, true};
-      }
-      if (static_cast<bool>(nte.getStrategyChoiceEntry())) {
-        return {false, false};
-      }
-      return {true, true};
-    });
-  for (const name_tree::Entry& nte : ntChanged) {
-    clearStrategyInfo(nte);
-  }
-}
-
-StrategyChoice::const_iterator
-StrategyChoice::begin() const
-{
-  auto&& enumerable = m_nameTree.fullEnumerate(
-    [] (const name_tree::Entry& entry) {
-      return static_cast<bool>(entry.getStrategyChoiceEntry());
-    });
-  return const_iterator(enumerable.begin());
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/table/strategy-choice.hpp b/NFD/daemon/table/strategy-choice.hpp
deleted file mode 100644
index fdff3ab..0000000
--- a/NFD/daemon/table/strategy-choice.hpp
+++ /dev/null
@@ -1,237 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_TABLE_STRATEGY_CHOICE_HPP
-#define NFD_DAEMON_TABLE_STRATEGY_CHOICE_HPP
-
-#include "strategy-choice-entry.hpp"
-#include "name-tree.hpp"
-
-namespace nfd {
-
-/** \brief represents the Strategy Choice table
- *
- *  The Strategy Choice table maintains available Strategy types,
- *  and associates Name prefixes with Strategy types.
- *
- *  Each strategy is identified by a strategyName.
- *  It's recommended to include a version number as the last component of strategyName.
- *
- *  A Name prefix is owned by a strategy if a longest prefix match on the
- *  Strategy Choice table returns that strategy.
- */
-class StrategyChoice : noncopyable
-{
-public:
-  StrategyChoice(NameTree& nameTree, shared_ptr<fw::Strategy> defaultStrategy);
-
-public: // available Strategy types
-  /** \brief determines if a strategy is installed
-   *  \param isExact true to require exact match, false to permit unversioned strategyName
-   *  \return true if strategy is installed
-   */
-  bool
-  hasStrategy(const Name& strategyName, bool isExact = false) const;
-
-  /** \brief install a strategy
-   *  \return true if installed; false if not installed due to duplicate strategyName
-   *  \note shared_ptr is passed by value because StrategyChoice takes ownership of strategy
-   */
-  bool
-  install(shared_ptr<fw::Strategy> strategy);
-
-public: // Strategy Choice table
-  /** \brief set strategy of prefix to be strategyName
-   *  \param strategyName the strategy to be used
-   *  \return true on success
-   *
-   *  This method set a strategy onto a Name prefix.
-   *  The strategy must have been installed.
-   *  The strategyName can either be exact (contains version component),
-   *  or omit the version component to pick the latest version.
-   */
-  bool
-  insert(const Name& prefix, const Name& strategyName);
-
-  /** \brief make prefix to inherit strategy from its parent
-   *
-   *  not allowed for root prefix (ndn:/)
-   */
-  void
-  erase(const Name& prefix);
-
-  /** \brief get strategy Name of prefix
-   *  \return true and strategyName at exact match, or false
-   */
-  std::pair<bool, Name>
-  get(const Name& prefix) const;
-
-public: // effective strategy
-  /// get effective strategy for prefix
-  fw::Strategy&
-  findEffectiveStrategy(const Name& prefix) const;
-
-  /// get effective strategy for pitEntry
-  fw::Strategy&
-  findEffectiveStrategy(const pit::Entry& pitEntry) const;
-
-  /// get effective strategy for measurementsEntry
-  fw::Strategy&
-  findEffectiveStrategy(const measurements::Entry& measurementsEntry) const;
-
-public: // enumeration
-  class const_iterator
-    : public std::iterator<std::forward_iterator_tag, const strategy_choice::Entry>
-  {
-  public:
-    explicit
-    const_iterator(const NameTree::const_iterator& it);
-
-    ~const_iterator();
-
-    const strategy_choice::Entry&
-    operator*() const;
-
-    shared_ptr<strategy_choice::Entry>
-    operator->() const;
-
-    const_iterator&
-    operator++();
-
-    const_iterator
-    operator++(int);
-
-    bool
-    operator==(const const_iterator& other) const;
-
-    bool
-    operator!=(const const_iterator& other) const;
-
-  private:
-    NameTree::const_iterator m_nameTreeIterator;
-  };
-
-  /// number of entries stored
-  size_t
-  size() const;
-
-  const_iterator
-  begin() const;
-
-  const_iterator
-  end() const;
-
-private:
-  /** \brief get Strategy instance by strategyName
-   *  \param strategyName a versioned or unversioned strategyName
-   */
-  fw::Strategy*
-  getStrategy(const Name& strategyName) const;
-
-  void
-  setDefaultStrategy(shared_ptr<fw::Strategy> strategy);
-
-  void
-  changeStrategy(strategy_choice::Entry& entry,
-                 fw::Strategy& oldStrategy,
-                 fw::Strategy& newStrategy);
-
-  fw::Strategy&
-  findEffectiveStrategy(shared_ptr<name_tree::Entry> nte) const;
-
-private:
-  NameTree& m_nameTree;
-  size_t m_nItems;
-
-  typedef std::map<Name, shared_ptr<fw::Strategy> > StrategyInstanceTable;
-  StrategyInstanceTable m_strategyInstances;
-};
-
-inline size_t
-StrategyChoice::size() const
-{
-  return m_nItems;
-}
-
-inline StrategyChoice::const_iterator
-StrategyChoice::end() const
-{
-  return const_iterator(m_nameTree.end());
-}
-
-inline
-StrategyChoice::const_iterator::const_iterator(const NameTree::const_iterator& it)
-  : m_nameTreeIterator(it)
-{
-}
-
-inline
-StrategyChoice::const_iterator::~const_iterator()
-{
-}
-
-inline
-StrategyChoice::const_iterator
-StrategyChoice::const_iterator::operator++(int)
-{
-  StrategyChoice::const_iterator temp(*this);
-  ++(*this);
-  return temp;
-}
-
-inline StrategyChoice::const_iterator&
-StrategyChoice::const_iterator::operator++()
-{
-  ++m_nameTreeIterator;
-  return *this;
-}
-
-inline const strategy_choice::Entry&
-StrategyChoice::const_iterator::operator*() const
-{
-  return *(m_nameTreeIterator->getStrategyChoiceEntry());
-}
-
-inline shared_ptr<strategy_choice::Entry>
-StrategyChoice::const_iterator::operator->() const
-{
-  return m_nameTreeIterator->getStrategyChoiceEntry();
-}
-
-inline bool
-StrategyChoice::const_iterator::operator==(const StrategyChoice::const_iterator& other) const
-{
-  return m_nameTreeIterator == other.m_nameTreeIterator;
-}
-
-inline bool
-StrategyChoice::const_iterator::operator!=(const StrategyChoice::const_iterator& other) const
-{
-  return m_nameTreeIterator != other.m_nameTreeIterator;
-}
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_STRATEGY_CHOICE_HPP
diff --git a/NFD/daemon/table/strategy-info-host.cpp b/NFD/daemon/table/strategy-info-host.cpp
deleted file mode 100644
index 4961c68..0000000
--- a/NFD/daemon/table/strategy-info-host.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "strategy-info-host.hpp"
-
-namespace nfd {
-
-void
-StrategyInfoHost::clearStrategyInfo()
-{
-  m_items.clear();
-}
-
-} // namespace nfd
diff --git a/NFD/daemon/table/strategy-info-host.hpp b/NFD/daemon/table/strategy-info-host.hpp
deleted file mode 100644
index 1f6d940..0000000
--- a/NFD/daemon/table/strategy-info-host.hpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_TABLE_STRATEGY_INFO_HOST_HPP
-#define NFD_DAEMON_TABLE_STRATEGY_INFO_HOST_HPP
-
-#include "fw/strategy-info.hpp"
-
-namespace nfd {
-
-/** \brief base class for an entity onto which StrategyInfo objects may be placed
- */
-class StrategyInfoHost
-{
-public:
-  /** \brief get a StrategyInfo item
-   *  \tparam T type of StrategyInfo, must be a subclass of from nfd::fw::StrategyInfo
-   *  \retval nullptr if no StrategyInfo of type T is stored
-   */
-  template<typename T>
-  shared_ptr<T>
-  getStrategyInfo() const;
-
-  /** \brief set a StrategyInfo item
-   *  \tparam T type of StrategyInfo, must be a subclass of from nfd::fw::StrategyInfo
-   */
-  template<typename T>
-  void
-  setStrategyInfo(shared_ptr<T> strategyInfo);
-
-  /** \brief get or create a StrategyInfo item
-   *  \tparam T type of StrategyInfo, must be a subclass of from nfd::fw::StrategyInfo
-   *
-   *  If no StrategyInfo of type T is stored, it's created with \p{args};
-   *  otherwise, the existing item is returned.
-   */
-  template<typename T, typename ...A>
-  shared_ptr<T>
-  getOrCreateStrategyInfo(A&&... args);
-
-  /** \brief clear all StrategyInfo items
-   */
-  void
-  clearStrategyInfo();
-
-private:
-  std::map<int, shared_ptr<fw::StrategyInfo>> m_items;
-};
-
-
-template<typename T>
-shared_ptr<T>
-StrategyInfoHost::getStrategyInfo() const
-{
-  static_assert(std::is_base_of<fw::StrategyInfo, T>::value,
-                "T must inherit from StrategyInfo");
-
-  auto it = m_items.find(T::getTypeId());
-  if (it == m_items.end()) {
-    return nullptr;
-  }
-  return static_pointer_cast<T, fw::StrategyInfo>(it->second);
-}
-
-template<typename T>
-void
-StrategyInfoHost::setStrategyInfo(shared_ptr<T> item)
-{
-  static_assert(std::is_base_of<fw::StrategyInfo, T>::value,
-                "T must inherit from StrategyInfo");
-
-  if (item == nullptr) {
-    m_items.erase(T::getTypeId());
-  }
-  else {
-    m_items[T::getTypeId()] = item;
-  }
-}
-
-template<typename T, typename ...A>
-shared_ptr<T>
-StrategyInfoHost::getOrCreateStrategyInfo(A&&... args)
-{
-  static_assert(std::is_base_of<fw::StrategyInfo, T>::value,
-                "T must inherit from StrategyInfo");
-
-  shared_ptr<T> item = this->getStrategyInfo<T>();
-  if (!static_cast<bool>(item)) {
-    item = make_shared<T>(std::forward<A>(args)...);
-    this->setStrategyInfo(item);
-  }
-  return item;
-}
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_TABLE_STRATEGY_INFO_HOST_HPP
diff --git a/NFD/version.hpp b/NFD/version.hpp
deleted file mode 100644
index 33381ff..0000000
--- a/NFD/version.hpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- 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
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_VERSION_HPP
-#define NFD_VERSION_HPP
-
-namespace nfd {
-
-/** NFD version follows Semantic Versioning 2.0.0 specification
- *  http://semver.org/
- */
-
-// To change version number, modify VERSION variable in top-level wscript.
-
-/** \brief NFD version represented as an integer
- *
- *  MAJOR*1000000 + MINOR*1000 + PATCH
- */
-#define NFD_VERSION 2000
-
-/** \brief NFD version represented as a string
- *
- *  MAJOR.MINOR.PATCH
- */
-#define NFD_VERSION_STRING "0.2.0"
-
-/** \brief NFD version string, including git commit information, if NFD is build from
- *         specific git commit
- *
- * NFD_VERSION_BUILD_STRING is obtained using the following command (`NFD-` prefix is
- * afterwards removed):
- *
- *    `git describe --match 'NFD-*'`
- *
- * When NFD is built not from git, NFD_VERSION_BUILD_STRING equals NFD_VERSION_STRING
- *
- * MAJOR.MINOR.PATCH(-release-candidate-tag)(-(number-of-commits-since-tag)-COMMIT-HASH)
- *
- * Example, 0.1.0-rc1-1-g5c86570
- */
-#define NFD_VERSION_BUILD_STRING "0.2.0-100-ga22a217"
-
-/// MAJOR version
-#define NFD_VERSION_MAJOR 0
-/// MINOR version
-#define NFD_VERSION_MINOR 2
-/// PATCH version
-#define NFD_VERSION_PATCH 0
-
-} // namespace nfd
-
-#endif // NFD_VERSION_HPP
