Added Node class, and move most functionality from Face to Node. Make connect take a Node, not a Face.
diff --git a/ndn-cpp/closure.hpp b/ndn-cpp/closure.hpp
index e8cc191..81846f1 100644
--- a/ndn-cpp/closure.hpp
+++ b/ndn-cpp/closure.hpp
@@ -33,27 +33,27 @@
   UPCALL_DATA_BAD           = 6  // verification failed  
 };
 
-class Face;
+class Node;
 class Interest;
 class Data;
 
 class UpcallInfo {
 public:
-  UpcallInfo(Face *ndn, ptr_lib::shared_ptr<Interest> &interest, int matchedComps, ptr_lib::shared_ptr<Data> &data) 
+  UpcallInfo(Node *node, ptr_lib::shared_ptr<Interest> &interest, int matchedComps, ptr_lib::shared_ptr<Data> &data) 
   {
-    ndn_ = ndn;
+    node_ = node;
     interest_ = interest;
     data_ = data;
   }
   
-  Face *getNDN() { return ndn_; }
+  Node *getNode() { return node_; }
   
   ptr_lib::shared_ptr<Interest> &getInterest() { return interest_; }
   
   ptr_lib::shared_ptr<Data> &getData() { return data_; }
   
 private:
-  Face *ndn_;
+  Node *node_;
   ptr_lib::shared_ptr<Interest> interest_;
   ptr_lib::shared_ptr<Data> data_;
 };
diff --git a/ndn-cpp/face.cpp b/ndn-cpp/face.cpp
index 89462d6..7b0d3ea 100644
--- a/ndn-cpp/face.cpp
+++ b/ndn-cpp/face.cpp
@@ -3,50 +3,15 @@
  * See COPYING for copyright and distribution information.
  */
 
-#include "encoding/binary-xml-decoder.hpp"
-#include "c/encoding/binary-xml.h"
-#include "data.hpp"
 #include "face.hpp"
 
 using namespace std;
-using namespace ndn::ptr_lib;
 
 namespace ndn {
-
-void Face::expressInterest(const Name &name, Closure *closure, const Interest *interestTemplate)
-{
-  Interest interest(name);
-  shared_ptr<vector<unsigned char> > encoding = interest.wireEncode();  
-
-  // TODO: This should go in the PIT.
-  tempClosure_ = closure;
   
-  transport_->connect(*this);
-  transport_->send(*encoding);
-}
-
-void Face::processEvents()
-{
-  transport_->processEvents();
-}
-
 void Face::shutdown()
 {
-  transport_->close();
-}
-
-void Face::onReceivedElement(unsigned char *element, unsigned int elementLength)
-{
-  BinaryXmlDecoder decoder(element, elementLength);
-  
-  if (decoder.peekDTag(ndn_BinaryXml_DTag_ContentObject)) {
-    shared_ptr<Data> data(new Data());
-    data->wireDecode(element, elementLength);
-    
-    shared_ptr<Interest> dummyInterest;
-    UpcallInfo upcallInfo(this, dummyInterest, 0, data);
-    tempClosure_->upcall(UPCALL_DATA, upcallInfo);
-  }
+  node_.shutdown();
 }
 
 }
diff --git a/ndn-cpp/face.hpp b/ndn-cpp/face.hpp
index 64d835c..c98932c 100644
--- a/ndn-cpp/face.hpp
+++ b/ndn-cpp/face.hpp
@@ -6,19 +6,14 @@
 #ifndef NDN_FACE_HPP
 #define NDN_FACE_HPP
 
-#include "closure.hpp"
-#include "interest.hpp"
-#include "transport/udp-transport.hpp"
-#include "encoding/binary-xml-element-reader.hpp"
-
-using namespace std;
+#include "node.hpp"
 
 namespace ndn {
 
 /**
  * The Face class provides the main methods for NDN communication.
  */
-class Face : public ElementListener {
+class Face {
 public:
   /**
    * Create a new Face for communication with an NDN hub at host:port with the given Transport object.
@@ -27,7 +22,7 @@
    * @param transport A pointer to a Transport object used for communication.
    */
   Face(const char *host, unsigned short port, const ptr_lib::shared_ptr<Transport> &transport)
-  : host_(host), port_(port), transport_(transport), tempClosure_(0)
+  : node_(host, port, transport)
   {
   }
   
@@ -37,7 +32,7 @@
    * @param port The port of the NDN hub.
    */
   Face(const char *host, unsigned short port)
-  : host_(host), port_(port), transport_(new UdpTransport()), tempClosure_(0)
+  : node_(host, port)
   {
   }
   
@@ -46,7 +41,7 @@
    * @param host The host of the NDN hub.
    */
   Face(const char *host)
-  : host_(host), port_(9695), transport_(new UdpTransport()), tempClosure_(0)
+  : node_(host)
   {
   }
 
@@ -59,37 +54,36 @@
    * @param closure a pointer for the Closure.  The caller must manage the memory for the Closure.  This will not try to delete it.
    * @param interestTemplate if not 0, copy interest selectors from the template.   This does not keep a pointer to the Interest object.
    */
-  void expressInterest(const Name &name, Closure *closure, const Interest *interestTemplate);
+  void expressInterest(const Name &name, Closure *closure, const Interest *interestTemplate)
+  {
+    node_.expressInterest(name, closure, interestTemplate);
+  }
   
   void expressInterest(const Name &name, Closure *closure)
   {
-    expressInterest(name, closure, 0);
+    node_.expressInterest(name, closure);
   }
   
   /**
-   * Process any data to receive.  For each element received, call face.onReceivedElement.
+   * Process any data to receive or call timeout callbacks.
    * This is non-blocking and will return immediately if there is no data to receive.
    * You should repeatedly call this from an event loop, with calls to sleep as needed so that the loop doesn't use 100% of the CPU.
    * @throw This may throw an exception for reading data or in the callback for processing the data.  If you
    * call this from an main event loop, you may want to catch and log/disregard all exceptions.
    */
-  void processEvents();
+  void processEvents()
+  {
+    // Just call Node's processEvents.
+    node_.processEvents();
+  }
 
+  /**
+   * Shut down and disconnect this Face.
+   */
   void shutdown();
   
-  const char *getHost() const { return host_.c_str(); }
-  
-  unsigned short getPort() const { return port_; }
-  
-  const ptr_lib::shared_ptr<Transport> &getTransport() { return transport_; }
-  
-  virtual void onReceivedElement(unsigned char *element, unsigned int elementLength);
-  
 private:
-  ptr_lib::shared_ptr<Transport> transport_;
-  string host_;
-  unsigned short port_;
-  Closure *tempClosure_;
+  Node node_;
 };
 
 }
diff --git a/ndn-cpp/node.cpp b/ndn-cpp/node.cpp
new file mode 100644
index 0000000..fed4c8e
--- /dev/null
+++ b/ndn-cpp/node.cpp
@@ -0,0 +1,52 @@
+/**
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "encoding/binary-xml-decoder.hpp"
+#include "c/encoding/binary-xml.h"
+#include "data.hpp"
+#include "Node.hpp"
+
+using namespace std;
+using namespace ndn::ptr_lib;
+
+namespace ndn {
+
+void Node::expressInterest(const Name &name, Closure *closure, const Interest *interestTemplate)
+{
+  Interest interest(name);
+  shared_ptr<vector<unsigned char> > encoding = interest.wireEncode();  
+
+  // TODO: This should go in the PIT.
+  tempClosure_ = closure;
+  
+  transport_->connect(*this);
+  transport_->send(*encoding);
+}
+
+void Node::processEvents()
+{
+  transport_->processEvents();
+}
+
+void Node::onReceivedElement(unsigned char *element, unsigned int elementLength)
+{
+  BinaryXmlDecoder decoder(element, elementLength);
+  
+  if (decoder.peekDTag(ndn_BinaryXml_DTag_ContentObject)) {
+    shared_ptr<Data> data(new Data());
+    data->wireDecode(element, elementLength);
+    
+    shared_ptr<Interest> dummyInterest;
+    UpcallInfo upcallInfo(this, dummyInterest, 0, data);
+    tempClosure_->upcall(UPCALL_DATA, upcallInfo);
+  }
+}
+
+void Node::shutdown()
+{
+  transport_->close();
+}
+
+}
diff --git a/ndn-cpp/node.hpp b/ndn-cpp/node.hpp
new file mode 100644
index 0000000..789a584
--- /dev/null
+++ b/ndn-cpp/node.hpp
@@ -0,0 +1,94 @@
+/**
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_NODE_HPP
+#define NDN_NODE_HPP
+
+#include "interest.hpp"
+#include "closure.hpp"
+#include "transport/udp-transport.hpp"
+#include "encoding/binary-xml-element-reader.hpp"
+
+namespace ndn {
+
+class Face;
+  
+class Node : public ElementListener {
+public:
+  /**
+   * Create a new Node for communication with an NDN hub at host:port with the given Transport object.
+   * @param host The host of the NDN hub.
+   * @param port The port of the NDN hub.
+   * @param transport A pointer to a Transport object used for communication.
+   */
+  Node(const char *host, unsigned short port, const ptr_lib::shared_ptr<Transport> &transport)
+  : host_(host), port_(port), transport_(transport), tempClosure_(0)
+  {
+  }
+  
+  /**
+   * Create a new Node for communication with an NDN hub at host:port using the default UdpTransport.
+   * @param host The host of the NDN hub.
+   * @param port The port of the NDN hub.
+   */
+  Node(const char *host, unsigned short port)
+  : host_(host), port_(port), transport_(new UdpTransport()), tempClosure_(0)
+  {
+  }
+  
+  /**
+   * Create a new Node for communication with an NDN hub at host with the default port 9695 and using the default UdpTransport.
+   * @param host The host of the NDN hub.
+   */
+  Node(const char *host)
+  : host_(host), port_(9695), transport_(new UdpTransport()), tempClosure_(0)
+  {
+  }
+
+  /**
+   * Encode name as an Interest. If interestTemplate is not 0, use its interest selectors.
+   * Send the interest through the transport, read the entire response and call
+   * closure->upcall(UPCALL_DATA (or UPCALL_DATA_UNVERIFIED),
+   *                 UpcallInfo(this, interest, 0, data)).
+   * @param name reference to a Name for the interest.  This does not keep a pointer to the Name object.
+   * @param closure a pointer for the Closure.  The caller must manage the memory for the Closure.  This will not try to delete it.
+   * @param interestTemplate if not 0, copy interest selectors from the template.   This does not keep a pointer to the Interest object.
+   */
+  void expressInterest(const Name &name, Closure *closure, const Interest *interestTemplate);
+  
+  void expressInterest(const Name &name, Closure *closure)
+  {
+    expressInterest(name, closure, 0);
+  }
+
+  /**
+   * Process any data to receive.  For each element received, call onReceivedElement.
+   * This is non-blocking and will return immediately if there is no data to receive.
+   * You should repeatedly call this from an event loop, with calls to sleep as needed so that the loop doesn't use 100% of the CPU.
+   * @throw This may throw an exception for reading data or in the callback for processing the data.  If you
+   * call this from an main event loop, you may want to catch and log/disregard all exceptions.
+   */
+  void processEvents();
+  
+  const char *getHost() const { return host_.c_str(); }
+  
+  unsigned short getPort() const { return port_; }
+  
+  const ptr_lib::shared_ptr<Transport> &getTransport() { return transport_; }
+  
+  virtual void onReceivedElement(unsigned char *element, unsigned int elementLength);
+  
+  void shutdown();
+
+private:
+  ptr_lib::shared_ptr<Transport> transport_;
+  std::string host_;
+  unsigned short port_;
+  Closure *tempClosure_;
+};
+
+}
+
+#endif
diff --git a/ndn-cpp/transport/tcp-transport.cpp b/ndn-cpp/transport/tcp-transport.cpp
index aa438bc..a0a53de 100644
--- a/ndn-cpp/transport/tcp-transport.cpp
+++ b/ndn-cpp/transport/tcp-transport.cpp
@@ -4,7 +4,7 @@
  */
 
 #include <stdexcept>
-#include "../face.hpp"
+#include "../node.hpp"
 #include "../c/util/ndn_realloc.h"
 #include "tcp-transport.hpp"
 
@@ -12,20 +12,20 @@
 
 namespace ndn {
 
-void TcpTransport::connect(Face &face)
+void TcpTransport::connect(Node &node)
 {
   ndn_Error error;
-  if ((error = ndn_TcpTransport_connect(&transport_, (char *)face.getHost(), face.getPort())))
+  if ((error = ndn_TcpTransport_connect(&transport_, (char *)node.getHost(), node.getPort())))
     throw std::runtime_error(ndn_getErrorString(error)); 
 
   // TODO: This belongs in the socket listener.
   const unsigned int initialLength = 1000;
   // Automatically cast ndn_ to (struct ndn_ElementListener *)
   ndn_BinaryXmlElementReader_init
-    (&elementReader_, &face, (unsigned char *)malloc(initialLength), initialLength, ndn_realloc);
+    (&elementReader_, &node, (unsigned char *)malloc(initialLength), initialLength, ndn_realloc);
   
   // TODO: Properly indicate connected status.
-  face_ = &face;
+  node_ = &node;
 }
 
 void TcpTransport::send(const unsigned char *data, unsigned int dataLength)
diff --git a/ndn-cpp/transport/tcp-transport.hpp b/ndn-cpp/transport/tcp-transport.hpp
index f3c5e91..1028def 100644
--- a/ndn-cpp/transport/tcp-transport.hpp
+++ b/ndn-cpp/transport/tcp-transport.hpp
@@ -15,17 +15,17 @@
 class TcpTransport : public Transport {
 public:
   TcpTransport() 
+  : node_(0)
   {
     ndn_TcpTransport_init(&transport_);
-    face_ = 0;
     elementReader_.partialData.array = 0;
   }
   
   /**
-   * Connect to the host specified in face.
-   * @param face Not a shared_ptr because we assume that it will remain valid during the life of this Transport object.
+   * Connect to the host specified in node.
+   * @param node Not a shared_ptr because we assume that it will remain valid during the life of this Transport object.
    */
-  virtual void connect(Face &face);
+  virtual void connect(Node &node);
   
   /**
    * Set data to the host
@@ -35,7 +35,7 @@
   virtual void send(const unsigned char *data, unsigned int dataLength);
 
   /**
-   * Process any data to receive.  For each element received, call face.onReceivedElement.
+   * Process any data to receive.  For each element received, call node.onReceivedElement.
    * This is non-blocking and will return immediately if there is no data to receive.
    * You should normally not call this directly since it is called by Face.processEvents.
    * @throw This may throw an exception for reading data or in the callback for processing the data.  If you
@@ -52,7 +52,7 @@
   
 private:
   struct ndn_TcpTransport transport_;
-  Face *face_;
+  Node *node_;
   // TODO: This belongs in the socket listener.
   ndn_BinaryXmlElementReader elementReader_;
 };
diff --git a/ndn-cpp/transport/transport.cpp b/ndn-cpp/transport/transport.cpp
index e16a879..cbcb659 100644
--- a/ndn-cpp/transport/transport.cpp
+++ b/ndn-cpp/transport/transport.cpp
@@ -10,7 +10,7 @@
 
 namespace ndn {
 
-void Transport::connect(Face &face) 
+void Transport::connect(Node &node) 
 {
   throw logic_error("unimplemented");
 }
diff --git a/ndn-cpp/transport/transport.hpp b/ndn-cpp/transport/transport.hpp
index 3246340..9159b99 100644
--- a/ndn-cpp/transport/transport.hpp
+++ b/ndn-cpp/transport/transport.hpp
@@ -10,14 +10,14 @@
 
 namespace ndn {
 
-class Face;  
+class Node;  
 class Transport {
 public:
   /**
-   * Connect to the host specified in face.
-   * @param face Not a shared_ptr because we assume that it will remain valid during the life of this Transport object.
+   * Connect to the host specified in node.
+   * @param node Not a shared_ptr because we assume that it will remain valid during the life of this Transport object.
    */
-  virtual void connect(Face &face);
+  virtual void connect(Node &node);
   
   /**
    * Set data to the host
@@ -32,7 +32,7 @@
   }
   
   /**
-   * Process any data to receive.  For each element received, call face.onReceivedElement.
+   * Process any data to receive.  For each element received, call node.onReceivedElement.
    * This is non-blocking and will silently time out after a brief period if there is no data to receive.
    * You should repeatedly call this from an event loop.
    * @throw This may throw an exception for reading data or in the callback for processing the data.  If you
diff --git a/ndn-cpp/transport/udp-transport.cpp b/ndn-cpp/transport/udp-transport.cpp
index 4ae9e37..b1d90e8 100644
--- a/ndn-cpp/transport/udp-transport.cpp
+++ b/ndn-cpp/transport/udp-transport.cpp
@@ -12,20 +12,20 @@
 
 namespace ndn {
 
-void UdpTransport::connect(Face &face)
+void UdpTransport::connect(Node &node)
 {
   ndn_Error error;
-  if ((error = ndn_UdpTransport_connect(&transport_, (char *)face.getHost(), face.getPort())))
+  if ((error = ndn_UdpTransport_connect(&transport_, (char *)node.getHost(), node.getPort())))
     throw std::runtime_error(ndn_getErrorString(error)); 
 
   // TODO: This belongs in the socket listener.
   const unsigned int initialLength = 1000;
   // Automatically cast ndn_ to (struct ndn_ElementListener *)
   ndn_BinaryXmlElementReader_init
-    (&elementReader_, &face, (unsigned char *)malloc(initialLength), initialLength, ndn_realloc);
+    (&elementReader_, &node, (unsigned char *)malloc(initialLength), initialLength, ndn_realloc);
   
   // TODO: Properly indicate connected status.
-  face_ = &face;
+  node_ = &node;
 }
 
 void UdpTransport::send(const unsigned char *data, unsigned int dataLength)
diff --git a/ndn-cpp/transport/udp-transport.hpp b/ndn-cpp/transport/udp-transport.hpp
index 4ea6324..ceeda72 100644
--- a/ndn-cpp/transport/udp-transport.hpp
+++ b/ndn-cpp/transport/udp-transport.hpp
@@ -15,17 +15,17 @@
 class UdpTransport : public Transport {
 public:
   UdpTransport() 
+  : node_(0)
   {
     ndn_UdpTransport_init(&transport_);
-    face_ = 0;
     elementReader_.partialData.array = 0;
   }
   
   /**
-   * Connect to the host specified in face.
-   * @param face Not a shared_ptr because we assume that it will remain valid during the life of this Transport object.
+   * Connect to the host specified in node.
+   * @param node Not a shared_ptr because we assume that it will remain valid during the life of this Transport object.
    */
-  virtual void connect(Face &face);
+  virtual void connect(Node &node);
   
   /**
    * Set data to the host
@@ -35,7 +35,7 @@
   virtual void send(const unsigned char *data, unsigned int dataLength);
 
   /**
-   * Process any data to receive.  For each element received, call face.onReceivedElement.
+   * Process any data to receive.  For each element received, call node.onReceivedElement.
    * This is non-blocking and will return immediately if there is no data to receive.
    * You should normally not call this directly since it is called by Face.processEvents.
    * @throw This may throw an exception for reading data or in the callback for processing the data.  If you
@@ -52,7 +52,7 @@
   
 private:
   struct ndn_UdpTransport transport_;
-  Face *face_;
+  Node *node_;
   // TODO: This belongs in the socket listener.
   ndn_BinaryXmlElementReader elementReader_;
 };