run timeoutcallback of ccnx wrapper in executor
provide selectors for interest callback
diff --git a/ccnx/ccnx-closure.cpp b/ccnx/ccnx-closure.cpp
index ccfeafa..5736511 100644
--- a/ccnx/ccnx-closure.cpp
+++ b/ccnx/ccnx-closure.cpp
@@ -33,15 +33,13 @@
 {
 }
 
-Closure::TimeoutCallbackReturnValue
-Closure::runTimeoutCallback(Name interest)
+void
+Closure::runTimeoutCallback(Name interest, const Closure &closure, Selectors selectors)
 {
-  if (m_timeoutCallback.empty ())
+  if (!m_timeoutCallback.empty ())
     {
-      return RESULT_OK;
+      m_timeoutCallback (interest, closure, selectors);
     }
-
-  return m_timeoutCallback (interest);
 }
 
 
diff --git a/ccnx/ccnx-closure.h b/ccnx/ccnx-closure.h
index 9741f6b..6a1b8d8 100644
--- a/ccnx/ccnx-closure.h
+++ b/ccnx/ccnx-closure.h
@@ -24,6 +24,7 @@
 
 #include "ccnx-common.h"
 #include "ccnx-name.h"
+#include "ccnx-selectors.h"
 #include "executor.h"
 
 namespace Ccnx {
@@ -36,13 +37,7 @@
 public:
   typedef boost::function<void (Name, PcoPtr pco)> DataCallback;
 
-  typedef enum
-  {
-    RESULT_OK,
-    RESULT_REEXPRESS
-  } TimeoutCallbackReturnValue;
-
-  typedef boost::function<TimeoutCallbackReturnValue (Name )> TimeoutCallback;
+  typedef boost::function<void (Name, const Closure &, Selectors)> TimeoutCallback;
 
   Closure(const DataCallback &dataCallback, const TimeoutCallback &timeoutCallback = TimeoutCallback());
   virtual ~Closure();
@@ -50,8 +45,8 @@
   virtual void
   runDataCallback(Name name, Ccnx::PcoPtr pco);
 
-  virtual TimeoutCallbackReturnValue
-  runTimeoutCallback(Name interest);
+  virtual void
+  runTimeoutCallback(Name interest, const Closure &closure, Selectors selectors);
 
   virtual Closure *
   dup () const { return new Closure (*this); }
diff --git a/ccnx/ccnx-selectors.cpp b/ccnx/ccnx-selectors.cpp
index b349cc1..510aaa9 100644
--- a/ccnx/ccnx-selectors.cpp
+++ b/ccnx/ccnx-selectors.cpp
@@ -27,6 +27,38 @@
   m_publisherPublicKeyDigest = other.m_publisherPublicKeyDigest;
 }
 
+Selectors::Selectors(const ccn_parsed_interest *pi)
+          : m_maxSuffixComps(-1)
+          , m_minSuffixComps(-1)
+          , m_answerOriginKind(AOK_DEFAULT)
+          , m_interestLifetime(-1.0)
+          , m_scope(-1)
+          , m_childSelector(DEFAULT)
+{
+  if (pi != NULL)
+  {
+    m_maxSuffixComps = pi->max_suffix_comps;
+    m_minSuffixComps = pi->min_suffix_comps;
+    switch(pi->orderpref)
+    {
+      case 0: m_childSelector = LEFT; break;
+      case 1: m_childSelector = RIGHT; break;
+      default: break;
+    }
+    switch(pi->answerfrom)
+    {
+      case 0x1: m_answerOriginKind = AOK_CS; break;
+      case 0x2: m_answerOriginKind = AOK_NEW; break;
+      case 0x3: m_answerOriginKind = AOK_DEFAULT; break;
+      case 0x4: m_answerOriginKind = AOK_STALE; break;
+      case 0x10: m_answerOriginKind = AOK_EXPIRE; break;
+      default: break;
+    }
+    m_scope = pi->scope;
+    // scope and interest lifetime do not really matter to receiving application, it's only meaningful to routers
+  }
+}
+
 bool
 Selectors::operator == (const Selectors &other)
 {
diff --git a/ccnx/ccnx-selectors.h b/ccnx/ccnx-selectors.h
index 56e29b5..a1125b9 100644
--- a/ccnx/ccnx-selectors.h
+++ b/ccnx/ccnx-selectors.h
@@ -33,6 +33,7 @@
 {
 public:
   Selectors();
+  Selectors(const ccn_parsed_interest *);
   Selectors(const Selectors &other);
   ~Selectors(){};
 
diff --git a/ccnx/ccnx-wrapper.cpp b/ccnx/ccnx-wrapper.cpp
index 0453789..2867ecc 100644
--- a/ccnx/ccnx-wrapper.cpp
+++ b/ccnx/ccnx-wrapper.cpp
@@ -283,8 +283,9 @@
     }
 
   Name interest(info->interest_ccnb, info->interest_comps);
+  Selectors selectors(info->pi);
 
-  executor->execute (bind (*f, interest));
+  executor->execute (bind (*f, interest, selectors));
   // this will be run in executor
   // (*f) (interest);
   // closure->runInterestCallback(interest);
@@ -294,7 +295,7 @@
 }
 
 static void
-deleterInDataTuple (tuple<Closure *, ExecutorPtr> *tuple)
+deleterInDataTuple (tuple<Closure *, ExecutorPtr, Selectors> *tuple)
 {
   delete tuple->get<0> ();
   delete tuple;
@@ -308,8 +309,9 @@
   // Closure *cp = static_cast<Closure *> (selfp->data);
   Closure *cp;
   ExecutorPtr executor;
-  tuple<Closure *, ExecutorPtr> *realData = reinterpret_cast< tuple<Closure*, ExecutorPtr>* > (selfp->data);
-  tie (cp, executor) = *realData;
+  Selectors selectors;
+  tuple<Closure *, ExecutorPtr, Selectors> *realData = reinterpret_cast< tuple<Closure*, ExecutorPtr, Selectors>* > (selfp->data);
+  tie (cp, executor, selectors) = *realData;
 
   _LOG_TRACE (">> incomingData upcall");
 
@@ -331,14 +333,7 @@
       {
         _LOG_TRACE ("<< incomingData timeout");
         Name interest(info->interest_ccnb, info->interest_comps);
-        // We can not run timeout callback in executor, because we need the return value
-        Closure::TimeoutCallbackReturnValue rv = cp->runTimeoutCallback(interest);
-        switch(rv)
-        {
-          case Closure::RESULT_OK : return CCN_UPCALL_RESULT_OK;
-          case Closure::RESULT_REEXPRESS : return CCN_UPCALL_RESULT_REEXPRESS;
-          default : break;
-        }
+        executor->execute (bind (&Closure::runTimeoutCallback, cp, interest, *cp, selectors));
       }
       else
         {
@@ -394,7 +389,7 @@
 
   // Closure *myClosure = new ExecutorClosure(closure, m_executor);
   Closure *myClosure = closure.dup ();
-  dataClosure->data = new tuple<Closure*, ExecutorPtr> (myClosure, m_executor);
+  dataClosure->data = new tuple<Closure*, ExecutorPtr, Selectors> (myClosure, m_executor, selectors);
 
   dataClosure->p = &incomingData;
 
diff --git a/ccnx/ccnx-wrapper.h b/ccnx/ccnx-wrapper.h
index 91e28c5..32d180c 100644
--- a/ccnx/ccnx-wrapper.h
+++ b/ccnx/ccnx-wrapper.h
@@ -42,7 +42,7 @@
 public:
   const static int MAX_FRESHNESS = 2147; // max value for ccnx
   const static int DEFAULT_FRESHNESS = 60;
-  typedef boost::function<void (const Name &)> InterestCallback;
+  typedef boost::function<void (Name, Selectors)> InterestCallback;
 
   CcnxWrapper();
   virtual ~CcnxWrapper();
diff --git a/src/fetcher.cc b/src/fetcher.cc
index a67f76a..2192fd7 100644
--- a/src/fetcher.cc
+++ b/src/fetcher.cc
@@ -104,7 +104,7 @@
       // cout << ">>> " << m_minSendSeqNo+1 << endl;
       m_ccnx->sendInterest (Name (m_forwardingHint)(m_name)(m_minSendSeqNo+1),
                             Closure (bind(&Fetcher::OnData, this, m_minSendSeqNo+1, _1, _2),
-                                     bind(&Fetcher::OnTimeout, this, m_minSendSeqNo+1, _1)),
+                                     bind(&Fetcher::OnTimeout, this, m_minSendSeqNo+1, _1, _2, _3)),
                             Selectors().interestLifetime (1)); // Alex: this lifetime should be changed to RTO
       _LOG_DEBUG (" >>> i ok");
 
@@ -181,8 +181,8 @@
     }
 }
 
-Closure::TimeoutCallbackReturnValue
-Fetcher::OnTimeout (uint64_t seqno, const Ccnx::Name &name)
+void
+Fetcher::OnTimeout (uint64_t seqno, const Ccnx::Name &name, const Closure &closure, Selectors selectors)
 {
   _LOG_DEBUG (" <<< :( timeout " << name.getPartialName (0, name.size () - 1) << ", seq = " << seqno);
 
@@ -202,11 +202,10 @@
           m_onFetchFailed (*this);
           // this is not valid anymore, but we still should be able finish work
         }
-      return Closure::RESULT_OK;
     }
   else
     {
       _LOG_DEBUG ("Asking to reexpress");
-      return Closure::RESULT_REEXPRESS;
+      m_ccnx->sendInterest (name, closure, selectors);
     }
 }
diff --git a/src/fetcher.h b/src/fetcher.h
index 6a31b5e..7ab08c9 100644
--- a/src/fetcher.h
+++ b/src/fetcher.h
@@ -86,8 +86,8 @@
   void
   OnData (uint64_t seqno, const Ccnx::Name &name, Ccnx::PcoPtr data);
 
-  Ccnx::Closure::TimeoutCallbackReturnValue
-  OnTimeout (uint64_t seqno, const Ccnx::Name &name);
+  void
+  OnTimeout (uint64_t seqno, const Ccnx::Name &name, const Ccnx::Closure &closure, Ccnx::Selectors selectors);
 
 public:
   boost::intrusive::list_member_hook<> m_managerListHook;
diff --git a/src/sync-core.cc b/src/sync-core.cc
index 191b92b..5a195f6 100644
--- a/src/sync-core.cc
+++ b/src/sync-core.cc
@@ -189,21 +189,19 @@
   }
 }
 
-Closure::TimeoutCallbackReturnValue
-SyncCore::handleSyncInterestTimeout(const Name &name)
+void
+SyncCore::handleSyncInterestTimeout(const Name &name, const Closure &closure, Selectors selectors)
 {
   // sync interest will be resent by scheduler
-  return Closure::RESULT_OK;
 }
 
-Closure::TimeoutCallbackReturnValue
-SyncCore::handleRecoverInterestTimeout(const Name &name)
+void
+SyncCore::handleRecoverInterestTimeout(const Name &name, const Closure &closure, Selectors selectors)
 {
   // We do not re-express recovery interest for now
   // if difference is not resolved, the sync interest will trigger
   // recovery anyway; so it's not so important to have recovery interest
   // re-expressed
-  return Closure::RESULT_OK;
 }
 
 void
@@ -322,7 +320,7 @@
   }
   m_ccnx->sendInterest(syncInterest,
                          Closure (boost::bind(&SyncCore::handleSyncData, this, _1, _2),
-                                  boost::bind(&SyncCore::handleSyncInterestTimeout, this, _1)),
+                                  boost::bind(&SyncCore::handleSyncInterestTimeout, this, _1, _2, _3)),
                           selectors);
 
   // if there is a pending syncSyncInterest task, reschedule it to be m_syncInterestInterval seconds from now
@@ -347,7 +345,7 @@
 
     m_ccnx->sendInterest(recoverInterest,
                          Closure (boost::bind(&SyncCore::handleRecoverData, this, _1, _2),
-                                  boost::bind(&SyncCore::handleRecoverInterestTimeout, this, _1)));
+                                  boost::bind(&SyncCore::handleRecoverInterestTimeout, this, _1, _2, _3)));
 
   }
   else
diff --git a/src/sync-core.h b/src/sync-core.h
index 423afcc..b804ac5 100644
--- a/src/sync-core.h
+++ b/src/sync-core.h
@@ -24,6 +24,7 @@
 
 #include "sync-log.h"
 #include "ccnx-wrapper.h"
+#include "ccnx-selectors.h"
 #include "scheduler.h"
 #include "task.h"
 
@@ -76,11 +77,11 @@
   void
   handleRecoverData(const Ccnx::Name &name, Ccnx::PcoPtr content);
 
-  Ccnx::Closure::TimeoutCallbackReturnValue
-  handleSyncInterestTimeout(const Ccnx::Name &name);
+  void
+  handleSyncInterestTimeout(const Ccnx::Name &name, const Ccnx::Closure &closure, Ccnx::Selectors selectors);
 
-  Ccnx::Closure::TimeoutCallbackReturnValue
-  handleRecoverInterestTimeout(const Ccnx::Name &name);
+  void
+  handleRecoverInterestTimeout(const Ccnx::Name &name, const Ccnx::Closure &closure, Ccnx::Selectors selectors);
 
   void
   deregister(const Ccnx::Name &name);
diff --git a/test/test-ccnx-wrapper.cc b/test/test-ccnx-wrapper.cc
index ad64617..dc2b0ce 100644
--- a/test/test-ccnx-wrapper.cc
+++ b/test/test-ccnx-wrapper.cc
@@ -61,10 +61,10 @@
   BOOST_CHECK_EQUAL(name, msg);
 }
 
-Closure::TimeoutCallbackReturnValue timeout(const Name &name)
+void
+timeout(const Name &name, const Closure &closure, Selectors selectors)
 {
   g_timeout_counter ++;
-  return Closure::RESULT_OK;
 }
 
 BOOST_AUTO_TEST_CASE (BlaCcnxWrapperTest)
@@ -79,7 +79,7 @@
   usleep(100000);
   c2->setInterestFilter(prefix2, bind(publish2, _1));
 
-  Closure closure (bind(dataCallback, _1, _2), bind(timeout, _1));
+  Closure closure (bind(dataCallback, _1, _2), bind(timeout, _1, _2, _3));
 
   c1->sendInterest(Name("/c2/hi"), closure);
   usleep(100000);
@@ -94,7 +94,7 @@
 BOOST_AUTO_TEST_CASE (CcnxWrapperSelector)
 {
 
-  Closure closure (bind(dataCallback, _1, _2), bind(timeout, _1));
+  Closure closure (bind(dataCallback, _1, _2), bind(timeout, _1, _2, _3));
 
   Selectors selectors;
   selectors.interestLifetime(1);