support for NS, TXT, NDNCERT, FH
diff --git a/src/app/name-caching-resolver.cpp b/src/app/name-caching-resolver.cpp
deleted file mode 100644
index 728d0b0..0000000
--- a/src/app/name-caching-resolver.cpp
+++ /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.
- *
- * This file is part of NDNS (Named Data Networking Domain Name Service).
- * See AUTHORS.md for complete list of NDNS authors and contributors.
- *
- * NDNS 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.
- *
- * NDNS 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
- * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-#include "name-caching-resolver.hpp"
-
-namespace ndn {
-namespace ndns {
-
-NameCachingResolver::NameCachingResolver(const char *programName, const char *prefix)
-: NDNApp(programName, prefix)
-//, m_resolverType(CachingResolver)
-{
-  this->setInterestLifetime(time::milliseconds(2000));
-}
-
-
-
-void
-NameCachingResolver::run()
-{
-  boost::asio::signal_set signalSet(m_ioService, SIGINT, SIGTERM);
-  signalSet.async_wait(boost::bind(&NDNApp::signalHandler, this));
- // boost::bind(&NdnTlvPingServer::signalHandler, this)
-
-  Name name(m_prefix);
-  name.append(Query::toString(Query::QUERY_DNS_R));
-
-  m_face.setInterestFilter(name,
-               bind(&NameCachingResolver::onInterest,
-                  this, _1, _2),
-               bind(&NDNApp::onRegisterFailed,
-                  this, _1,_2));
-
-  std::cout << "\n=== NDNS Resolver "<<m_programName
-            <<" with routeble prefix "<< name.toUri()
-            << " starts===\n" << std::endl;
-
-  try {
-    m_face.processEvents();
-  }
-  catch (std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    m_hasError = true;
-    m_ioService.stop();
-  }
-}
-
-
-
-void
-NameCachingResolver::onData(const Interest& interest, Data &data, IterativeQuery& iq)
-{
-  if (interest.getName() != iq.getLastInterest().getName())
-  {
-    std::cout<<iq<<std::endl;
-    std::cout<<"waiting for "<<iq.getLastInterest().getName().toUri()<<std::endl;
-    std::cout<<"coming data "<<data.getName().toUri()<<std::endl;
-    return;
-  }
-
-  iq.doData(data);
-
-  if (iq.getStep() == IterativeQuery::AnswerStub)
-  {
-    Data data = iq.getLastResponse().toData();
-    Name name = iq.getQuery().getAuthorityZone();
-    name.append(Query::toString(iq.getQuery().getQueryType()));
-    name.append(iq.getQuery().getRrLabel());
-    name.append(RR::toString(iq.getQuery().getRrType()));
-    name.appendVersion();
-    data.setName(name);
-    data.setFreshnessPeriod(iq.getLastResponse().getFreshness());
-
-    m_keyChain.sign(data);
-    m_face.put(data);
-    std::cout<<"[* <- *] answer Response ("
-        <<Response::toString(iq.getLastResponse().getResponseType())<<") to stub:"<<std::endl;
-    std::cout<<iq.getLastResponse()<<std::endl;
-    for (int i=0; i<15; i++)
-    {
-      std::cout<<"----";
-    }
-    std::cout<<std::endl<<std::endl;
-
-  } else if (iq.getStep() == IterativeQuery::NSQuery){
-    resolve(iq);
-  } else if (iq.getStep() == IterativeQuery::RRQuery) {
-    resolve(iq);
-  } else if (iq.getStep() == IterativeQuery::Abort) {
-    return;
-  } else {
-    std::cout<<"let me see the current step="<<IterativeQuery::toString(iq.getStep())<<std::endl;
-    std::cout<<iq<<std::endl;
-  }
-
-}
-
-
-void
-NameCachingResolver::answerRespNack(IterativeQuery& iq)
-{
-  Response re;
-
-  Name name = iq.getQuery().getAuthorityZone();
-  name.append(Query::toString(iq.getQuery().getQueryType()));
-  name.append(iq.getQuery().getRrLabel());
-  name.append(RR::toString(iq.getQuery().getRrType()));
-  name.appendVersion();
-
-  re.setResponseType(Response::NDNS_Nack);
-  re.setFreshness(this->getContentFreshness());
-  re.setQueryName(name);
-  Data data = re.toData();
-
-  m_keyChain.sign(data);
-  m_face.put(data);
-  std::cout<<"[* <- *] answer RRs to stub:"<<std::endl;
-  std::cout<<iq.getLastResponse().getStringRRs()<<std::endl;
-  for (int i=0; i<15; i++)
-  {
-    std::cout<<"----";
-  }
-  std::cout<<std::endl<<std::endl;
-}
-
-void
-NameCachingResolver::onInterest(const Name &name, const Interest &interest)
-{
-  Query query;
-  query.fromInterest(interest);
-  std::cout<<"[* -> *] receive Interest: "<<interest.getName().toUri()<<std::endl;
-  if (query.getQueryType() == Query::QUERY_DNS)
-  {
-    cout<<m_programName<<" is not in charge of Query_DNS"<<endl;
-  }
-
-  IterativeQuery iq(query);
-  //iq.setQuery(query);
-  resolve(iq);
-
-}
-
-
-void
-NameCachingResolver::onTimeout(const Interest& interest, IterativeQuery& iq)
-{
-  std::cout<<"[* !! *] timeout Interest "<<interest.getName().toUri()<<" timeouts"<<std::endl;
-
-  iq.doTimeout();
-  return;
-}
-
-void
-NameCachingResolver::resolve(IterativeQuery& iq) {
-
-  Interest interest = iq.toLatestInterest();
-
-  //must be set before express interest,since the call will back call iq
-  //if set after, then the iq in call of onData will return nothing
-  //be very careful here,  as a new guy to c++
-
-  interest.setInterestLifetime(this->getInterestLifetime());
-  iq.setLastInterest(interest);
-  try {
-    m_face.expressInterest(interest,
-            boost::bind(&NameCachingResolver::onData, this, _1, _2, iq),
-            boost::bind(&NameCachingResolver::onTimeout, this, _1, iq)
-            );
-  }catch(std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-  }
-
-
-  std::cout<<"[* <- *] send Interest: "<<interest.getName().toUri()<<std::endl;
-  std::cout<<iq<<std::endl;
-}
-
-} /* namespace ndns */
-} /* namespace ndn */
diff --git a/src/app/name-caching-resolver.hpp b/src/app/name-caching-resolver.hpp
index 5f4fe53..d1047d3 100644
--- a/src/app/name-caching-resolver.hpp
+++ b/src/app/name-caching-resolver.hpp
@@ -33,6 +33,7 @@
 #include "response.hpp"
 #include "rr.hpp"
 #include "iterative-query.hpp"
+#include "iterative-query-with-forwarding-hint.hpp"
 #include "ndn-app.hpp"
 
 using namespace std;
@@ -40,45 +41,215 @@
 namespace ndn {
 namespace ndns {
 
-
-class NameCachingResolver : public NDNApp{
-enum ResolverType
+template <class IQStrategy> //IQ stands for iterative Query Strategy
+class NameCachingResolver: public NDNApp
 {
-  StubResolver,
-  CachingResolver
-};
 
 public:
 
-NameCachingResolver(const char *programName, const char *prefix);
+  NameCachingResolver(const char *programName, const char *prefix);
 
+  void
+  resolve(IQStrategy& iq);
 
-void
-resolve(IterativeQuery& iq);
+  using NDNApp::onData;
+  void
+  onData(const Interest& interest, Data &data, IQStrategy& iq);
 
-void
-answerRespNack(IterativeQuery& iq);
+  void
+  onInterest(const Name &name, const Interest &interest);
 
-using NDNApp::onData;
-void
-onData(const Interest& interest, Data &data, IterativeQuery& iq);
+  using NDNApp::onTimeout;
+  void
+  onTimeout(const Interest& interest, IQStrategy& iq);
 
-void
-onInterest(const Name &name, const Interest &interest);
+  void
+  run();
 
-using NDNApp::onTimeout;
+  const Name& getRootZoneFowardingHint() const
+  {
+    return m_rootZoneFowardingHint;
+  }
 
-void
-onTimeout(const Interest& interest, IterativeQuery& iq);
-
-void
-run();
+  void setRootZoneFowardingHint(const Name& rootZoneFowardingHint)
+  {
+    m_rootZoneFowardingHint = rootZoneFowardingHint;
+  }
 
 private:
-  //ResolverType m_resolverType;
+  /**
+   * 0 means disable forwarding hint,
+   * 1 means enable forwarding hint
+   * todo: 2, retrieve name and hint of the name server as a optimization way
+   */
+
+  Name m_rootZoneFowardingHint;
 
 };
 
+
+template <typename IQStrategy>
+NameCachingResolver<IQStrategy>::NameCachingResolver(const char *programName,
+    const char *prefix)
+  : NDNApp(programName, prefix)
+  , m_rootZoneFowardingHint("/")
+{
+  this->setInterestLifetime(time::milliseconds(2000));
+}
+
+template <class IQStrategy> void
+NameCachingResolver<IQStrategy>::run()
+{
+  boost::asio::signal_set signalSet(m_ioService, SIGINT, SIGTERM);
+  signalSet.async_wait(boost::bind(&NDNApp::signalHandler, this));
+  // boost::bind(&NdnTlvPingServer::signalHandler, this)
+
+  Name name(m_prefix);
+  name.append(Query::toString(Query::QUERY_DNS_R));
+
+  m_face.setInterestFilter(name,
+      bind(&NameCachingResolver::onInterest, this, _1, _2),
+      bind(&NDNApp::onRegisterFailed, this, _1, _2));
+
+  std::cout << "\n=== NDNS Resolver " << m_programName
+      << " with routeble prefix " << name.toUri() << " starts";
+
+  if (this->m_enableForwardingHint > 0) {
+    std::cout<<" & Root Zone ForwardingHint "<<this->m_rootZoneFowardingHint.toUri();
+  }
+  std::cout<<"==="<< std::endl;
+
+  try {
+    m_face.processEvents();
+  } catch (std::exception& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    m_hasError = true;
+    m_ioService.stop();
+  }
+}
+template <class IQStrategy> void
+NameCachingResolver<IQStrategy>::onData(const Interest& interest, Data &data, IQStrategy& iq)
+{
+  /*
+  if (interest.getName() != iq.getLastInterest().getName()) {
+    std::cout << iq << std::endl;
+    std::cout << "waiting for " << iq.getLastInterest().getName().toUri()
+        << std::endl;
+    std::cout << "coming data " << data.getName().toUri() << std::endl;
+    return;
+  }*/
+
+  iq.doData(data);
+
+  if (iq.getStep() == IterativeQuery::AnswerStub) {
+    Data data = iq.getLastResponse().toData();
+    Name name = iq.getQuery().getAuthorityZone();
+    name.append(Query::toString(iq.getQuery().getQueryType()));
+    name.append(iq.getQuery().getRrLabel());
+    name.append(RR::toString(iq.getQuery().getRrType()));
+    name.appendVersion();
+    data.setName(name);
+    data.setFreshnessPeriod(iq.getLastResponse().getFreshness());
+
+    m_keyChain.sign(data);
+    m_face.put(data);
+    std::cout << "[* <- *] answer Response ("
+        << Response::toString(iq.getLastResponse().getResponseType())
+        << ") to stub:" << std::endl;
+    std::cout << iq.getLastResponse() << std::endl;
+    for (int i = 0; i < 15; i++) {
+      std::cout << "----";
+    }
+    std::cout << std::endl << std::endl;
+
+    //iq.setStep(IterativeQuery::FinishedSuccessfully);
+
+  } else if (iq.getStep() == IterativeQuery::NSQuery) {
+    resolve(iq);
+  } else if (iq.getStep() == IterativeQuery::RRQuery) {
+    resolve(iq);
+  } else if (iq.getStep() == IterativeQuery::Abort) {
+    return;
+  } else if (iq.getStep() == IterativeQuery::FHQuery) {
+    resolve(iq);
+  }
+  else {
+    std::cout << "let me see the current step="
+        << IterativeQuery::toString(iq.getStep()) << std::endl;
+    std::cout << iq;
+    std::cout<<std::endl;
+  }
+
+}
+
+template <class IQStrategy> void
+NameCachingResolver<IQStrategy>::onInterest(const Name &name, const Interest &interest)
+{
+  Query query;
+  query.fromInterest(interest);
+  std::cout << "[* -> *] receive Interest: " << interest.getName().toUri()
+      << std::endl;
+  if (query.getQueryType() == Query::QUERY_DNS) {
+    cout << m_programName << " is not in charge of Query_DNS" << endl;
+  }
+
+  IQStrategy iq(query);
+
+  if (this->m_enableForwardingHint == 0) {
+
+  } else if (this->m_enableForwardingHint > 0) {
+    //std::cout<<"--------------------create a Forwarding Hint"<<std::endl;
+    IterativeQueryWithFowardingHint& iqfh =dynamic_cast<IterativeQueryWithFowardingHint&>(iq);
+    iqfh.setForwardingHint(this->m_rootZoneFowardingHint);
+    iqfh.setLastForwardingHint(this->m_rootZoneFowardingHint);
+  }
+  resolve(iq);
+}
+
+template <class IQStrategy> void
+NameCachingResolver<IQStrategy>::onTimeout(const Interest& interest, IQStrategy& iq)
+{
+  std::cout << "[* !! *] timeout Interest " << interest.getName().toUri()
+      << " timeouts" << std::endl;
+
+  iq.doTimeout();
+}
+
+template <class IQStrategy>
+void NameCachingResolver<IQStrategy>::resolve(IQStrategy& iq)
+{
+
+  Interest interest = iq.toLatestInterest();
+
+  //must be set before express interest,since the call will back call iq
+  //if set after, then the iq in call of onData will return nothing
+  //be very careful here,  as a new guy to c++
+
+  interest.setInterestLifetime(this->getInterestLifetime());
+  iq.setLastInterest(interest);
+  /*
+  if (this->m_enableForwardingHint > 0)
+  {
+    //iq = (IterativeQueryWithFowardingHint)iq;
+    iq = dynamic_cast<IterativeQueryWithFowardingHint>iq;
+  }
+  */
+  std::cout<<"lastInterest="<<iq.getLastInterest()<<std::endl;
+
+  try {
+    m_face.expressInterest(interest,
+        boost::bind(&NameCachingResolver::onData, this, _1, _2, iq),
+        boost::bind(&NameCachingResolver::onTimeout, this, _1,  iq));
+        //boost::bind(&NameCachingResolver::onData, this, _1, _2, ndn::ref(iq)),
+        //boost::bind(&NameCachingResolver::onTimeout, this, _1, iq));
+  } catch (std::exception& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+  }
+
+  std::cout << "[* <- *] send Interest: " << interest.getName().toUri()
+      << std::endl;
+  std::cout << iq << std::endl;
+}
 } /* namespace ndns */
 } /* namespace ndn */
 
diff --git a/src/app/name-dig.cpp b/src/app/name-dig.cpp
index 6e64e31..a95a0d0 100644
--- a/src/app/name-dig.cpp
+++ b/src/app/name-dig.cpp
@@ -22,45 +22,43 @@
 namespace ndns {
 
 NameDig::NameDig(const char *programName, const char *prefix)
-: NDNApp(programName, prefix)
-, m_resolverName(Name("/"))
-, m_dstLabel(Name(prefix)){
+  : NDNApp(programName, prefix)
+  , m_resolverName(Name("/"))
+  , m_dstLabel(Name(prefix))
+  , m_rrType(RR::TXT)
+{
   //prefix in this app is the m_dstLabel
   this->setInterestLifetime(time::milliseconds(10000));
 }
 
-NameDig::~NameDig() {
+NameDig::~NameDig()
+{
   // TODO Auto-generated destructor stub
 }
 
-void
-NameDig::onData(const Interest& interest, Data& data)
+void NameDig::onData(const Interest& interest, Data& data)
 {
   Response re;
   re.fromData(data);
-  cout<<"get data:->"<<data.getName()<<endl;
-  cout<<"get response:->"<<re<<endl;
+  cout << "get data:->" << data.getName() << endl;
+  cout << "get response:->" << re << endl;
 
-
+  response = re;
 
   m_rrs = re.getRrs();
 
-
-
   vector<RR>::iterator iter = m_rrs.begin();
 
-  while (iter != m_rrs.end())
-  {
+  while (iter != m_rrs.end()) {
     RR rr = *iter;
-    cout<<rr<<endl;
-    iter ++;
+    cout << rr << endl;
+    iter++;
   }
 
   this->stop();
 }
 
-void
-NameDig::sendQuery()
+void NameDig::sendQuery()
 {
   Query q;
   q.setAuthorityZone(this->m_resolverName);
@@ -72,46 +70,39 @@
   interest.setInterestLifetime(this->m_interestLifetime);
   try {
     m_face.expressInterest(interest,
-            boost::bind(&NameDig::onData, this, _1, _2),
-            boost::bind(&NameDig::onTimeout, this, _1)
-            );
-    std::cout<<"[* <- *] send Interest: "<<interest.getName().toUri()<<std::endl;
-  }catch(std::exception& e) {
+        boost::bind(&NameDig::onData, this, _1, _2),
+        boost::bind(&NameDig::onTimeout, this, _1));
+    std::cout << "[* <- *] send Interest: " << interest.getName().toUri()
+        << std::endl;
+  } catch (std::exception& e) {
     m_hasError = true;
     m_error = e.what();
   }
   m_interestTriedNum += 1;
 }
 
-void
-NameDig::onTimeout(const Interest& interest)
+void NameDig::onTimeout(const Interest& interest)
 {
-  std::cout<<"[* !! *] timeout Interest"<<interest.getName()<<std::endl;
+  std::cout << "[* !! *] timeout Interest" << interest.getName() << std::endl;
 
-  if (m_interestTriedNum >= m_interestTriedMax)
-  {
+  if (m_interestTriedNum >= m_interestTriedMax) {
     m_error = "All Interests timeout";
     m_hasError = true;
     this->stop();
-  } else
-  {
+  } else {
     sendQuery();
   }
 
 }
 
-void
-NameDig::run()
+void NameDig::run()
 {
 
   this->sendQuery();
 
-  try
-  {
+  try {
     m_face.processEvents();
-  }
-  catch (std::exception& e)
-  {
+  } catch (std::exception& e) {
     m_error = e.what();
     m_hasError = true;
     this->stop();
diff --git a/src/app/name-dig.hpp b/src/app/name-dig.hpp
index 475cf26..3f07a1e 100644
--- a/src/app/name-dig.hpp
+++ b/src/app/name-dig.hpp
@@ -27,7 +27,8 @@
 namespace ndn {
 namespace ndns {
 
-class NameDig: public NDNApp {
+class NameDig: public NDNApp
+{
 public:
   NameDig(const char *programName, const char *prefix);
   virtual ~NameDig();
@@ -35,7 +36,6 @@
   void
   onData(const ndn::Interest& interest, Data& data);
 
-
   void
   onTimeout(const ndn::Interest& interest);
 
@@ -45,45 +45,63 @@
   void
   run();
 
-  const vector<RR>& getRrs() const {
+  const vector<RR>& getRrs() const
+  {
     return m_rrs;
   }
 
-  void setRrs(const vector<RR>& rrs) {
+  void setRrs(const vector<RR>& rrs)
+  {
     m_rrs = rrs;
   }
 
-  const Name& getResolverName() const {
+  const Name& getResolverName() const
+  {
     return m_resolverName;
   }
 
-  void setResolverName(const Name& resolverName) {
+  void setResolverName(const Name& resolverName)
+  {
     m_resolverName = resolverName;
   }
 
-
-
-  const Name& getDstLabel() const {
+  const Name& getDstLabel() const
+  {
     return m_dstLabel;
   }
 
-  void setDstLabel(const Name& dstLabel) {
+  void setDstLabel(const Name& dstLabel)
+  {
     m_dstLabel = dstLabel;
   }
 
-  RR::RRType getRrType() const {
+  RR::RRType getRrType() const
+  {
     return m_rrType;
   }
 
-  void setRrType(RR::RRType rrType) {
+  void setRrType(RR::RRType rrType)
+  {
     m_rrType = rrType;
   }
 
+  const Response& getResponse() const
+  {
+    return response;
+  }
+
+  void setResponse(const Response& response)
+  {
+    this->response = response;
+  }
+
 private:
   Name m_resolverName;
   Name m_dstLabel;
   RR::RRType m_rrType;
   vector<RR> m_rrs;
+
+  Response response;
 };
 
 } /* namespace ndns */
diff --git a/src/app/name-server.cpp b/src/app/name-server.cpp
index 6e6428d..99ceb19 100644
--- a/src/app/name-server.cpp
+++ b/src/app/name-server.cpp
@@ -18,39 +18,38 @@
  */
 #include "name-server.hpp"
 
-
-namespace ndn{
-namespace ndns{
-NameServer::NameServer(const char *programName, const char *prefix, const char *nameZone)
-: NDNApp(programName, prefix)
-, m_zone(Name(nameZone))
-, m_zoneMgr(m_zone)
+namespace ndn {
+namespace ndns {
+NameServer::NameServer(const char *programName, const char *prefix,
+    const char *nameZone, const string dbfile)
+  : NDNApp(programName, prefix)
+  , m_zone(Name(nameZone))
+  , m_zoneMgr(m_zone)
 {
+  m_zoneMgr.setDbfile(dbfile);
   //m_zoneMgr.lookupId();
-}//NameServer Construction
+} //NameServer Construction
 
-
-void
-NameServer::onInterest(const Name &name, const Interest &interest)
+void NameServer::onInterest(const Name &name, const Interest &interest)
 {
 
-  cout<<"[* -> *] receive Interest: "<<interest.getName().toUri()<<std::endl;
+  cout << "[* -> *] receive Interest: " << interest.getName().toUri()
+      << std::endl;
   Query query;
-  if (!query.fromInterest(interest))
-  {
-    cout<<"can resolve the Query from Interest: "<<endl;
+  if (!query.fromInterest(interest)) {
+    cout << "can resolve the Query from Interest: " << endl;
     return;
   }
 
   /*
    * query.getAuthorityZone is routable name, not the zone's service name
-  if (query.getAuthorityZone() != m_zoneMgr.getZone().getAuthorizedName())
-  {
-    cout<<"Query is intent to zone: "<<query.getAuthorityZone()
-        <<". This is "<<m_zoneMgr.getZone().getAuthorizedName()<<endl;
-    return;
-  }
-  */
+   if (query.getAuthorityZone() != m_zoneMgr.getZone().getAuthorizedName())
+   {
+   cout<<"Query is intent to zone: "<<query.getAuthorityZone()
+   <<". This is "<<m_zoneMgr.getZone().getAuthorizedName()<<endl;
+   return;
+   }
+   */
 
   Response response;
   Name name2 = interest.getName();
@@ -58,28 +57,23 @@
   response.setQueryName(name2);
   RRMgr mgr(m_zone, query, response);
 
-
-  if (mgr.lookup()<0)
-  {
-    cout<<"[* !! *] lookup error, then exit: "<<mgr.getErr()<<endl;
+  if (mgr.lookup() < 0) {
+    cout << "[* !! *] lookup error, then exit: " << mgr.getErr() << endl;
     return;
   }
 
-  if (response.getRrs().size() >0)
-  {
+  if (response.getRrs().size() > 0) {
     response.setResponseType(Response::NDNS_Resp);
   } else {
 
     if (query.getRrType() == RR::NS) {
       int count = mgr.count();
-      if (count < 0)
-      {
-        cout<<"[* !! *] lookup error, then exit: "<<mgr.getErr()<<endl;
+      if (count < 0) {
+        cout << "[* !! *] lookup error, then exit: " << mgr.getErr() << endl;
         return;
-      } else if (count > 0)
-      {
+      } else if (count > 0) {
         response.setResponseType(Response::NDNS_Auth);
-      } else{
+      } else {
         response.setResponseType(Response::NDNS_Nack);
       }
     } else {
@@ -87,56 +81,63 @@
     }
   }
 
-
   Data data = response.toData();
   data.setFreshnessPeriod(response.getFreshness());
 
   m_keyChain.sign(data);
   m_face.put(data);
-  cout<<"[* <- *] send response: "<<response<<": "<<data<<endl;
-}//onInterest
+  cout << "[* <- *] send response: " << response << ": " << data << endl;
+} //onInterest
 
-
-void
-NameServer::run()
+void NameServer::run()
 {
   //m_zoneMgr.lookupId();
-  if (m_zoneMgr.getZone().getId() == 0)
-  {
+  if (m_zoneMgr.getZone().getId() == 0) {
     m_hasError = true;
-    m_error = "cannot get Zone.id from database for name="+m_zone.getAuthorizedName().toUri();
+    m_error = "cannot get Zone.id from database for name="
+        + m_zone.getAuthorizedName().toUri();
     stop();
   }
 
   boost::asio::signal_set signalSet(m_ioService, SIGINT, SIGTERM);
   signalSet.async_wait(boost::bind(&NDNApp::signalHandler, this));
- // boost::bind(&NdnTlvPingServer::signalHandler, this)
+  // boost::bind(&NdnTlvPingServer::signalHandler, this)
   Name name;
   name.set(m_prefix);
   name.append(Query::toString(Query::QUERY_DNS));
 
-  m_face.setInterestFilter(name,
-               bind(&NameServer::onInterest,
-                  this, _1, _2),
-               bind(&NDNApp::onRegisterFailed,
-                  this, _1,_2));
+  std::cout<<"========= NDNS Name Server for Zone "
+            <<m_zoneMgr.getZone().getAuthorizedName().toUri()
+            <<" Starts with Prefix "<<m_prefix;
+  if (m_enableForwardingHint > 0) {
+    std::cout<<" & ForwardingHint "<<m_forwardingHint.toUri();
+  }
+    std::cout<<"============="<<std::endl;
 
-  std::cout << "\n=== NDNS Server for Zone "
-            << m_zoneMgr.getZone().getAuthorizedName().toUri()
-            <<" with routable prefix "<< name.toUri()
-            << " starts===\n" << std::endl;
+  m_face.setInterestFilter(name, bind(&NameServer::onInterest, this, _1, _2),
+      bind(&NDNApp::onRegisterFailed, this, _1, _2));
+ std::cout<<"Name Server Register Name Prefix: "<<name<<std::endl;
+
+  if (m_enableForwardingHint > 0) {
+    Name name2 = Name(m_forwardingHint);
+    name2.append(ndn::ndns::label::ForwardingHintLabel);
+    name2.append(name);
+    m_face.setInterestFilter(name2, bind(&NameServer::onInterest, this, _1, _2),
+        bind(&NDNApp::onRegisterFailed, this, _1, _2));
+    std::cout<<"Name Server Register Name Prefix: "<<name2<<std::endl;
+  }
+
 
   try {
     m_face.processEvents();
-  }
-  catch (std::exception& e) {
+  } catch (std::exception& e) {
     m_hasError = true;
     m_error = "ERROR: ";
     m_error += e.what();
     stop();
   }
 
-}//run
+} //run
 
 } //namespace ndns
 } /* namespace ndn */
diff --git a/src/app/name-server.hpp b/src/app/name-server.hpp
index 9d6f5cd..5c2f109 100644
--- a/src/app/name-server.hpp
+++ b/src/app/name-server.hpp
@@ -38,29 +38,28 @@
 using namespace std;
 using namespace ndn;
 
-
-namespace ndn{
-namespace ndns{
-class NameServer : public NDNApp
+namespace ndn {
+namespace ndns {
+class NameServer: public NDNApp
 {
 
 public:
-explicit
-NameServer(const char *programName, const char *prefix, const char *nameZone);
+  explicit
+  NameServer(const char *programName, const char *prefix, const char *nameZone,
+      const string dbfile = "src/db/ndns-local.db");
 
-void
-onInterest(const Name &name, const Interest &interest);
+  void
+  onInterest(const Name &name, const Interest &interest);
 
-
-void
-run();
+  void
+  run();
 
 public:
   /*
    * the name used by the server to provide routeable accessory.
 
-  Name m_name;
-  */
+   Name m_name;
+   */
   /*
    * the zone the server is in charge of
    */
@@ -71,7 +70,8 @@
    */
   ZoneMgr m_zoneMgr;
 
-};//clcass NameServer
+};
+//clcass NameServer
 }//namespace ndns
-}//namespace ndn
+} //namespace ndn
 #endif /* NAME_SERVER_HPP_ */
diff --git a/src/app/ndn-app.cpp b/src/app/ndn-app.cpp
index b8f123a..f7804f2 100644
--- a/src/app/ndn-app.cpp
+++ b/src/app/ndn-app.cpp
@@ -30,6 +30,8 @@
   , m_interestTriedMax(2)
   , m_interestTriedNum(0)
   , m_face(m_ioService)
+  , m_enableForwardingHint(0)
+  , m_forwardingHint("/")
 {
 }
 
@@ -39,9 +41,5 @@
   m_prefix = 0;
 }
 
-
-
-
-
 } //namespace ndns
 } /* namespace ndn */
diff --git a/src/app/ndn-app.hpp b/src/app/ndn-app.hpp
index 00595ea..13130e2 100644
--- a/src/app/ndn-app.hpp
+++ b/src/app/ndn-app.hpp
@@ -28,28 +28,29 @@
 #include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/noncopyable.hpp>
 
+#include "ndns-label.hpp"
+
 using namespace std;
 
 namespace ndn {
-namespace ndns{
+namespace ndns {
 
-class NDNApp {
+class NDNApp
+{
 public:
   NDNApp(const char *programName, const char *prefix);
   virtual ~NDNApp();
 
-  virtual void
-  onData(const ndn::Interest& interest, Data& data)
+  virtual void onData(const ndn::Interest& interest, Data& data)
   {
   }
-  virtual void
-  onTimeout(const ndn::Interest& interest)
+  virtual void onTimeout(const ndn::Interest& interest)
   {
-    std::cout<<"!- Interest Timeout"<<interest.getName()<<std::endl;
+    std::cout << "!- Interest Timeout" << interest.getName() << std::endl;
   }
 
-  virtual void
-  onRegisterFailed(const ndn::Name& prefix, const std::string& reason)
+  virtual void onRegisterFailed(const ndn::Name& prefix,
+      const std::string& reason)
   {
     m_error = "ERROR: Failed to register prefix in local hub's daemon";
     m_error += " due to: ";
@@ -58,95 +59,120 @@
     this->stop();
   }
 
-
-  virtual void
-  onInterest(const Name &name, const Interest& interest)
+  virtual void onInterest(const Name &name, const Interest& interest)
   {
 
   }
 
-  virtual void
-  signalHandler()
+  virtual void signalHandler()
   {
     this->stop();
     exit(1);
   }
 
-
-  virtual void
-  stop()
+  virtual void stop()
   {
-    std::cout<<m_programName<<" stops"<<std::endl;
+    std::cout << m_programName << " stops" << std::endl;
     m_ioService.stop();
     m_face.shutdown();
-    if (hasError())
-    {
-      cout<<m_error<<endl;
+    if (hasError()) {
+      cout << m_error << endl;
     }
   }
 
-
-
-  bool hasError() const {
+  bool hasError() const
+  {
     return m_hasError;
   }
 
-  void setHasError(bool hasError) {
+  void setHasError(bool hasError)
+  {
     m_hasError = hasError;
   }
 
-  const char* getPrefix() const {
+  const char* getPrefix() const
+  {
     return m_prefix;
   }
 
-  void setPrefix(char* prefix) {
+  void setPrefix(char* prefix)
+  {
     m_prefix = prefix;
   }
 
-  const char* getProgramName() const {
+  const char* getProgramName() const
+  {
     return m_programName;
   }
 
-  void setProgramName(char* programName) {
+  void setProgramName(char* programName)
+  {
     m_programName = programName;
   }
 
-  const string& getErr() const {
+  const string& getErr() const
+  {
     return m_error;
   }
 
-  void setErr(const string& err) {
+  void setErr(const string& err)
+  {
     m_error = err;
   }
 
-  uint32_t getInterestTriedMax() const {
+  uint32_t getInterestTriedMax() const
+  {
     return m_interestTriedMax;
   }
 
-  void setInterestTriedMax(uint32_t interestTriedMax) {
+  void setInterestTriedMax(uint32_t interestTriedMax)
+  {
     m_interestTriedMax = interestTriedMax;
   }
 
-  time::milliseconds getContentFreshness() const {
+  time::milliseconds getContentFreshness() const
+  {
     return m_contentFreshness;
   }
 
-  void setContentFreshness(time::milliseconds contentFreshness) {
+  void setContentFreshness(time::milliseconds contentFreshness)
+  {
     m_contentFreshness = contentFreshness;
   }
 
-  time::milliseconds getInterestLifetime() const {
+  time::milliseconds getInterestLifetime() const
+  {
     return m_interestLifetime;
   }
 
-  void setInterestLifetime(time::milliseconds interestLifetime) {
+  void setInterestLifetime(time::milliseconds interestLifetime)
+  {
     m_interestLifetime = interestLifetime;
   }
 
-public:
+  const Name& getForwardingHint() const
+  {
+    return m_forwardingHint;
+  }
+
+  void setForwardingHint(const Name& forwardingHint)
+  {
+    m_forwardingHint = forwardingHint;
+  }
+
+  unsigned short getEnableForwardingHint() const
+  {
+    return m_enableForwardingHint;
+  }
+
+  void setEnableForwardingHint(unsigned short enableForwardingHint)
+  {
+    m_enableForwardingHint = enableForwardingHint;
+  }
+
+protected:
   const char* m_programName;
-  const char* m_prefix;
-  bool m_hasError;
+  const char* m_prefix;bool m_hasError;
   string m_error;
   time::milliseconds m_contentFreshness;
   time::milliseconds m_interestLifetime;
@@ -159,9 +185,14 @@
   //Zone m_zone;
   //ZoneMgr m_zoneMgr;
 
-
   Face m_face;
   KeyChain m_keyChain;
+
+  /**
+   * forwarding hint
+   */
+  unsigned short m_enableForwardingHint;
+  Name m_forwardingHint;
 };
 
 } //namespace ndns
diff --git a/src/db/db-mgr.cpp b/src/db/db-mgr.cpp
index 5ab9db1..baabad8 100644
--- a/src/db/db-mgr.cpp
+++ b/src/db/db-mgr.cpp
@@ -26,25 +26,22 @@
 namespace ndns {
 
 DBMgr::DBMgr()
-: m_dbfile("src/db/ndns-local.db")
-, m_conn(0)
-, m_reCode(-1)
-, m_status(DBClosed)
-, m_resultNum(0)
+  : m_dbfile("src/db/ndns-local.db")
+  , m_conn(0)
+  , m_reCode(-1)
+  , m_status(DBClosed)
+  , m_resultNum(0)
 {
   std::fstream file;
-  file.open(m_dbfile,std::ios::in);
-  if (file)
-  {
-    std::cout<<"database file "<<m_dbfile<<" does exist"<<std::endl;
-  } else
-  {
-    std::cout<<"database file "<<m_dbfile<<" does not exist"<<std::endl;
+  file.open(m_dbfile, std::ios::in);
+  if (file) {
+    std::cout << "database file " << m_dbfile << " does exist" << std::endl;
+  } else {
+    std::cout << "database file " << m_dbfile << " does not exist" << std::endl;
   }
 
 }
 
-
 DBMgr::~DBMgr()
 {
 }
@@ -55,14 +52,12 @@
     return;
 
   m_reCode = sqlite3_open(this->m_dbfile.c_str(), &(this->m_conn));
-  if (m_reCode != SQLITE_OK)
-  {
-    m_err = "Cannot connect to the db: "+this->m_dbfile;
+  if (m_reCode != SQLITE_OK) {
+    m_err = "Cannot connect to the db: " + this->m_dbfile;
     m_status = DBError;
     //exit(1);
-  }else
-  {
-    std::cout<<"connect to the db: "<<m_dbfile<<std::endl;
+  } else {
+    std::cout << "connect to the db: " << m_dbfile << std::endl;
   }
   m_status = DBConnected;
 }
@@ -73,15 +68,15 @@
     return;
 
   m_reCode = sqlite3_close(this->m_conn);
-  if (m_reCode != SQLITE_OK)
-  {
-        m_err = "Cannot close the db: "+this->m_dbfile;
-        m_status = DBError;
+  if (m_reCode != SQLITE_OK) {
+    m_err = "Cannot close the db: " + this->m_dbfile;
+    m_status = DBError;
   }
   m_status = DBClosed;
 }
 
-void DBMgr::execute(std::string sql, int (*callback)(void*,int,char**,char**), void * paras)
+void DBMgr::execute(std::string sql,
+    int (*callback)(void*, int, char**, char**), void * paras)
 {
   if (m_status == DBClosed)
     this->open();
@@ -89,15 +84,14 @@
   clearResultNum();
   char *err_msg;
   m_reCode = sqlite3_exec(m_conn, sql.c_str(), callback, paras, &err_msg);
-  if (m_reCode != SQLITE_OK)
-  {
+  if (m_reCode != SQLITE_OK) {
     m_status = DBError;
     this->m_err.append(err_msg);
-    std::cout<<this->m_err<<std::endl;
+    std::cout << this->m_err << std::endl;
   }
   this->close();
 }
 
-}//namespace ndns
-}//namespace ndn
+} //namespace ndns
+} //namespace ndn
 
diff --git a/src/db/db-mgr.hpp b/src/db/db-mgr.hpp
index c6445af..ab016e1 100644
--- a/src/db/db-mgr.hpp
+++ b/src/db/db-mgr.hpp
@@ -23,19 +23,15 @@
 #include <sqlite3.h>
 #include <iostream>
 
-
 namespace ndn {
 namespace ndns {
 
-
 class DBMgr
 {
 public:
   enum m_status
   {
-    DBConnected,
-    DBClosed,
-    DBError
+    DBConnected, DBClosed, DBError
   };
 
 public:
@@ -44,57 +40,68 @@
 
   void open();
   void close();
-  void execute(std::string sql,
-        int (*callback)(void*,int,char**,char**), void * paras);
+  void execute(std::string sql, int (*callback)(void*, int, char**, char**),
+      void * paras);
 
-  inline void addResultNum(){
+  inline void addResultNum()
+  {
     m_resultNum += 1;
   }
-  inline void clearResultNum() {
+  inline void clearResultNum()
+  {
     m_resultNum = 0;
   }
 
-  const std::string& getDbfile() const {
+  const std::string& getDbfile() const
+  {
     return m_dbfile;
   }
 
-  void setDbfile(const std::string& dbfile) {
+  void setDbfile(const std::string& dbfile)
+  {
     this->m_dbfile = dbfile;
   }
 
-  const std::string& getErr() const {
+  const std::string& getErr() const
+  {
     return m_err;
   }
 
-  void setErr(const std::string& err) {
+  void setErr(const std::string& err)
+  {
     this->m_err = err;
   }
 
-  int getReCode() const {
+  int getReCode() const
+  {
     return m_reCode;
   }
 
-  void setReCode(int reCode) {
+  void setReCode(int reCode)
+  {
     this->m_reCode = reCode;
   }
 
-  m_status getStatus() const {
+  m_status getStatus() const
+  {
     return m_status;
   }
 
-  void setStatus(m_status status) {
+  void setStatus(m_status status)
+  {
     this->m_status = status;
   }
 
-  int getResultNum() const {
+  int getResultNum() const
+  {
     return m_resultNum;
   }
 
-  void setResultNum(int resultNum) {
+  void setResultNum(int resultNum)
+  {
     m_resultNum = resultNum;
   }
 
-
 private:
   std::string m_dbfile;
   sqlite3 *m_conn;
@@ -102,8 +109,9 @@
   int m_reCode;
   m_status m_status;
   int m_resultNum;
-}; //class DBMgr
+};
+//class DBMgr
 }//namespace ndns
-}//namespace ndn
+} //namespace ndn
 
 #endif
diff --git a/src/db/ndns-db-data-demo.sql b/src/db/ndns-db-data-demo.sql
index 8564207..6567c5b 100644
--- a/src/db/ndns-db-data-demo.sql
+++ b/src/db/ndns-db-data-demo.sql
@@ -1,4 +1,7 @@
-
+/*
+sqlite3 src/db/ndns-local.db
+.read ndns-db-data-demo.sql
+*/
 delete from rrs;
 delete from rrsets;
 delete from zones;
@@ -8,33 +11,102 @@
                   (2, "/net"),
                   (3, "/net/ndnsim"),
                   (4, "/dns/google/com"),
-                  (5, "/net/ndnsim/git/doc")
+                  (5, "/net/ndnsim/git/doc"),
+                  
+                  (6, "/com"),
+                  (7, "/com/skype")
                   ;
 
 insert into rrsets (id, zone_id, label, class, type, ndndata) values
+                  /* NS of sub-domain */
+                   (4,   1,     "/net",  NULL,   "NS", NULL),
+                   (3,   2,     "/ndnsim", NULL, "NS", NULL),
+                   (7,   3,     "/git/doc", NULL, "NS", NULL),
+                   
+                    /* FH of NS (name servers) */
+                   (21,  1,     "/net/ns1", NULL, "FH", NULL),
+                   (18,  2,     "/net/ndnsim/ns1", NULL, "FH", NULL),   
+                   (19,  3,     "/net/ndnsim/git/doc/ns1", NULL, "FH", NULL),
+              
+                   /* TXT of service/app*/
                    (1,   3,     "/www", NULL, "TXT", NULL),
                    (2,   3,     "/doc", NULL, "TXT", NULL),
-                   (3,   2,     "/ndnsim", NULL, "NS", NULL),
-                   (4,   1,     "/net",  NULL,   "NS", NULL),
-                   (5,   4,     "/net",  NULL,   "NS", NULL),
                    (6,   3,     "/git/www", NULL, "TXT", NULL),
-                   (7,   3,     "/git/doc", NULL, "NS", NULL),
-                   (8,   5,     "/www", NULL, "TXT", NULL),
                    (9,   3,     "/repo/www", NULL, "TXT", NULL),
-                   (10,  3,     "/norrdata", NULL, "TXT", NULL)
+                   (8,   5,     "/www", NULL, "TXT", NULL),
+                   (10,  3,     "/norrdata", NULL, "TXT", NULL),
+           
+                   /* FH of physical hosts, which is not named by hierarchical */
+                   (25,  3,     "/net/ndnsim/www/h1",   NULL, "FH", NULL),
+                   (26,  3,     "/net/ndnsim/h1",   NULL, "FH", NULL),
+                   (27,  3,     "/net/ndnsim/h2",   NULL, "FH", NULL),
+                   (28,  5,     "/net/ndnsim/git/doc/h1", NULL, "FH", NULL),
+                   
+                   /* NDNCERT of domain */
+                   (11,  3,     "/www/dsk-1", NULL, "NDNCERT", NULL),
+                   (12,  3,     "/www/ksk-1", NULL, "NDNCERT", NULL),
+                   (13,  3,     "/dsk-1",     NULL, "NDNCERT", NULL),
+                   (14,  2,     "/ndnsim/ksk-1", NULL, "NDNCERT", NULL),
+                   (15,  2,     "/dsk-1", NULL, "NDNCERT", NULL),
+                   (16,  1,     "/net/ksk-1", NULL, "NDNCERT", NULL),
+                   (17,  1,     "/root",     NULL, "NDNCERT", NULL),
+                   
+                   /* Mobility Support for Skype (NDN rtc in the future) */
+                   (100,  1,    "/com",         NULL, "NS", NULL),
+                   (101,  6,    "/skype",   NULL, "NS", NULL),
+                   (102,  1,    "/com/ns1",     NULL, "FH", NULL),
+                   (103,  6,    "/com/skype/ns1", NULL, "FH", NULL),
+                   
+                   (105,  7,    "/shock",  NULL, "FH",   NULL),
+                   (106,  7,    "/alex",   NULL,  "FH",  NULL),
+                   (107,  7,    "/lixia",   NULL,  "FH",  NULL),
+                   (108,  7,    "/yiding",   NULL,  "FH",  NULL)
                    ;
                    
                    
 insert into rrs (id, rrset_id, ttl, rrdata) values
-                (1, 1, 3600, "/ucla"),
-                (2, 1, 8000, "/att"),
-                (3, 2, 3600, "/ucla"),
-                (4, 3, 4000, "/net/ndnsim2"),
-                (5, 4, 5000, "/net"),
-                (6, 5, 6000, "/net"),
-                (7, 3, 4000, "/net/ndnsim"),
-                (8, 6, 3000, "/net/ndnsim/git/www"),
-                (9, 7, 3000, "/net/ndnsim/git/doc"),
-                (10,8, 3000, "/net/ndnsim/git/doc/www"),
-                (11,9, 3000, "/net/ndnsim/repo/www")
+                /* NS */
+                (31, 4,  3600, "/net/ns1"),
+                (32, 3,  3600, "/net/ndnsim/ns1"),
+                (33, 7,  3600, "/net/ndnsim/git/doc/ns1"),
+                
+                /* FH of NS (name server) */
+                (20,  21, 3600, "/sprint"),
+                (21,  18, 3600, "/ucla"),
+                (22,  19, 3600, "/ucla"), 
+                
+                /* TXT of service/app */
+                (1, 1, 3600, "/net/ndnsim/www/h1"),
+                (2, 1, 8000, "/net/ndnsim/h1"),
+                (3, 2, 3600, "/net/ndnsim/www/h1"),
+                (8, 6, 3000, "/net/ndnsim/h1"),
+                (11,9, 3000, "/net/ndnsim/h2"),
+                (10,8, 3000, "/net/ndnsim/git/doc/h1"),
+                
+                /* rrdata of FH of physical hosts, rrdata is FH */
+                (25,  25,   3000, "/ucla"),
+                (26,  26,   3000, "/ucla"),
+                (27,  27,   3000, "/ucla"),
+                (28,  28,   3000, "/ucla"),
+                
+                 /* NDNCERT*/
+                (12,11,3000, "/net/ndnsim/DNS/www/dsk-1:010010101101010101"),
+                (13,12,3000, "/net/ndnsim/DNS/www/ksk-1:0101111010001111110"),
+                (14,13,3000, "/net/ndnsim/DNS/dsk-1:1010110101"),
+                (15,14,3000, "/net/DNS/ndnsim/ksk-1:0101010101010111100011010"),
+                (16,15,3000, "/net/DNS/dsk-1:01111010101036654646"),
+                (17,16,3000, "/DNS/net/ksk-1:43a13f1a3d13a"),
+                (18,17,3000, "/KEY/ROOT:44631346541aaaf"),
+                
+                /* Mobility Support for Skype */
+                (100, 100,  3000, "/com/ns1"), 
+                (101, 101,  3000, "/com/skype/ns1"),
+                (102, 102,  3000, "/bt"),
+                (103, 103,  3000, "/verizon"),
+                
+                (104, 105,  3000, "/ucla"),
+                (105, 105,  3000, "/att"),
+                (106, 106,  3000, "/ucla"),
+                (107, 107,  3000, "/ucla"),
+                (108, 108,  3000, "/ucla")
                 ;
diff --git a/src/db/ndns-local.db b/src/db/ndns-local.db
index a9177ca..b844390 100644
--- a/src/db/ndns-local.db
+++ b/src/db/ndns-local.db
Binary files differ
diff --git a/src/db/rr-mgr.cpp b/src/db/rr-mgr.cpp
index 51e0e3b..0d4588d 100644
--- a/src/db/rr-mgr.cpp
+++ b/src/db/rr-mgr.cpp
@@ -8,7 +8,7 @@
 #include "rr-mgr.hpp"
 
 namespace ndn {
-namespace ndns{
+namespace ndns {
 RRMgr::RRMgr(Zone& zone, Query& query, Response& response)
   : m_count(0U)
   , m_zone(zone)
@@ -18,18 +18,15 @@
 
 }
 
-
-RRMgr::~RRMgr() {
+RRMgr::~RRMgr()
+{
   // TODO Auto-generated destructor stub
 }
 
-
-
-int
-RRMgr::count()
+int RRMgr::count()
 {
   std::string sql;
-  sql =  "SELECT count(*) FROM rrs INNER JOIN rrsets ON rrs.rrset_id=rrsets.id";
+  sql = "SELECT count(*) FROM rrs INNER JOIN rrsets ON rrs.rrset_id=rrsets.id";
   sql += " WHERE rrsets.zone_id=";
   sql += std::to_string(m_zone.getId());
   sql += " AND ";
@@ -37,24 +34,23 @@
   sql += RR::toString(m_query.getRrType());
   sql += "\' AND ";
   sql += "rrsets.label LIKE\'";
-  sql += m_query.getRrLabel().toUri()+"/%\'";
+  sql += m_query.getRrLabel().toUri() + "/%\'";
 
-  std::cout<<"sql="<<sql<<std::endl;
+  std::cout << "sql=" << sql << std::endl;
   this->execute(sql, static_callback_countRr, this);
 
-  if (this->getStatus() == DBMgr::DBError)
-  {
+  if (this->getStatus() == DBMgr::DBError) {
     return -1;
   }
 
   return this->m_count;
 }
-int
-RRMgr::callback_countRr(int argc, char **argv, char **azColName)
+int RRMgr::callback_countRr(int argc, char **argv, char **azColName)
 {
   this->addResultNum();
 
-  std::cout<<this->getResultNum()<<"th result: "<<"count="<<argv[0]<<std::endl;
+  std::cout << this->getResultNum() << "th result: " << "count=" << argv[0]
+      << std::endl;
   m_count = std::atoi(argv[0]);
   return 0;
 }
@@ -63,7 +59,8 @@
 {
   std::string sql;
 
-  sql =  "SELECT rrs.ttl, rrs.rrdata, rrs.id FROM rrs INNER JOIN rrsets ON rrs.rrset_id=rrsets.id";
+  sql =
+      "SELECT rrs.ttl, rrs.rrdata, rrs.id FROM rrs INNER JOIN rrsets ON rrs.rrset_id=rrsets.id";
   sql += " WHERE rrsets.zone_id=";
   sql += std::to_string(m_zone.getId());
   sql += " AND ";
@@ -71,14 +68,13 @@
   sql += RR::toString(m_query.getRrType());
   sql += "\' AND ";
   sql += "rrsets.label=\'";
-  sql += m_query.getRrLabel().toUri()+"\'";
+  sql += m_query.getRrLabel().toUri() + "\'";
   sql += " ORDER BY rrs.id";
 
-  std::cout<<"sql="<<sql<<std::endl;
+  std::cout << "sql=" << sql << std::endl;
   this->execute(sql, static_callback_getRr, this);
 
-  if (this->getStatus() == DBMgr::DBError)
-  {
+  if (this->getStatus() == DBMgr::DBError) {
     return -1;
   }
 
@@ -89,16 +85,16 @@
 int RRMgr::callback_getRr(int argc, char **argv, char **azColName)
 {
   this->addResultNum();
-  if (argc < 1)
-  {
-    this->setErr("No RRType="+RR::toString(m_query.getRrType())+
-        " and label="+m_query.getRrLabel().toUri()+
-        " and zone="+m_zone.getAuthorizedName().toUri());
+  if (argc < 1) {
+    this->setErr(
+        "No RRType=" + RR::toString(m_query.getRrType()) + " and label="
+            + m_query.getRrLabel().toUri() + " and zone="
+            + m_zone.getAuthorizedName().toUri());
     return 0;
   }
 
-  std::cout<<this->getResultNum()<<"th result: "<<"id="<<argv[2]
-           <<" ttl="<<argv[0]<<" rrdata="<<argv[1]<<std::endl;
+  std::cout << this->getResultNum() << "th result: " << "id=" << argv[2]
+      << " ttl=" << argv[0] << " rrdata=" << argv[1] << std::endl;
 
   m_response.setFreshness(time::milliseconds(std::atoi(argv[0])));
 
@@ -108,5 +104,5 @@
   return 0;
 }
 
-}//namespace ndnsn
+}  //namespace ndnsn
 } /* namespace ndn */
diff --git a/src/db/rr-mgr.hpp b/src/db/rr-mgr.hpp
index e940d10..b1f33d0 100644
--- a/src/db/rr-mgr.hpp
+++ b/src/db/rr-mgr.hpp
@@ -25,12 +25,12 @@
 #include "response.hpp"
 #include "zone.hpp"
 
-
 namespace ndn {
-namespace ndns{
-class RRMgr : public DBMgr {
+namespace ndns {
+class RRMgr: public DBMgr
+{
 public:
-  RRMgr( Zone& zone, Query& query, Response& response);
+  RRMgr(Zone& zone, Query& query, Response& response);
   virtual ~RRMgr();
 
 public:
@@ -38,44 +38,50 @@
 
   int callback_getRr(int argc, char **argv, char **azColName);
 
-  static int
-  static_callback_getRr(void *param, int argc, char **argv, char **azColName)
+  static int static_callback_getRr(void *param, int argc, char **argv,
+      char **azColName)
   {
     RRMgr *mgr = reinterpret_cast<RRMgr*>(param);
     return mgr->callback_getRr(argc, argv, azColName);
-   }
+  }
 
   int count();
   int callback_countRr(int argc, char **argv, char **azColName);
 
-  static int
-  static_callback_countRr(void *param, int argc, char **argv, char **azColName)
+  static int static_callback_countRr(void *param, int argc, char **argv,
+      char **azColName)
   {
     RRMgr *mgr = reinterpret_cast<RRMgr*>(param);
     return mgr->callback_countRr(argc, argv, azColName);
-   }
+  }
 
-  const Query& getQuery() const {
+  const Query& getQuery() const
+  {
     return m_query;
   }
 
-  void setQuery(const Query& query) {
+  void setQuery(const Query& query)
+  {
     m_query = query;
   }
 
-  const Response& getResponse() const {
+  const Response& getResponse() const
+  {
     return m_response;
   }
 
-  void setResponse(const Response& response) {
+  void setResponse(const Response& response)
+  {
     m_response = response;
   }
 
-  const Zone& getZone() const {
+  const Zone& getZone() const
+  {
     return m_zone;
   }
 
-  void setZone(const Zone& zone) {
+  void setZone(const Zone& zone)
+  {
     m_zone = zone;
   }
 
@@ -86,8 +92,6 @@
   Response& m_response;
 };
 
-
-
 } //namespace ndns
 } /* namespace ndn */
 
diff --git a/src/db/zone-mgr.cpp b/src/db/zone-mgr.cpp
index cc0b613..4efc285 100644
--- a/src/db/zone-mgr.cpp
+++ b/src/db/zone-mgr.cpp
@@ -19,59 +19,50 @@
 
 #include "zone-mgr.hpp"
 
-
 namespace ndn {
 namespace ndns {
 
-ZoneMgr::ZoneMgr( Zone& zone)
-: m_zone(zone)
+ZoneMgr::ZoneMgr(Zone& zone)
+  : m_zone(zone)
 {
   this->lookupId();
 }
 
-void
-ZoneMgr::lookupId(const Name& name)
+void ZoneMgr::lookupId(const Name& name)
 {
   this->open();
-  std::string sql = "SELECT id FROM zones WHERE name=\'"+name.toUri()+"\'";
+  std::string sql = "SELECT id FROM zones WHERE name=\'" + name.toUri() + "\'";
   //sql = "SELECT * FROM ZONES";
-  std::cout<<"sql="<<sql<<std::endl;
+  std::cout << "sql=" << sql << std::endl;
   //std::cout<<"*this="<<this<<" m_zone.id="<<m_zone.getId()<<" zoneId="<<&m_zone<<std::endl;
   this->execute(sql, static_callback_setId, this);
   //std::cout<<"*this="<<this<<" m_zone.id="<<m_zone.getId()<<" zoneId="<<&m_zone<<std::endl;
   this->close();
 
 }
-int
-ZoneMgr::callback_setId(int argc, char **argv, char **azColName)
+int ZoneMgr::callback_setId(int argc, char **argv, char **azColName)
 {
   //Zone zone = this->getZone();
   this->addResultNum();
 
   Zone zone = this->m_zone;
 
-  if (argc < 1)
-  {
-    this->setErr("No Zone with Name "+zone.getAuthorizedName().toUri());
+  if (argc < 1) {
+    this->setErr("No Zone with Name " + zone.getAuthorizedName().toUri());
     return -1;
   }
   //std::cout<<"id="<<(uint32_t)std::atoi(argv[0])<<" "<<std::endl;
   int t1 = std::atoi(argv[0]);
 
-
   m_zone.setId(t1);
 
   return 0;
 }
-void
-ZoneMgr::lookupId()
+void ZoneMgr::lookupId()
 {
   lookupId(this->m_zone.getAuthorizedName());
 }
 
-
-}//namepsace ndns
-}//namespace ndn
-
-
+} //namepsace ndns
+} //namespace ndn
 
diff --git a/src/db/zone-mgr.hpp b/src/db/zone-mgr.hpp
index 8ced971..faf8f27 100644
--- a/src/db/zone-mgr.hpp
+++ b/src/db/zone-mgr.hpp
@@ -29,11 +29,11 @@
 namespace ndn {
 namespace ndns {
 
-class ZoneMgr : public DBMgr
+class ZoneMgr: public DBMgr
 {
 
 public:
-  ZoneMgr( Zone& zone);
+  ZoneMgr(Zone& zone);
 
 public:
   void
@@ -42,31 +42,32 @@
   void
   lookupId();
 
-   const Zone& getZone() const {
+  const Zone& getZone() const
+  {
     return m_zone;
   }
 
-  void setZone(const Zone& zone) {
+  void setZone(const Zone& zone)
+  {
     this->m_zone = zone;
   }
 
   int
   callback_setId(int argc, char **argv, char **azColName);
 
+  static int static_callback_setId(void *param, int argc, char **argv,
+      char **azColName)
+  {
 
-  static int
-  static_callback_setId(void *param, int argc, char **argv, char **azColName){
-
-     ZoneMgr *mgr = reinterpret_cast<ZoneMgr*>(param);
-     return mgr->callback_setId(argc, argv, azColName);
-   }
+    ZoneMgr *mgr = reinterpret_cast<ZoneMgr*>(param);
+    return mgr->callback_setId(argc, argv, azColName);
+  }
 
 private:
   Zone& m_zone;
-};//class ZoneMgr
-
-
+};
+//class ZoneMgr
 
 }//namespace ndns
-}//namespace ndn
+} //namespace ndn
 #endif
diff --git a/src/iterative-query.cpp b/src/iterative-query.cpp
index 989634a..2f4da51 100644
--- a/src/iterative-query.cpp
+++ b/src/iterative-query.cpp
@@ -22,86 +22,87 @@
 namespace ndns {
 
 IterativeQuery::IterativeQuery(const Query& query)
-: m_step(IterativeQuery::NSQuery)
-, m_tryNum(0)
-, m_tryMax(2)
-, m_query(query)
-, m_finishedLabelNum(0)
-, m_rrLabelLen(1)
-, m_authZoneIndex(0)
+  : m_step(IterativeQuery::NSQuery)
+  , m_tryNum(0)
+  , m_tryMax(2)
+  , m_query(query)
+  , m_finishedLabelNum(0)
+  , m_lastFinishedLabelNum(0)
+  , m_rrLabelLen(1)
+  , m_authZoneIndex(0)
 {
 }
 
-
-bool
-IterativeQuery::doTimeout()
+bool IterativeQuery::doTimeout()
 {
   abort();
   return false;
 }
 
-void
-IterativeQuery::abort(){
-  std::cout<<(*this);
-  std::cout<<std::endl;
-}
+void IterativeQuery::abort()
+ {
+  std::cout<<"Abort the Resolving"<<std::endl;
+   std::cout << (*this);
+   std::cout << std::endl;
+ }
 
-void
-IterativeQuery::doData(Data& data)
+void IterativeQuery::doData(Data& data)
 {
-  std::cout<<"[* -> *] resolve Data: "<<data.getName().toUri()<<std::endl;
+  std::cout << "[* -> *] resolve Data: " << data.getName().toUri() << std::endl;
   Response re;
   re.fromData(data);
-  std::cout<<re<<std::endl;
+  std::cout << re << std::endl;
 
-  if (re.getResponseType() == Response::UNKNOWN)
-  {
-    std::cout<<"[* !! *] unknown content type and exit";
+  if (re.getResponseType() == Response::UNKNOWN) {
+    std::cout << "[* !! *] unknown content type and exit";
     m_step = Abort;
     abort();
     return;
-  }
-  else if (re.getResponseType() == Response::NDNS_Nack)
-  {
-      if (m_step == NSQuery) {
-        //In fact, there are two different situations
-        //1st: /net/ndnsim/DNS/www/NS is nacked
-        //2st: /net/DNS/ndnsim/www/NS is nacked
-        m_step = RRQuery;
+  } else if (re.getResponseType() == Response::NDNS_Nack) {
+    if (m_step == NSQuery) {
+      //In fact, there are two different situations
+      //1st: /net/ndnsim/DNS/www/NS is nacked
+      //2st: /net/DNS/ndnsim/www/NS is nacked
+      m_step = RRQuery;
 
-      } else if (m_step == RRQuery)
-      {
-        m_step = AnswerStub;
+      if (m_query.getRrType() == RR::NDNCERT && m_rrLabelLen == 1) {
+        //here working for KSK and NDNCERT when get a Nack
+        //e.g., /net/ndnsim/ksk-1, ksk-1 returns nack, but it should query /net
+
+        Name dstLabel = m_query.getRrLabel();
+        Name label = dstLabel.getSubName(m_finishedLabelNum, m_rrLabelLen);
+        if (boost::starts_with(label.toUri(), "/ksk") || boost::starts_with(label.toUri(), "/KSK")) {
+          m_finishedLabelNum = m_lastFinishedLabelNum;
+        }
+
       }
-      m_lastResponse = re;
-  }
-  else if (re.getResponseType() == Response::NDNS_Auth)
-  { // need more specific info
-    m_rrLabelLen += 1;
+    } else if (m_step == RRQuery) {
+      m_step = AnswerStub;
+    }
 
-  }
-  else if (re.getResponseType() == Response::NDNS_Resp)
-  {// get the intermediate answer
+    m_lastResponse = re;
+  } else if (re.getResponseType() == Response::NDNS_Auth) { // need more specific info
+    m_rrLabelLen += 1;
+  } else if (re.getResponseType() == Response::NDNS_Resp) { // get the intermediate answer
     if (m_step == NSQuery) {
       //do nothing, step NSQuery
+      m_lastFinishedLabelNum = m_finishedLabelNum;
       m_finishedLabelNum += m_rrLabelLen;
       m_rrLabelLen = 1;
       m_authZoneIndex = 0;
       m_lastResponse = re;
 
-    } else if (m_step == RRQuery)
-    { // final resolver gets result back
+    } else if (m_step == RRQuery) { // final resolver gets result back
       m_step = AnswerStub;
       m_lastResponse = re;
     }
 
-    std::cout<<"get RRs: "<<m_lastResponse.getStringRRs()<<std::endl;
+    std::cout << "get RRs: " << m_lastResponse.getStringRRs() << std::endl;
   }
 
 }
 
-const Interest
-IterativeQuery::toLatestInterest()
+const Interest IterativeQuery::toLatestInterest()
 {
   Query query = Query();
   Name dstLabel = m_query.getRrLabel();
@@ -111,23 +112,25 @@
   Name label;
   if (m_step == RRQuery) {
     label = dstLabel.getSubName(m_finishedLabelNum);
-  }
-  else {
+  } else {
     label = dstLabel.getSubName(m_finishedLabelNum, m_rrLabelLen);
   }
   query.setAuthorityZone(authZone);
   query.setRrLabel(label);
 
-  if (m_step == NSQuery)
-  {
+  if (m_step == NSQuery) {
     query.setRrType(RR::NS);
     query.setQueryType(Query::QUERY_DNS);
-  } else if (m_step == RRQuery)
-  {
+  } else if (m_step == RRQuery) {
     query.setRrType(m_query.getRrType());
-    query.setQueryType(Query::QUERY_DNS);
-  } else if (m_step == AnswerStub)
-  {
+    if (m_query.getRrType() == RR::NDNCERT) {
+      query.setQueryType(Query::QUERY_KEY);
+      query.setQueryType(Query::QUERY_DNS);
+    } else {
+      query.setQueryType(Query::QUERY_DNS);
+    }
+
+  } else if (m_step == AnswerStub) {
     query.setRrType(m_query.getRrType());
     query.setQueryType(Query::QUERY_DNS);
   }
diff --git a/src/iterative-query.hpp b/src/iterative-query.hpp
index 3f0ab98..aff9e43 100644
--- a/src/iterative-query.hpp
+++ b/src/iterative-query.hpp
@@ -26,6 +26,9 @@
 #include <cstdbool>
 #include <iostream>
 
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/lexical_cast.hpp>
+
 #include "query.hpp"
 #include "response.hpp"
 //#include "rr.hpp"
@@ -37,23 +40,24 @@
 {
 
 public:
-  enum QuerySteps{
-    NSQuery,
+  enum QuerySteps
+  {
+    NSQuery=1,
     NackNS,
     RRQuery,
     NackRR,
+    FHQuery,
     AnswerStub,
     Abort,
-    FinishedSuccessfully
+    FinishedSuccessfully,
+    UNKNOWN
   };
 
-
   static std::string
   toString(const QuerySteps& step)
   {
     std::string label;
-    switch(step)
-    {
+    switch (step) {
     case NSQuery:
       label = "NSQuery";
       break;
@@ -66,12 +70,18 @@
     case NackRR:
       label = "NackRR";
       break;
+    case FHQuery:
+      label = "FHQuery";
+      break;
     case AnswerStub:
       label = "AnswerStub";
       break;
     case Abort:
       label = "Abort";
       break;
+    case FinishedSuccessfully:
+      label = "FinishedSuccessfully";
+      break;
     default:
       label = "UNKNOW";
     }
@@ -79,109 +89,157 @@
     return label;
   }
 
-public:
-  IterativeQuery(const Query& );
+  static QuerySteps
+  toQuerySteps(std::string str)
+  {
+      QuerySteps step = UNKNOWN;
+      if (str == "NSQuery") {
+        step = NSQuery;
+      } else if (str == "NackNS") {
+        step = NackNS;
+      } else if (str == "RRQuery") {
+        step = RRQuery;
+      } else if (str == "NackRR") {
+        step = NackRR;
+      } else if (str == "FHQuery")
+        step = FHQuery;
+      else if (str == "AnswerStub")
+        step = AnswerStub;
+      else if (str == "Abort")
+        step = Abort;
+      else if (str == "FinishedSuccessfully")
+        step = FinishedSuccessfully;
+      else
+        step = UNKNOWN;
 
-  void
+      return step;
+  }
+
+
+public:
+  IterativeQuery(const Query&);
+
+  virtual void
   doData(Data& data);
 
-  bool
+  virtual bool
   doTimeout();
 
+  void abort();
 
-  void
-  abort();
-
-
-  const Interest
+  virtual const Interest
   toLatestInterest();
 
-
-  bool hasFinished() {
+  bool hasFinished()
+  {
     return m_query.getRrLabel().size() == m_finishedLabelNum;
   }
 
-  void addTryNum() {
+  void addTryNum()
+  {
     m_tryNum += 1;
   }
 
-  ssize_t getFinishedLabelNum() const {
+  ssize_t getFinishedLabelNum() const
+  {
     return m_finishedLabelNum;
   }
 
-  void setFinishedLabelNum(ssize_t finishedLabelNum) {
+  void setFinishedLabelNum(ssize_t finishedLabelNum)
+  {
     m_finishedLabelNum = finishedLabelNum;
   }
 
-  const Query& getQuery() const {
+  const Query& getQuery() const
+  {
     return m_query;
   }
 
-  const Response& getLastResponse() const {
+  const Response& getLastResponse() const
+  {
     return m_lastResponse;
   }
 
-  void setLastResponse(const Response& response) {
+  void setLastResponse(const Response& response)
+  {
     m_lastResponse = response;
   }
 
-  unsigned short getTryMax() const {
+  unsigned short getTryMax() const
+  {
     return m_tryMax;
   }
 
-  void setTryMax(unsigned short tryMax) {
+  void setTryMax(unsigned short tryMax)
+  {
     m_tryMax = tryMax;
   }
 
-  unsigned short getTryNum() const {
+  unsigned short getTryNum() const
+  {
     return m_tryNum;
   }
 
-  void setTryNum(unsigned short tryNum) {
+  void setTryNum(unsigned short tryNum)
+  {
     m_tryNum = tryNum;
   }
 
-  const Interest& getLastInterest() const {
+  const Interest& getLastInterest() const
+  {
     return m_lastInterest;
   }
 
-  void setLastInterest(const Interest& lastInterest) {
+  void setLastInterest(const Interest& lastInterest)
+  {
     m_lastInterest = lastInterest;
 
   }
 
-  QuerySteps getStep() const {
+  QuerySteps getStep() const
+  {
     return m_step;
   }
-
-  void setStep(QuerySteps step) {
+/*
+  void setStep(QuerySteps step)
+  {
     m_step = step;
   }
-
-  ssize_t getRrLabelLen() const {
+*/
+  ssize_t getRrLabelLen() const
+  {
     return m_rrLabelLen;
   }
 
-  void setRrLabelLen(ssize_t rrLabelLen) {
+  void setRrLabelLen(ssize_t rrLabelLen)
+  {
     m_rrLabelLen = rrLabelLen;
   }
 
-  unsigned int getAuthZoneIndex() const {
+  unsigned int getAuthZoneIndex() const
+  {
     return m_authZoneIndex;
   }
 
-  void setRrAsNextAuthorityZoneToTry(unsigned int authZoneIndex) {
+  void setRrAsNextAuthorityZoneToTry(unsigned int authZoneIndex)
+  {
     m_authZoneIndex = authZoneIndex;
   }
 
-private:
+  /**
+   * The function is neccesarry since the template of class CachingResolver call setForwardingHint
+
+  void setForwardingHint(const Name& lastForwardingHint)
+  {
+  }
+*/
+protected:
   QuerySteps m_step;
 
   unsigned short m_tryNum;
   unsigned short m_tryMax;
   //Name m_dstLabel;
 
-
   /*
    * the original query, not the intermediate query
    */
@@ -193,13 +251,19 @@
    */
   ssize_t m_finishedLabelNum;
 
+
+  /*
+   * used when query the KSK (key signing key), e.g., /net/ndnsim/ksk-1
+   */
+  ssize_t m_lastFinishedLabelNum;
+
+
   /*
    * the number used to generated the label
    * query.getRrLabel().getSubName(m_finishedLabelNum, m_labelLength);
    */
   ssize_t m_rrLabelLen;
 
-
   /*
    * m_lastResponse is changed once a new expecting Data is understood:
    * response.from(data)
@@ -211,26 +275,24 @@
    */
   unsigned int m_authZoneIndex;
 
-
-
-
   /*
    * last interest that has sent
    */
   Interest m_lastInterest;
+
+  //friend class IterativeQueryWithForwardingHint;
 };
 
 inline std::ostream&
 operator<<(std::ostream& os, const IterativeQuery iq)
 {
-  os<<"InterativeQuery: dstLabel="<<iq.getQuery().getRrLabel().toUri()
-      <<" currentStep="<<IterativeQuery::toString( iq.getStep())
-      <<" finishedLabel="<<iq.getFinishedLabelNum()
-      <<" rrLabelen="<<iq.getRrLabelLen()
-      <<" NextAuZoneIndex="<<iq.getAuthZoneIndex()
-      << " [OriginalQuery: " <<iq.getQuery() << "]"
-      <<" [LastReponse: "<<iq.getLastResponse()<<"]"
-      <<" [LastInterest: " <<iq.getLastInterest()<<"]";
+  os << "InterativeQuery: dstLabel=" << iq.getQuery().getRrLabel().toUri()
+      << " currentStep=" << IterativeQuery::toString(iq.getStep())
+      << " finishedLabel=" << iq.getFinishedLabelNum() << " rrLabelen="
+      << iq.getRrLabelLen() << " NextAuZoneIndex=" << iq.getAuthZoneIndex()
+      << " [OriginalQuery: " << iq.getQuery() << "]" << " [LastReponse: "
+      << iq.getLastResponse() << "]" << " [LastInterest: "
+      << iq.getLastInterest() << "]";
 
   return os;
 }
diff --git a/src/ndns-label.hpp b/src/ndns-label.hpp
new file mode 100644
index 0000000..3c7db2b
--- /dev/null
+++ b/src/ndns-label.hpp
@@ -0,0 +1,37 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California.
+ *
+ * This file is part of NDNS (Named Data Networking Domain Name Service).
+ * See AUTHORS.md for complete list of NDNS authors and contributors.
+ *
+ * NDNS 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.
+ *
+ * NDNS 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
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef NDNS_NDNS_LABEL_HPP
+#define NDNS_NDNS_LABEL_HPP
+#include "query.hpp"
+
+
+namespace ndn {
+namespace ndns {
+namespace label {
+  const std::string ForwardingHintLabel = "\xF0.";
+  const ndn::Name::Component ForwardingHintComp(ForwardingHintLabel);
+  const ndn::Name::Component QueryDNSComp(Query::toString(Query::QUERY_DNS));
+  const ndn::Name::Component QueryDNSRComp(Query::toString(Query::QUERY_DNS_R));
+
+}
+} // namespace ndns
+} // namespace ndn
+#endif
diff --git a/src/ndns-tlv.hpp b/src/ndns-tlv.hpp
index b027f1a..5dd8df0 100644
--- a/src/ndns-tlv.hpp
+++ b/src/ndns-tlv.hpp
@@ -23,7 +23,8 @@
 namespace ndns {
 namespace tlv {
 
-enum {
+enum
+{
   ResponseType = 130,
   ResponseFressness = 131,
   ResponseContentBlob = 132,
diff --git a/src/query.cpp b/src/query.cpp
index 7a96731..1c021c5 100644
--- a/src/query.cpp
+++ b/src/query.cpp
@@ -18,62 +18,77 @@
  */
 
 #include "query.hpp"
-
+#include "ndns-label.hpp"
 namespace ndn {
 namespace ndns {
 
 Query::Query()
-  : m_queryType (QUERY_DNS)
+  : m_forwardingHint("/")
+  , m_queryType(QUERY_DNS)
   , m_interestLifetime(time::milliseconds(4000))
   , m_rrType(RR::NS)
 {
 }
 
-Query::~Query() {
+Query::~Query()
+{
 }
 
-
-bool
-Query::fromInterest(const Name &name, const Interest &interest)
+bool Query::fromInterest(const Name &name, const Interest &interest)
 {
   return fromInterest(interest);
 }
 
-bool
-Query::fromInterest(const Interest& interest)
+bool Query::fromInterest(const Interest& interest)
 {
   Name interestName;
   interestName = interest.getName();
 
   int qtflag = -1;
+  int zoneStart = -1;
   size_t len = interestName.size();
-  for (size_t i=0; i<len; i++)
-    {
-      std::string comp = interestName.get(i).toUri();
-      if (comp == toString(QUERY_DNS) || comp == toString(QUERY_DNS_R))
-        {
-          qtflag = i;
-          break;
-        }
-    }//for
 
-  if (qtflag == -1)
-    {
-      std::cerr << "There is no QueryType in the Interest Name: "<< interestName << std::endl;
-      return false;
+  for (size_t i = 0; i < len; i++) {
+    ndn::Name::Component comp = interestName.get(i);
+    //if (comp == ndn::ndns::label::ForwardingHintLabel) {
+    if (comp == ndn::ndns::label::ForwardingHintComp) {
+      zoneStart = i;
+    } else if (comp == ndn::ndns::label::QueryDNSComp || comp == ndn::ndns::label::QueryDNSRComp ) {
+      qtflag = i;
+      break;
     }
+  } //for
+
+  if (qtflag == -1) {
+    std::cerr << "There is no QueryType in the Interest Name: " << interestName
+        << std::endl;
+    return false;
+  }
   this->m_queryType = toQueryType(interestName.get(qtflag).toUri());
-  this->m_rrType = RR::toRRType(interestName.get(len-1).toUri());
-  this->m_authorityZone = interestName.getPrefix(qtflag); //the DNS/DNS-R is not included
+  this->m_rrType = RR::toRRType(interestName.get(len - 1).toUri());
+  if (zoneStart == -1) {
+    this->m_authorityZone = interestName.getPrefix(qtflag); //the DNS/DNS-R is not included
+  } else {
+    this->m_forwardingHint = interestName.getPrefix(zoneStart);
+    this->m_authorityZone = interestName.getSubName(zoneStart+1, qtflag-zoneStart-1);
+  }
   this->m_interestLifetime = interest.getInterestLifetime();
-  this->m_rrLabel = interestName.getSubName(qtflag+1, len-qtflag-2);
+  this->m_rrLabel = interestName.getSubName(qtflag + 1, len - qtflag - 2);
   return true;
 }
 
-Interest
-Query::toInterest() const
+Interest Query::toInterest() const
 {
-  Name name = this->m_authorityZone;
+  Name name;
+  if (m_forwardingHint != Name("/")) {
+    name = m_forwardingHint;
+    name.append(ndn::ndns::label::ForwardingHintLabel);
+    //std::cout<<"add forwarding---------------------------:"<<name.toUri()<<std::endl;
+  } else {
+    //std::cout<<"do not add forwarding---------------------------:"<<std::endl;
+  }
+
+  name.append(this->m_authorityZone);
   name.append(toString(this->m_queryType));
   name.append(this->m_rrLabel);
   name.append(RR::toString(this->m_rrType));
diff --git a/src/query.hpp b/src/query.hpp
index 61b1cff..157745e 100644
--- a/src/query.hpp
+++ b/src/query.hpp
@@ -22,6 +22,7 @@
 
 #include "rr.hpp"
 
+
 #include <ndn-cxx/name.hpp>
 
 namespace ndn {
@@ -31,43 +32,47 @@
 {
 public:
 
-  enum QueryType {
-    QUERY_DNS,
-    QUERY_DNS_R
+  enum QueryType
+  {
+    QUERY_DNS = 1,
+    QUERY_DNS_R,
+    QUERY_KEY,
+    QUERY_UNKNOWN
   };
 
-  static std::string
-  toString(const QueryType& qType)
+  static std::string toString(const QueryType& qType)
   {
     std::string label;
-    switch (qType)
-      {
-      case QUERY_DNS:
-        label = "DNS";
-        break;
-      case QUERY_DNS_R:
-        label = "DNS-R";
-        break;
-      default:
-        label = "Default";
-        break;
-      }
+    switch (qType) {
+    case QUERY_DNS:
+      label = "DNS";
+      break;
+    case QUERY_DNS_R:
+      label = "DNS-R";
+      break;
+    case QUERY_KEY:
+      label = "KEY";
+      break;
+    default:
+      label = "UNKNOWN";
+      break;
+    }
     return label;
 
   }
 
-  static const QueryType
-  toQueryType(const std::string& str)
+  static const QueryType toQueryType(const std::string& str)
   {
     QueryType atype;
     if (str == "DNS") {
       atype = QUERY_DNS;
-    }
-    else if (str == "DNS-R") {
+    } else if (str == "DNS-R") {
       atype = QUERY_DNS_R;
+    } else if (str == "KEY") {
+      atype = QUERY_KEY;
     }
     else {
-      atype = QUERY_DNS;
+      atype = QUERY_UNKNOWN;
     }
     return atype;
   }
@@ -76,47 +81,56 @@
 
   virtual ~Query();
 
-  const Name& getAuthorityZone() const {
+  const Name& getAuthorityZone() const
+  {
     return m_authorityZone;
   }
 
-  void setAuthorityZone(const Name& authorityZone) {
+  void setAuthorityZone(const Name& authorityZone)
+  {
     m_authorityZone = authorityZone;
   }
 
-  time::milliseconds getInterestLifetime() const {
+  time::milliseconds getInterestLifetime() const
+  {
     return m_interestLifetime;
   }
 
-  void setInterestLifetime(time::milliseconds interestLifetime) {
+  void setInterestLifetime(time::milliseconds interestLifetime)
+  {
     m_interestLifetime = interestLifetime;
   }
 
-  enum QueryType getQueryType() const {
+  enum QueryType getQueryType() const
+  {
     return m_queryType;
   }
 
-  void setQueryType(enum QueryType queryType) {
+  void setQueryType(enum QueryType queryType)
+  {
     m_queryType = queryType;
   }
 
-  const Name& getRrLabel() const {
+  const Name& getRrLabel() const
+  {
     return m_rrLabel;
   }
 
-  void setRrLabel(const Name& rrLabel) {
+  void setRrLabel(const Name& rrLabel)
+  {
     m_rrLabel = rrLabel;
   }
 
-  const RR::RRType& getRrType() const {
+  const RR::RRType& getRrType() const
+  {
     return m_rrType;
   }
 
-  void setRrType(const RR::RRType& rrType) {
+  void setRrType(const RR::RRType& rrType)
+  {
     m_rrType = rrType;
   }
 
-
 private:
   template<bool T>
   size_t
@@ -132,29 +146,40 @@
   bool
   fromInterest(const Interest& interest);
 
+  const Name& getFowardingHint() const
+  {
+    return m_forwardingHint;
+  }
+
+  void setFowardingHint(const Name& fowardingHint)
+  {
+    m_forwardingHint = fowardingHint;
+  }
 
 public:
+
   Name m_authorityZone;
+  Name m_forwardingHint;
+
   enum QueryType m_queryType;
   time::milliseconds m_interestLifetime;
   Name m_rrLabel;
   enum RR::RRType m_rrType;
 
+
   mutable Block m_wire;
 };
 
-
 inline std::ostream&
 operator<<(std::ostream& os, const Query& query)
 {
-  os<<"Query: authorityZone="<<query.getAuthorityZone().toUri()
-    <<" queryType="<<Query::toString(query.getQueryType())
-    <<" rrLabel="<<query.getRrLabel().toUri()
-    <<" rrType="<<RR::toString(query.getRrType());
+  os << "Query: authorityZone=" << query.getAuthorityZone().toUri()
+      << " queryType=" << Query::toString(query.getQueryType()) << " rrLabel="
+      << query.getRrLabel().toUri() << " rrType="
+      << RR::toString(query.getRrType());
   return os;
 }
 
-
 } // namespace ndns
 } // namespace ndn
 
diff --git a/src/response.cpp b/src/response.cpp
index cb13dda..c326bd6 100644
--- a/src/response.cpp
+++ b/src/response.cpp
@@ -23,9 +23,9 @@
 namespace ndns {
 
 Response::Response()
-  : m_freshness (time::milliseconds(3600))
-  , m_contentType (Query::QUERY_DNS)
-  , m_responseType (NDNS_Resp)
+  : m_freshness(time::milliseconds(3600))
+  , m_contentType(Query::QUERY_DNS)
+  , m_responseType(NDNS_Resp)
 {
 }
 
@@ -34,70 +34,58 @@
 }
 
 template<bool T>
-size_t
-Response::wireEncode(EncodingImpl<T> & block) const
+size_t Response::wireEncode(EncodingImpl<T> & block) const
 {
-    size_t totalLength = 0;
-    std::vector<RR>::size_type lenOfRR = m_rrs.size();
-    RR rr;
-    Block btemp;
+  size_t totalLength = 0;
+  std::vector<RR>::size_type lenOfRR = m_rrs.size();
+  RR rr;
+  Block btemp;
 
-    //totalLength += m_rrs[0].wireEncode(block);
+  //totalLength += m_rrs[0].wireEncode(block);
 
-    for (std::vector<RR>::size_type i=0; i<lenOfRR; i++)
-    {
-      rr = m_rrs[lenOfRR-i-1];
-      totalLength += rr.wireEncode(block);
-      //std::cout<<"totalLenght="<<totalLength<<std::endl;
-    }
+  for (std::vector<RR>::size_type i = 0; i < lenOfRR; i++) {
+    rr = m_rrs[lenOfRR - i - 1];
+    totalLength += rr.wireEncode(block);
+    //std::cout<<"totalLenght="<<totalLength<<std::endl;
+  }
 
-    totalLength += prependNonNegativeIntegerBlock(block,
-                        ndn::ndns::tlv::ResponseNumberOfRRData,
-                        lenOfRR);
+  totalLength += prependNonNegativeIntegerBlock(block,
+      ndn::ndns::tlv::ResponseNumberOfRRData, lenOfRR);
 
-    totalLength += block.prependVarNumber(totalLength);
-    totalLength += block.prependVarNumber(ndn::ndns::tlv::ResponseContentBlob);
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(ndn::ndns::tlv::ResponseContentBlob);
 
-    totalLength += prependNonNegativeIntegerBlock(block,
-                                ndn::ndns::tlv::ResponseFressness,
-                                m_freshness.count()
-                                  );
+  totalLength += prependNonNegativeIntegerBlock(block,
+      ndn::ndns::tlv::ResponseFressness, m_freshness.count());
 
-    std::string msg = Response::toString(m_responseType);
-    totalLength += prependByteArrayBlock(block,
-                           ndn::ndns::tlv::ResponseType,
-                           reinterpret_cast<const uint8_t*>(msg.c_str()),
-                           msg.size()
-                           );
+  std::string msg = Response::toString(m_responseType);
+  totalLength += prependByteArrayBlock(block, ndn::ndns::tlv::ResponseType,
+      reinterpret_cast<const uint8_t*>(msg.c_str()), msg.size());
 
-    totalLength += m_queryName.wireEncode(block);
+  totalLength += m_queryName.wireEncode(block);
 
-
-    totalLength += block.prependVarNumber(totalLength);
-    totalLength += block.prependVarNumber(Tlv::Content);
-    return totalLength;
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(Tlv::Content);
+  return totalLength;
 }
 
-
 const Block&
 Response::wireEncode() const
 {
 
   if (m_wire.hasWire())
-     return m_wire;
-   EncodingEstimator estimator;
+    return m_wire;
+  EncodingEstimator estimator;
 
-   size_t estimatedSize = wireEncode(estimator);
-   //std::cout<< typeid( this).name()<<" Instance estimatedsize="<<estimatedSize<<std::endl;
-   EncodingBuffer buffer(estimatedSize, 0);
-   wireEncode(buffer);
-   m_wire = buffer.block();
-   return m_wire;
+  size_t estimatedSize = wireEncode(estimator);
+  //std::cout<< typeid( this).name()<<" Instance estimatedsize="<<estimatedSize<<std::endl;
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+  m_wire = buffer.block();
+  return m_wire;
 }
 
-
-void
-Response::wireDecode(const Block& wire)
+void Response::wireDecode(const Block& wire)
 {
   if (!wire.hasWire()) {
     throw Tlv::Error("The supplied block does not contain wire format");
@@ -109,100 +97,81 @@
   m_wire = wire;
   m_wire.parse();
 
-
   Block::element_const_iterator it = m_wire.elements_begin();
 
-  if (it != m_wire.elements_end() && it->type() == ndn::Tlv::Name)
-  {
+  if (it != m_wire.elements_end() && it->type() == ndn::Tlv::Name) {
     m_queryName.wireDecode(*it);
-    it ++;
-  } else
-  {
+    it++;
+  } else {
     throw Tlv::Error("not the ndn::Tlv::Name type");
   }
 
-  if (it != m_wire.elements_end() && it->type() == ndn::ndns::tlv::ResponseType)
-  {
+  if (it != m_wire.elements_end()
+      && it->type() == ndn::ndns::tlv::ResponseType) {
     std::string temp = std::string(reinterpret_cast<const char*>(it->value()),
-                          it->value_size());
+        it->value_size());
     m_responseType = Response::toResponseType(temp);
-      it ++;
-  } else
-  {
-      throw Tlv::Error("not the ndn::ndns::tlv::ReponseType type");
+    it++;
+  } else {
+    throw Tlv::Error("not the ndn::ndns::tlv::ReponseType type");
   }
 
-  if (it != m_wire.elements_end() && it->type() == ndn::ndns::tlv::ResponseFressness)
-    {
-      m_freshness = time::milliseconds(readNonNegativeInteger(*it));
-      it ++;
-    } else
-    {
-      throw Tlv::Error("not the ndn::ndns::tlv::ReponseFreshness type");
+  if (it != m_wire.elements_end()
+      && it->type() == ndn::ndns::tlv::ResponseFressness) {
+    m_freshness = time::milliseconds(readNonNegativeInteger(*it));
+    it++;
+  } else {
+    throw Tlv::Error("not the ndn::ndns::tlv::ReponseFreshness type");
+  }
+
+  if (it != m_wire.elements_end()
+      && it->type() == ndn::ndns::tlv::ResponseContentBlob) {
+    //Block b2 = it->value();/* to check */
+    Block b2 = *it;/* to check */
+
+    b2.parse();
+    Block::element_const_iterator it2 = b2.elements_begin();
+    size_t rrlen = 0;
+    if (it2 != b2.elements_end()
+        && it2->type() == ndn::ndns::tlv::ResponseNumberOfRRData) {
+      rrlen = readNonNegativeInteger(*it2);
+      it2++;
+    } else {
+      throw Tlv::Error("not the ndn::ndns::tlv::ResponseNumberOfRRData type");
+    }
+    for (size_t i = 0; i < rrlen; i++) {
+      if (it2 != b2.elements_end() && it2->type() == ndn::ndns::tlv::RRData) {
+        RR rr;
+        rr.wireDecode(*it2);
+        this->m_rrs.push_back(rr);
+        it2++;
+      } else {
+        throw Tlv::Error("not the ndn::ndns::tlv::RRData type");
+      }
     }
 
-
-  if (it != m_wire.elements_end() && it->type() == ndn::ndns::tlv::ResponseContentBlob)
-    {
-      //Block b2 = it->value();/* to check */
-      Block b2 = *it;/* to check */
-
-      b2.parse();
-      Block::element_const_iterator it2 = b2.elements_begin();
-      size_t rrlen = 0;
-      if (it2 != b2.elements_end() && it2->type() == ndn::ndns::tlv::ResponseNumberOfRRData)
-      {
-         rrlen = readNonNegativeInteger(*it2);
-         it2 ++;
-      } else
-      {
-        throw Tlv::Error("not the ndn::ndns::tlv::ResponseNumberOfRRData type");
-      }
-      for (size_t i=0; i<rrlen; i++)
-      {
-        if (it2 != b2.elements_end() &&
-            it2->type() == ndn::ndns::tlv::RRData)
-        {
-          RR rr;
-          rr.wireDecode(*it2);
-          this->m_rrs.push_back(rr);
-          it2 ++;
-        } else
-        {
-          throw Tlv::Error("not the ndn::ndns::tlv::RRData type");
-        }
-      }
-
-
-      it ++;
-    } else
-    {
-      throw Tlv::Error("not the ndn::ndns::tlv::ResponseContentBlob type");
-    }
-
-
+    it++;
+  } else {
+    throw Tlv::Error("not the ndn::ndns::tlv::ResponseContentBlob type");
+  }
 
 }
 
-void
-Response::fromData(const Data& data)
+void Response::fromData(const Data& data)
 {
 
-    m_queryName = data.getName();
-    m_freshness = data.getFreshnessPeriod();
-    m_contentType = Query::QueryType(data.getContentType());
-    this->wireDecode(data.getContent());
+  m_queryName = data.getName();
+  m_freshness = data.getFreshnessPeriod();
+  m_contentType = Query::QueryType(data.getContentType());
+  this->wireDecode(data.getContent());
 }
 
-
-void
-Response::fromData(const Name& name, const Data& data)
+void Response::fromData(const Name& name, const Data& data)
 {
   fromData(data);
 }
 
-Data
-Response::toData() const
+Data Response::toData() const
 {
   Data data;
   data.setName(m_queryName);
@@ -213,6 +182,5 @@
   return data;
 }
 
-
 } // namespace ndns
 } // namespace ndn
diff --git a/src/response.hpp b/src/response.hpp
index e2266ac..97791a7 100644
--- a/src/response.hpp
+++ b/src/response.hpp
@@ -42,58 +42,50 @@
 namespace ndn {
 namespace ndns {
 
-
-class Response {
+class Response
+{
 public:
   enum ResponseType
-    {
-      NDNS_Resp,
-      NDNS_Nack,
-      NDNS_Auth,
-      UNKNOWN
-    };
+  {
+    NDNS_Resp,
+    NDNS_Nack,
+    NDNS_Auth,
+    UNKNOWN
+  };
 
-
-  static std::string
-  toString(ResponseType responseType)
+  static std::string toString(ResponseType responseType)
   {
     std::string label;
-    switch (responseType)
-      {
-      case NDNS_Resp:
-        label = "NDNS Resp";
-        break;
-      case NDNS_Nack:
-        label = "NDNS Nack";
-        break;
-      case NDNS_Auth:
-        label = "NDNS Auth";
-        break;
-      default:
-        label = "UNKNOWN";
-        break;
-      }
+    switch (responseType) {
+    case NDNS_Resp:
+      label = "NDNS Resp";
+      break;
+    case NDNS_Nack:
+      label = "NDNS Nack";
+      break;
+    case NDNS_Auth:
+      label = "NDNS Auth";
+      break;
+    default:
+      label = "UNKNOWN";
+      break;
+    }
     return label;
   }
 
-  static ResponseType
-  toResponseType(const std::string& str)
+  static ResponseType toResponseType(const std::string& str)
   {
-      ResponseType atype;
-      if (str == "NDNS Resp"){
-          atype = NDNS_Resp;
-      }
-      else if (str == "NDNS Nack") {
-          atype = NDNS_Nack;
-      }
-      else if (str == "NDNS Auth")
-      {
-        atype = NDNS_Auth;
-      }
-      else {
-          atype = UNKNOWN;
-      }
-      return atype;
+    ResponseType atype;
+    if (str == "NDNS Resp") {
+      atype = NDNS_Resp;
+    } else if (str == "NDNS Nack") {
+      atype = NDNS_Nack;
+    } else if (str == "NDNS Auth") {
+      atype = NDNS_Auth;
+    } else {
+      atype = UNKNOWN;
+    }
+    return atype;
   }
 
   Response();
@@ -117,7 +109,6 @@
   size_t
   wireEncode(EncodingImpl<T> & block) const;
 
-
   void
   fromData(const Name& name, const Data& data);
 
@@ -127,64 +118,69 @@
   Data
   toData() const;
 
-
-
-  const std::string
-  getStringRRs() const {
+  const std::string getStringRRs() const
+  {
     std::stringstream str;
-    str<<"[";
+    str << "[";
     std::vector<RR>::const_iterator iter = m_rrs.begin();
-    while (iter != m_rrs.end())
-    {
-      str<<" "<<*iter;
-      iter ++;
+    while (iter != m_rrs.end()) {
+      str << " " << *iter;
+      iter++;
     }
-    str<<"]";
+    str << "]";
     return str.str();
   }
 
-  Query::QueryType getContentType() const {
+  Query::QueryType getContentType() const
+  {
     return m_contentType;
   }
 
-  void setContentType(Query::QueryType contentType) {
+  void setContentType(Query::QueryType contentType)
+  {
     m_contentType = contentType;
   }
 
-  time::milliseconds getFreshness() const {
+  time::milliseconds getFreshness() const
+  {
     return m_freshness;
   }
 
-  void setFreshness(time::milliseconds freshness) {
+  void setFreshness(time::milliseconds freshness)
+  {
     m_freshness = freshness;
   }
 
-  const Name& getQueryName() const {
+  const Name& getQueryName() const
+  {
     return m_queryName;
   }
 
-  void setQueryName(const Name& queryName) {
+  void setQueryName(const Name& queryName)
+  {
     m_queryName = queryName;
   }
 
-  ResponseType getResponseType() const {
+  ResponseType getResponseType() const
+  {
     return m_responseType;
   }
 
-  void setResponseType(ResponseType responseType) {
+  void setResponseType(ResponseType responseType)
+  {
     m_responseType = responseType;
   }
 
-  const std::vector<RR>& getRrs() const {
+  const std::vector<RR>& getRrs() const
+  {
     return m_rrs;
   }
 
-  void setRrs(const std::vector<RR>& rrs) {
+  void setRrs(const std::vector<RR>& rrs)
+  {
     m_rrs = rrs;
   }
 
-
-
 private:
   time::milliseconds m_freshness;
   Name m_queryName;
@@ -192,30 +188,26 @@
   Query::QueryType m_contentType;
   ResponseType m_responseType;
   //unsigned int m_numberOfRR;
-  std::vector<RR>  m_rrs;
+  std::vector<RR> m_rrs;
   mutable Block m_wire;
 
 };
 
-
 inline std::ostream&
 operator<<(std::ostream& os, const Response& response)
 {
-  os<<"Response: queryName="<<response.getQueryName().toUri()
-    <<" responseType="<<Response::toString(response.getResponseType())
-    <<" contentType="<<Query::toString(response.getContentType())
-    <<" [";
+  os << "Response: queryName=" << response.getQueryName().toUri()
+      << " responseType=" << Response::toString(response.getResponseType())
+      << " contentType=" << Query::toString(response.getContentType()) << " [";
   std::vector<RR>::const_iterator iter = response.getRrs().begin();
-  while (iter != response.getRrs().end())
-  {
-    os<<" "<<*iter;
-    iter ++;
+  while (iter != response.getRrs().end()) {
+    os << " " << *iter;
+    iter++;
   }
-  os<<"]";
+  os << "]";
   return os;
 }
 
-
 } // namespace ndns
 } // namespace ndn
 
diff --git a/src/rr.cpp b/src/rr.cpp
index c2700ba..ffbefe6 100644
--- a/src/rr.cpp
+++ b/src/rr.cpp
@@ -32,10 +32,6 @@
 {
 }
 
-
-
-
-
 const Block&
 RR::wireEncode() const
 {
@@ -51,8 +47,7 @@
   return m_wire;
 }
 
-void
-RR::wireDecode(const Block& wire)
+void RR::wireDecode(const Block& wire)
 {
   if (!wire.hasWire()) {
     throw Tlv::Error("The supplied block does not contain wire format");
@@ -66,26 +61,22 @@
 
   Block::element_const_iterator it = m_wire.elements_begin();
 
-  if (it != m_wire.elements_end() && it->type() == ndn::ndns::tlv::RRDataSub1)
-    {
-      m_id = readNonNegativeInteger(*it);
-      it ++;
-    } else {
+  if (it != m_wire.elements_end() && it->type() == ndn::ndns::tlv::RRDataSub1) {
+    m_id = readNonNegativeInteger(*it);
+    it++;
+  } else {
     throw Tlv::Error("not the RRDataSub1 Type");
   }
 
-  if (it != m_wire.elements_end() && it->type() == ndn::ndns::tlv::RRDataSub2)
-    {
+  if (it != m_wire.elements_end() && it->type() == ndn::ndns::tlv::RRDataSub2) {
 
-      m_rrData = std::string(reinterpret_cast<const char*>(it->value()),
-                            it->value_size());
-      it ++;
-    } else {
+    m_rrData = std::string(reinterpret_cast<const char*>(it->value()),
+        it->value_size());
+    it++;
+  } else {
     throw Tlv::Error("not the RRDataSub2 Type");
   }
 
-
-
 }
 
 } // namespace ndns
diff --git a/src/rr.hpp b/src/rr.hpp
index 106bb39..50cdd68 100644
--- a/src/rr.hpp
+++ b/src/rr.hpp
@@ -30,50 +30,70 @@
 namespace ndn {
 namespace ndns {
 
-
-class RR {
+class RR
+{
 public:
 
   enum RRType
-    {
-      NS,
-      TXT,
-      UNKNOWN
-    };
-  static std::string
-  toString(const RRType& type)
-    {
-      std::string str;
-
-        switch (type)
-        {
-            case NS:
-                str = "NS";
-                break;
-            case TXT:
-                str = "TXT";
-                break;
-            default:
-                str = "UNKNOWN";
-                break;
-        }
-        return str;
-    }
-
-  static RRType
-  toRRType(const std::string& str)
   {
-      RRType atype;
-      if (str == "NS"){
-          atype = NS;
-      }
-      else if (str == "TXT") {
-          atype = TXT;
-      }
-      else {
-          atype = UNKNOWN;
-      }
-      return atype;
+    NS,
+    TXT,
+    FH,
+    A,
+    AAAA,
+    NDNCERT,
+    UNKNOWN
+  };
+  static std::string toString(const RRType& type)
+  {
+    std::string str;
+
+    switch (type) {
+    case NS:
+      str = "NS";
+      break;
+    case TXT:
+      str = "TXT";
+      break;
+    case FH:
+      str = "FH";
+      break;
+    case A:
+      str = "A";
+      break;
+    case AAAA:
+      str = "AAAA";
+      break;
+    case NDNCERT:
+      str = "NDNCERT";
+      break;
+    default:
+      str = "UNKNOWN";
+      break;
+    }
+    return str;
+  }
+
+  static RRType toRRType(const std::string& str)
+  {
+    RRType atype;
+    if (str == "NS") {
+      atype = NS;
+    } else if (str == "TXT") {
+      atype = TXT;
+    } else if (str == "FH") {
+      atype = FH;
+    } else if (str == "A") {
+      atype = A;
+    } else if (str == "AAAA") {
+      atype = AAAA;
+    } else if (str == "NDNCERT") {
+      atype = NDNCERT;
+    }
+    else {
+      atype = UNKNOWN;
+    }
+    return atype;
   }
 
   RR();
@@ -91,26 +111,27 @@
     this->m_rrData = rrdata;
   }
 
-
-
 public:
 
-	uint32_t getId() const {
-		return m_id;
-	}
-
-	void setId(uint32_t id) {
-		m_id = id;
-	}
-
-  const Block& getWire() const {
-      return m_wire;
+  uint32_t getId() const
+  {
+    return m_id;
   }
 
-  void setWire(const Block& wire) {
-      m_wire = wire;
+  void setId(uint32_t id)
+  {
+    m_id = id;
   }
 
+  const Block& getWire() const
+  {
+    return m_wire;
+  }
+
+  void setWire(const Block& wire)
+  {
+    m_wire = wire;
+  }
 
   inline bool operator==(const RR& rr) const
   {
@@ -120,22 +141,16 @@
     return false;
   }
 
-
   template<bool T>
-  inline size_t
-  wireEncode(EncodingImpl<T> & block) const
+  inline size_t wireEncode(EncodingImpl<T> & block) const
   {
     size_t totalLength = 0;
     const std::string& msg = this->getRrdata();
-    totalLength += prependByteArrayBlock(block,
-                           ndn::ndns::tlv::RRDataSub2,
-                           reinterpret_cast<const uint8_t*>(msg.c_str()),
-                           msg.size()
-                           );
+    totalLength += prependByteArrayBlock(block, ndn::ndns::tlv::RRDataSub2,
+        reinterpret_cast<const uint8_t*>(msg.c_str()), msg.size());
 
     totalLength += prependNonNegativeIntegerBlock(block,
-                        ndn::ndns::tlv::RRDataSub1,
-                        this->getId());
+        ndn::ndns::tlv::RRDataSub1, this->getId());
 
     totalLength += block.prependVarNumber(totalLength);
     totalLength += block.prependVarNumber(ndn::ndns::tlv::RRData);
@@ -143,7 +158,6 @@
     return totalLength;
   }
 
-
   const Block&
   wireEncode() const;
 
@@ -158,19 +172,17 @@
   std::string m_rrData;
 
   mutable Block m_wire;
-};//class RR
-
+};
+//class RR
 
 inline std::ostream&
 operator<<(std::ostream& os, const RR& rr)
 {
-  os<<"RR: Id="<<rr.getId()<<" Data="<<rr.getRrdata();
+  os << "RR: Id=" << rr.getId() << " Data=" << rr.getRrdata();
   return os;
 }
 
 } // namespace ndns
 } // namespace ndn
 
-
-
 #endif // NDNS_RR_HPP
diff --git a/src/zone.cpp b/src/zone.cpp
index c161cd3..06e1bb1 100644
--- a/src/zone.cpp
+++ b/src/zone.cpp
@@ -23,13 +23,13 @@
 namespace ndns {
 
 Zone::Zone(const Name& name)
-: m_id(0)
-, m_authorizedName(name)
+  : m_id(0)
+  , m_authorizedName(name)
 {
 }
 
 Zone::Zone()
- : m_id(0)
+    : m_id(0)
 {
 }
 
diff --git a/src/zone.hpp b/src/zone.hpp
index 6b62580..2912e5c 100644
--- a/src/zone.hpp
+++ b/src/zone.hpp
@@ -27,7 +27,8 @@
 namespace ndn {
 namespace ndns {
 
-class Zone {
+class Zone
+{
 
 public:
 
@@ -35,28 +36,33 @@
   Zone();
   virtual ~Zone();
 
-  const Name& getAuthorizedName() const {
+  const Name& getAuthorizedName() const
+  {
     return m_authorizedName;
   }
 
-  void setAuthorizedName(const Name& authorizedName) {
+  void setAuthorizedName(const Name& authorizedName)
+  {
     m_authorizedName = authorizedName;
   }
 
-  uint32_t getId() const {
+  uint32_t getId() const
+  {
     return m_id;
   }
 
-  void setId(uint32_t id) {
+  void setId(uint32_t id)
+  {
     m_id = id;
   }
 
 private:
   uint32_t m_id;
   Name m_authorizedName;
-};//class Zone
+};
+//class Zone
 
-} // namespace ndns
+}// namespace ndns
 } // namespace ndn
 
 #endif // NDNS_ZONE_HPP