more refactoring. Tunnel finishes
diff --git a/include/ccnx-closure.h b/include/ccnx-closure.h
new file mode 100644
index 0000000..54306d6
--- /dev/null
+++ b/include/ccnx-closure.h
@@ -0,0 +1,41 @@
+#ifndef CCNX_CLOSURE_H
+#define CCNX_CLOSURE_H
+
+#include "ccnx-common.h"
+
+using namespace std;
+
+namespace Ccnx {
+
+class Closure 
+{
+public:
+  typedef boost::function<void (const string &, const Bytes &)> DataCallback;
+
+  typedef enum
+  {
+    RESULT_OK,
+    RESULT_REEXPRESS
+  } TimeoutCallbackReturnValue;
+
+  typedef boost::function<TimeoutCallbackReturnValue (const string &)> TimeoutCallback;
+
+  Closure(int retry, const DataCallback &dataCallback, const TimeoutCallback &timeoutCallback);
+  Closure(const Closure &other);
+  int getRetry() {return m_retry;}
+  void decRetry() { m_retry--;}
+  virtual ~Closure();
+  virtual void 
+  runDataCallback(const string &name, const Bytes &content);
+  virtual TimeoutCallbackReturnValue 
+  runTimeoutCallback(const string &interest);
+
+protected:
+  int m_retry;
+  TimeoutCallback *m_timeoutCallback;
+  DataCallback *m_dataCallback;  
+};
+
+} // Ccnx
+
+#endif
diff --git a/include/ccnx-common.h b/include/ccnx-common.h
new file mode 100644
index 0000000..7394c03
--- /dev/null
+++ b/include/ccnx-common.h
@@ -0,0 +1,24 @@
+#ifndef CCNX_COMMON_H
+#define CCNX_COMMON_H
+
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include <boost/exception/all.hpp>
+#include <boost/function.hpp>
+#include <string>
+#include <sstream>
+#include <map>
+#include <utility>
+
+using namespace std;
+namespace Ccnx {
+typedef vector<unsigned char> Bytes;
+
+void
+readRaw(Bytes &bytes, const unsigned char *src, size_t len);
+
+const unsigned char *
+head(const Bytes &bytes);
+
+} // Ccnx
+#endif // CCNX_COMMON_H
diff --git a/include/ccnx-pco.h b/include/ccnx-pco.h
index 5b48ccf..1357333 100644
--- a/include/ccnx-pco.h
+++ b/include/ccnx-pco.h
@@ -1,9 +1,8 @@
 #ifndef CCNX_CONTENT_OBJECT_H
 #define CCNX_CONTENT_OBJECT_H
 
-#include <boost/exception/all.hpp>
-#include <boost/shared_ptr.hpp>
 #include "ccnx-wrapper.h"
+#include "ccnx-common.h"
 
 using namespace std;
 
diff --git a/include/ccnx-tunnel.h b/include/ccnx-tunnel.h
index c17569d..4e1eade 100644
--- a/include/ccnx-tunnel.h
+++ b/include/ccnx-tunnel.h
@@ -1,13 +1,10 @@
 #ifndef CCNX_TUNNEL_H
 #define CCNX_TUNNEL_H
 
-#include <string>
-#include <boost/function.hpp>
 #include <boost/variant.hpp>
 #include <boost/thread/locks.hpp>
-#include <utility>
-#include <map>
 
+#include "ccnx-common.h"
 #include "ccnx-wrapper.h"
 
 #define _OVERRIDE 
@@ -40,10 +37,10 @@
 
   // name is topology-independent
   virtual int
-  publishData(const string &name, const char *buf, size_t len, int freshness) _OVERRIDE;
+  publishData(const string &name, const unsigned 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;
+  sendInterest (const std::string &interest, Closure *closure);
 
 
   // prefix is topology-independent
@@ -76,7 +73,7 @@
   handleTunneledInterest(const string &tunneldInterest);
   
   void
-  handleTunneledData(const string &name, const Bytes &tunneledData, const DataCallback &originalDataCallback);
+  handleTunneledData(const string &name, const Bytes &tunneledData, const Closure::DataCallback &originalDataCallback);
 
 protected:
   // need a way to update local prefix, perhaps using macports trick, but eventually we need something more portable
@@ -85,15 +82,17 @@
   Lock m_ritLock;
 };
 
-class TunnelClosurePass : public ClosurePass
+class TunnelClosure : public Closure
 {
 public:
-  TunnelClosurePass(int retry, const CcnxWrapper::DataCallback &dataCallback, const CcnxWrapper::TimeoutCallback &timeoutCallback, CcnxTunnel *tunnel, const string &originalInterest);
+  TunnelClosure(int retry, const DataCallback &dataCallback, const TimeoutCallback &timeoutCallback, CcnxTunnel *tunnel, const string &originalInterest);
+
+  TunnelClosure(const Closure *closure, CcnxTunnel *tunnel, const string &originalInterest);
 
   virtual void 
   runDataCallback(const string &name, const Bytes &content) _OVERRIDE;
 
-  virtual CcnxWrapper::TimeoutCallbackReturnValue
+  virtual TimeoutCallbackReturnValue
   runTimeoutCallback(const string &interest) _OVERRIDE;
 
 private:
diff --git a/include/ccnx-wrapper.h b/include/ccnx-wrapper.h
index b4a8536..6ee5749 100644
--- a/include/ccnx-wrapper.h
+++ b/include/ccnx-wrapper.h
@@ -10,38 +10,22 @@
 #include <ccn/signing.h>
 }
 
-#include <vector>
-#include <boost/exception/all.hpp>
 #include <boost/thread/recursive_mutex.hpp>
 #include <boost/thread/thread.hpp>
-#include <boost/function.hpp>
-#include <string>
-#include <sstream>
-#include <map>
+
+#include "ccnx-common.h"
+#include "ccnx-closure.h"
 
 using namespace std;
 
 namespace Ccnx {
 
-typedef vector<unsigned char> Bytes;
-
-void
-readRaw(Bytes &bytes, const unsigned char *src, size_t len);
-
 struct CcnxOperationException : virtual boost::exception, virtual exception { };
 
-class CcnxWrapper {
+class CcnxWrapper 
+{
 public:
-  typedef boost::function<void (const string &, const Bytes &)> DataCallback;
   typedef boost::function<void (const string &)> InterestCallback;
-  typedef enum
-  {
-    RESULT_OK,
-    RESULT_REEXPRESS
-  } TimeoutCallbackReturnValue;
-  typedef boost::function<TimeoutCallbackReturnValue (const string &)> TimeoutCallback;
-
-public:
 
   CcnxWrapper();
   virtual ~CcnxWrapper();
@@ -53,10 +37,10 @@
   clearInterestFilter (const string &prefix);
 
   virtual int 
-  sendInterest (const string &strInterest, const DataCallback &dataCallback, int retry = 0, const TimeoutCallback &timeoutCallback = TimeoutCallback());
+  sendInterest (const string &strInterest, Closure *closure);
 
   virtual int 
-  publishData (const string &name, const char *buf, size_t len, int freshness);
+  publishData (const string &name, const unsigned char *buf, size_t len, int freshness);
 
   int
   publishData (const string &name, const Bytes &content, int freshness);
@@ -69,7 +53,7 @@
 
 protected:
   Bytes
-  createContentObject(const string &name, const char *buf, size_t len, int freshness);
+  createContentObject(const string &name, const unsigned char *buf, size_t len, int freshness);
 
   int 
   putToCcnd (const Bytes &contentObject);
@@ -97,8 +81,6 @@
   void
   ccnLoop ();
 
-  int 
-  sendInterest (const string &strInterest, void *dataPass);
   /// @endcond
 
 protected:
@@ -116,22 +98,6 @@
 
 typedef boost::shared_ptr<CcnxWrapper> CcnxWrapperPtr;
 
-class ClosurePass 
-{
-public:
-  ClosurePass(int retry, const CcnxWrapper::DataCallback &dataCallback, const CcnxWrapper::TimeoutCallback &timeoutCallback);
-  int getRetry() {return m_retry;}
-  void decRetry() { m_retry--;}
-  virtual ~ClosurePass();
-  virtual void runDataCallback(const string &name, const Bytes &content);
-  virtual CcnxWrapper::TimeoutCallbackReturnValue runTimeoutCallback(const string &interest);
-
-protected:
-  int m_retry;
-  CcnxWrapper::TimeoutCallback *m_timeoutCallback;
-  CcnxWrapper::DataCallback *m_dataCallback;  
-};
-
 
 } // Ccnx
 
diff --git a/src/ccnx-closure.cpp b/src/ccnx-closure.cpp
new file mode 100644
index 0000000..43b0d65
--- /dev/null
+++ b/src/ccnx-closure.cpp
@@ -0,0 +1,45 @@
+#include "ccnx-closure.h"
+
+namespace Ccnx {
+
+Closure::Closure(int retry, const DataCallback &dataCallback, const TimeoutCallback &timeoutCallback)
+              : m_retry(retry), m_timeoutCallback(NULL)
+{
+  m_timeoutCallback = new TimeoutCallback (timeoutCallback);
+  m_dataCallback = new DataCallback (dataCallback); 
+}
+
+Closure::Closure(const Closure &other)
+{
+  Closure(other.m_retry, *(other.m_dataCallback), *(other.m_timeoutCallback));
+}
+
+Closure::~Closure () 
+{
+  delete m_dataCallback;
+  delete m_timeoutCallback;
+  m_dataCallback = NULL;
+  m_timeoutCallback = NULL;
+}
+
+Closure::TimeoutCallbackReturnValue 
+Closure::runTimeoutCallback(const string &interest)
+{
+  if ((*m_timeoutCallback).empty())
+  {
+    return RESULT_OK;
+  }
+  
+  return (*m_timeoutCallback)(interest);
+}
+
+
+void 
+Closure::runDataCallback(const string &name, const Bytes &content) 
+{
+  if (m_dataCallback != NULL) {
+    (*m_dataCallback)(name, content);
+  }
+}
+
+} // Ccnx
diff --git a/src/ccnx-pco.cpp b/src/ccnx-pco.cpp
index e2db766..df3bd06 100644
--- a/src/ccnx-pco.cpp
+++ b/src/ccnx-pco.cpp
@@ -16,7 +16,7 @@
 
 ParsedContentObject::ParsedContentObject(const Bytes &bytes)
 {
-  ParsedContentObject((const unsigned char *)bytes[0], bytes.size());
+  ParsedContentObject(head(bytes), bytes.size());
 }
 
 ParsedContentObject::ParsedContentObject(const ParsedContentObject &other)
@@ -36,7 +36,7 @@
   const unsigned char *content;
   size_t len;
   Bytes bytes;
-  int res = ccn_content_get_value((const unsigned char *)m_bytes[0], m_pco.offset[CCN_PCO_E], &m_pco, &content, &len);
+  int res = ccn_content_get_value(head(m_bytes), m_pco.offset[CCN_PCO_E], &m_pco, &content, &len);
   if (res < 0)
   {
     boost::throw_exception(MisformedContentObjectException());
@@ -49,7 +49,7 @@
 string
 ParsedContentObject::name() const
 {
-  return CcnxWrapper::extractName((const unsigned char *)m_bytes[0], m_comps);
+  return CcnxWrapper::extractName(head(m_bytes), m_comps);
 }
 
 }
diff --git a/src/ccnx-tunnel.cpp b/src/ccnx-tunnel.cpp
index f12e2d5..467f7a1 100644
--- a/src/ccnx-tunnel.cpp
+++ b/src/ccnx-tunnel.cpp
@@ -28,28 +28,28 @@
 }
 
 int
-CcnxTunnel::sendInterest (const std::string &interest, const DataCallback &dataCallback, int retry, const TimeoutCallback &timeoutCallback)
+CcnxTunnel::sendInterest (const std::string &interest, Closure *closure)
 {
   string tunneledInterest = queryRoutableName(interest);
-  ClosurePass *cp = new TunnelClosurePass(retry, dataCallback, timeoutCallback, this, interest);
-  CcnxWrapper::sendInterest(tunneledInterest, cp);
+  Closure *cp = new TunnelClosure(closure, this, interest);
+  sendInterest(tunneledInterest, cp);
 }
 
 void 
-CcnxTunnel::handleTunneledData(const string &name, const Bytes &tunneledData, const DataCallback &originalDataCallback)
+CcnxTunnel::handleTunneledData(const string &name, const Bytes &tunneledData, const Closure::DataCallback &originalDataCallback)
 {
   ParsedContentObject pco(tunneledData);
   originalDataCallback(pco.name(), pco.content());
 }
 
 int
-CcnxTunnel::publishData(const string &name, const char *buf, size_t len, int freshness)
+CcnxTunnel::publishData(const string &name, const unsigned char *buf, size_t len, int freshness)
 {
   Bytes content = createContentObject(name, buf, len, freshness);
   storeContentObject(name, content);
   
   string tunneledName = m_localPrefix + name;
-  Bytes tunneledCo = createContentObject(tunneledName, (const char*)&content[0], content.size(), freshness);
+  Bytes tunneledCo = createContentObject(tunneledName, head(content), content.size(), freshness);
 
   return putToCcnd(tunneledCo);
 }
@@ -108,15 +108,21 @@
   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)
+TunnelClosure::TunnelClosure(int retry, const DataCallback &dataCallback, const TimeoutCallback &timeoutCallback, CcnxTunnel *tunnel, const string &originalInterest)
+                  : Closure(retry, dataCallback, timeoutCallback)
                   , m_tunnel(tunnel)
                   , m_originalInterest(originalInterest)
 {
 }
 
+TunnelClosure::TunnelClosure(const Closure *closure, CcnxTunnel *tunnel, const string &originalInterest)
+                 : Closure(*closure)
+                 , m_tunnel(tunnel)
+{
+}
+
 void 
-TunnelClosurePass::runDataCallback(const string &name, const Bytes &content)
+TunnelClosure::runDataCallback(const string &name, const Bytes &content)
 {
   if (m_tunnel != NULL)
   {
@@ -124,10 +130,10 @@
   }
 }
 
-CcnxWrapper::TimeoutCallbackReturnValue
-TunnelClosurePass::runTimeoutCallback(const string &interest)
+Closure::TimeoutCallbackReturnValue
+TunnelClosure::runTimeoutCallback(const string &interest)
 {
-  return ClosurePass::runTimeoutCallback(m_originalInterest);
+  return Closure::runTimeoutCallback(m_originalInterest);
 }
 
 } // Ccnx
diff --git a/src/ccnx-wrapper.cpp b/src/ccnx-wrapper.cpp
index 7549e3a..0710c67 100644
--- a/src/ccnx-wrapper.cpp
+++ b/src/ccnx-wrapper.cpp
@@ -26,6 +26,11 @@
   }
 }
 
+const unsigned char *
+head(const Bytes &bytes)
+{
+  return &bytes[0];
+}
 
 CcnxWrapper::CcnxWrapper()
   : m_handle (0)
@@ -207,7 +212,7 @@
 }
 
 Bytes
-CcnxWrapper::createContentObject(const std::string &name, const char *buf, size_t len, int freshness)
+CcnxWrapper::createContentObject(const std::string &name, const unsigned char *buf, size_t len, int freshness)
 {
   ccn_charbuf *pname = ccn_charbuf_create();
   ccn_charbuf *signed_info = ccn_charbuf_create();
@@ -223,7 +228,7 @@
 			 NULL,
 			 m_keyLoactor);
   if(ccn_encode_ContentObject(content, pname, signed_info,
-			   (const unsigned char *)buf, len,
+			   buf, len,
 			   NULL, getPrivateKey()) < 0)
   {
     // BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str("encode content failed"));
@@ -247,7 +252,7 @@
     return -1;
   
 
-  if (ccn_put(m_handle, (const unsigned char *)contentObject[0], contentObject.size()) < 0)
+  if (ccn_put(m_handle, head(contentObject), contentObject.size()) < 0)
   {
     // BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str("ccnput failed"));
   }
@@ -256,7 +261,7 @@
 }
 
 int
-CcnxWrapper::publishData (const string &name, const char *buf, size_t len, int freshness)
+CcnxWrapper::publishData (const string &name, const unsigned char *buf, size_t len, int freshness)
 {
   Bytes co = createContentObject(name, buf, len, freshness); 
   return putToCcnd(co);
@@ -265,7 +270,7 @@
 int
 CcnxWrapper::publishData (const string &name, const Bytes &content, int freshness)
 {
-  publishData(name, (const char*)content[0], content.size(), freshness);
+  publishData(name, head(content), content.size(), freshness);
 }
 
 string
@@ -318,7 +323,7 @@
              ccn_upcall_kind kind,
              ccn_upcall_info *info)
 {
-  ClosurePass *cp = static_cast<ClosurePass *> (selfp->data);
+  Closure *cp = static_cast<Closure *> (selfp->data);
 
   switch (kind)
     {
@@ -338,11 +343,11 @@
       }
 
       string interest = CcnxWrapper::extractName(info->interest_ccnb, info->interest_comps);
-      CcnxWrapper::TimeoutCallbackReturnValue rv = cp->runTimeoutCallback(interest);
+      Closure::TimeoutCallbackReturnValue rv = cp->runTimeoutCallback(interest);
       switch(rv)
       {
-        case CcnxWrapper::RESULT_OK : return CCN_UPCALL_RESULT_OK;
-        case CcnxWrapper::RESULT_REEXPRESS : return CCN_UPCALL_RESULT_REEXPRESS;
+        case Closure::RESULT_OK : return CCN_UPCALL_RESULT_OK;
+        case Closure::RESULT_REEXPRESS : return CCN_UPCALL_RESULT_REEXPRESS;
         default : break;
       }
       return CCN_UPCALL_RESULT_OK;
@@ -371,14 +376,7 @@
   return CCN_UPCALL_RESULT_OK;
 }
 
-
-int CcnxWrapper::sendInterest (const string &strInterest, const DataCallback &dataCallback, int retry, const TimeoutCallback &timeoutCallback)
-{
-  ClosurePass * pass = new ClosurePass(retry, dataCallback, timeoutCallback);
-  sendInterest(strInterest, pass);
-}
-
-int CcnxWrapper::sendInterest (const string &strInterest, void *dataPass)
+int CcnxWrapper::sendInterest (const string &strInterest, Closure *closure)
 {
   recursive_mutex::scoped_lock lock(m_mutex);
   if (!m_running || !m_connected)
@@ -388,7 +386,7 @@
   ccn_closure *dataClosure = new ccn_closure;
 
   ccn_name_from_uri (pname, strInterest.c_str());
-  dataClosure->data = dataPass;
+  dataClosure->data = (void *)closure;
 
   dataClosure->p = &incomingData;
   if (ccn_express_interest (m_handle, pname, dataClosure, NULL) < 0)
@@ -521,40 +519,4 @@
   return retval;
 }
 
-
-ClosurePass::ClosurePass(int retry, const CcnxWrapper::DataCallback &dataCallback, const CcnxWrapper::TimeoutCallback &timeoutCallback)
-              : m_retry(retry), m_timeoutCallback(NULL)
-{
-  m_timeoutCallback = new CcnxWrapper::TimeoutCallback (timeoutCallback);
-  m_dataCallback = new CcnxWrapper::DataCallback (dataCallback); 
-}
-
-ClosurePass::~ClosurePass () 
-{
-  delete m_dataCallback;
-  delete m_timeoutCallback;
-  m_dataCallback = NULL;
-  m_timeoutCallback = NULL;
-}
-
-CcnxWrapper::TimeoutCallbackReturnValue
-ClosurePass::runTimeoutCallback(const string &interest)
-{
-  if ((*m_timeoutCallback).empty())
-  {
-    return CcnxWrapper::RESULT_OK;
-  }
-  
-  return (*m_timeoutCallback)(interest);
-}
-
-
-void 
-ClosurePass::runDataCallback(const string &name, const Bytes &content) 
-{
-  if (m_dataCallback != NULL) {
-    (*m_dataCallback)(name, content);
-  }
-}
-
 }
diff --git a/wscript b/wscript
index a08e2b5..4e55f15 100644
--- a/wscript
+++ b/wscript
@@ -64,6 +64,7 @@
         source =  [
             'src/ccnx-wrapper.cpp',
             'src/ccnx-pco.cpp',
+            'src/ccnx-closure.cpp',
             'src/ccnx-tunnel.cpp',
             ],
         use = 'BOOST BOOST_THREAD SSL CCNX',