ccnx tunnel compiles
diff --git a/include/ccnx-tunnel.h b/include/ccnx-tunnel.h
index 21cbcbb..c17569d 100644
--- a/include/ccnx-tunnel.h
+++ b/include/ccnx-tunnel.h
@@ -1,7 +1,6 @@
 #ifndef CCNX_TUNNEL_H
 #define CCNX_TUNNEL_H
 
-#include <ccnx-wrapper.h>
 #include <string>
 #include <boost/function.hpp>
 #include <boost/variant.hpp>
@@ -9,7 +8,16 @@
 #include <utility>
 #include <map>
 
-using namespace Sync;
+#include "ccnx-wrapper.h"
+
+#define _OVERRIDE 
+#ifdef __GNUC__
+#if __GNUC_MAJOR >= 4 && __GNUC_MINOR__ >= 7
+  #undef _OVERRIDE
+  #define _OVERRIDE override
+#endif // __GNUC__ version
+#endif // __GNUC__
+
 using namespace std;
 
 // Eventually, Sync::CcnxWrapper should be moved to this namespace. 
@@ -20,9 +28,8 @@
 class CcnxTunnel : public CcnxWrapper 
 {
 public: 
-  typedef boost::variant<StringDataCallback, RawDataCallback> DataCallback;
   typedef multimap<string, InterestCallback> RegisteredInterestTable;
-  typedef multimap<string, InterestCallback>iterator RitIter;
+  typedef multimap<string, InterestCallback>::iterator RitIter;
   typedef boost::shared_mutex Lock;
   typedef boost::unique_lock<Lock> WriteLock;
   typedef boost::shared_lock<Lock> ReadLock;
@@ -33,40 +40,43 @@
 
   // name is topology-independent
   virtual int
-  publishRawData(const string &name, const char *buf, size_t len, int freshness);
+  publishData(const string &name, const char *buf, size_t len, int freshness) _OVERRIDE;
+
+  virtual int
+  sendInterest (const std::string &interest, const DataCallback &dataCallback, int retry = 0, const TimeoutCallback &timeoutCallback = TimeoutCallback()) _OVERRIDE;
+
 
   // prefix is topology-independent
   virtual int
-  setInterestFilter(const string &prefix, const InterestCallback &interestCallback);
+  setInterestFilter(const string &prefix, const InterestCallback &interestCallback) _OVERRIDE;
 
   // prefix is topology-independent
   // this clears all entries with key equal to prefix
   virtual void
-  clearInterestFilter(const string &prefix);
+  clearInterestFilter(const string &prefix) _OVERRIDE;
 
   // subclass should provide translation service from topology-independent name
   // to routable name
   virtual string
-  queryRoutableName(string &name) = 0;
+  queryRoutableName(const string &name) = 0;
 
   // subclass should implement the function to store ContentObject with topoloy-independent
   // name to the permanent storage; default does nothing
   virtual void
-  storeContentObject(string &name, ContentObjectPtr co) {}
+  storeContentObject(const string &name, const Bytes &content) {}
 
   // should be called  when connect to a different network
   void
   refreshLocalPrefix();
 
   static bool
-  isPrefix(string &prefix, string &name);
+  isPrefix(const string &prefix, const string &name);
 
-protected:
   void
-  handleTunneledInterest(string tunneldInterest);
-
-  virtual int
-  sendInterest (const std::string &strInterest, void *dataPass);
+  handleTunneledInterest(const string &tunneldInterest);
+  
+  void
+  handleTunneledData(const string &name, const Bytes &tunneledData, const DataCallback &originalDataCallback);
 
 protected:
   // need a way to update local prefix, perhaps using macports trick, but eventually we need something more portable
@@ -75,6 +85,22 @@
   Lock m_ritLock;
 };
 
+class TunnelClosurePass : public ClosurePass
+{
+public:
+  TunnelClosurePass(int retry, const CcnxWrapper::DataCallback &dataCallback, const CcnxWrapper::TimeoutCallback &timeoutCallback, CcnxTunnel *tunnel, const string &originalInterest);
+
+  virtual void 
+  runDataCallback(const string &name, const Bytes &content) _OVERRIDE;
+
+  virtual CcnxWrapper::TimeoutCallbackReturnValue
+  runTimeoutCallback(const string &interest) _OVERRIDE;
+
+private:
+  CcnxTunnel *m_tunnel;
+  string m_originalInterest;
+};
+
 };
 
 #endif
diff --git a/src/ccnx-tunnel.cpp b/src/ccnx-tunnel.cpp
index 670a76a..f12e2d5 100644
--- a/src/ccnx-tunnel.cpp
+++ b/src/ccnx-tunnel.cpp
@@ -1,4 +1,5 @@
 #include "ccnx-tunnel.h"
+#include "ccnx-pco.h"
 
 namespace Ccnx
 {
@@ -14,6 +15,7 @@
 {
 }
 
+void
 CcnxTunnel::refreshLocalPrefix() 
 {
   string newPrefix = getLocalPrefix();
@@ -26,30 +28,39 @@
 }
 
 int
-sendInterest(const string &interest, void *dataPass)
+CcnxTunnel::sendInterest (const std::string &interest, const DataCallback &dataCallback, int retry, const TimeoutCallback &timeoutCallback)
 {
   string tunneledInterest = queryRoutableName(interest);
+  ClosurePass *cp = new TunnelClosurePass(retry, dataCallback, timeoutCallback, this, interest);
+  CcnxWrapper::sendInterest(tunneledInterest, cp);
+}
+
+void 
+CcnxTunnel::handleTunneledData(const string &name, const Bytes &tunneledData, const DataCallback &originalDataCallback)
+{
+  ParsedContentObject pco(tunneledData);
+  originalDataCallback(pco.name(), pco.content());
 }
 
 int
-CccnxTunnel::publishRawData(const string &name, const char *buf, size_t len, int freshness)
+CcnxTunnel::publishData(const string &name, const char *buf, size_t len, int freshness)
 {
-  ContentObjectPtr co = createContentObject(name, buf, len, freshness);
-  storeContentObject(name, co);
+  Bytes content = createContentObject(name, buf, len, freshness);
+  storeContentObject(name, content);
   
   string tunneledName = m_localPrefix + name;
-  ContentObjectPtr tunneledCo = createContentObject(tunneledName, co->m_data, co->m_len, freshness);
+  Bytes tunneledCo = createContentObject(tunneledName, (const char*)&content[0], content.size(), freshness);
 
   return putToCcnd(tunneledCo);
 }
 
 void
-CcnxTunnel::handleTunneledInterest(string tunneledInterest)
+CcnxTunnel::handleTunneledInterest(const string &tunneledInterest)
 {
   // The interest must have m_localPrefix as a prefix (component-wise), otherwise ccnd would not deliver it to us
   string interest = (m_localPrefix == "/") 
                     ? tunneledInterest
-                    : tunneldInterest.substr(m_localPrefix.size());
+                    : tunneledInterest.substr(m_localPrefix.size());
 
   ReadLock(m_ritLock); 
   
@@ -57,15 +68,15 @@
   for (RitIter it = m_rit.begin(); it != m_rit.end(); it++)
   {
     // evoke callback for any prefix that is the prefix of the interest
-    if (isPrefix(it->first(), interest))
+    if (isPrefix(it->first, interest))
     {
-      (it->second())(interest);
+      (it->second)(interest);
     }
   }
 }
 
 bool
-CcnxTunnel::isPrefix(string &prefix, string &name)
+CcnxTunnel::isPrefix(const string &prefix, const string &name)
 {
   // prefix is literally prefix of name 
   if (name.find(prefix) == 0)
@@ -84,7 +95,8 @@
 CcnxTunnel::setInterestFilter(const string &prefix, const InterestCallback &interestCallback)
 {
   WriteLock(m_ritLock);
-  m_rit.insert(make_pair(prefix, new InterestCallback(interestCallback)));
+  // make sure copy constructor for boost::function works properly
+  m_rit.insert(make_pair(prefix, interestCallback));
   return 0;
 }
 
@@ -96,5 +108,26 @@
   m_rit.erase(prefix);
 }
 
+TunnelClosurePass::TunnelClosurePass(int retry, const CcnxWrapper::DataCallback &dataCallback, const CcnxWrapper::TimeoutCallback &timeoutCallback, CcnxTunnel *tunnel, const string &originalInterest)
+                  : ClosurePass(retry, dataCallback, timeoutCallback)
+                  , m_tunnel(tunnel)
+                  , m_originalInterest(originalInterest)
+{
 }
 
+void 
+TunnelClosurePass::runDataCallback(const string &name, const Bytes &content)
+{
+  if (m_tunnel != NULL)
+  {
+    m_tunnel->handleTunneledData(name, content, (*m_dataCallback));
+  }
+}
+
+CcnxWrapper::TimeoutCallbackReturnValue
+TunnelClosurePass::runTimeoutCallback(const string &interest)
+{
+  return ClosurePass::runTimeoutCallback(m_originalInterest);
+}
+
+} // Ccnx
diff --git a/wscript b/wscript
index c51a765..a08e2b5 100644
--- a/wscript
+++ b/wscript
@@ -64,7 +64,7 @@
         source =  [
             'src/ccnx-wrapper.cpp',
             'src/ccnx-pco.cpp',
-            #'src/ccnx-tunnel.cpp',
+            'src/ccnx-tunnel.cpp',
             ],
         use = 'BOOST BOOST_THREAD SSL CCNX',
         includes = ['include', ],