diff --git a/tests/face/udp.cpp b/tests/face/udp.cpp
new file mode 100644
index 0000000..02c4319
--- /dev/null
+++ b/tests/face/udp.cpp
@@ -0,0 +1,869 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "face/udp-factory.hpp"
+#include "core/scheduler.hpp"
+#include "core/face-uri.hpp"
+#include "tests/test-common.hpp"
+
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <boost/asio.hpp>
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(FaceUdp, BaseFixture)
+
+class FactoryErrorCheck : protected BaseFixture
+{
+public:
+  bool isTheSameMulticastEndpoint(const UdpFactory::Error& e) {
+    return strcmp(e.what(),
+                  "Cannot create the requested UDP unicast channel, local "
+                  "endpoint is already allocated for a UDP multicast face") == 0;
+  }
+  
+  bool isNotMulticastAddress(const UdpFactory::Error& e) {
+    return strcmp(e.what(),
+                  "Cannot create the requested UDP multicast face, "
+                  "the multicast group given as input is not a multicast address") == 0;
+  }
+  
+  bool isTheSameUnicastEndpoint(const UdpFactory::Error& e) {
+    return strcmp(e.what(),
+                  "Cannot create the requested UDP multicast face, local "
+                  "endpoint is already allocated for a UDP unicast channel") == 0;
+  }
+  
+  bool isLocalEndpointOnDifferentGroup(const UdpFactory::Error& e) {
+    return strcmp(e.what(),
+                  "Cannot create the requested UDP multicast face, local "
+                  "endpoint is already allocated for a UDP multicast face "
+                  "on a different multicast group") == 0;
+  }
+};
+  
+BOOST_FIXTURE_TEST_CASE(ChannelMapUdp, FactoryErrorCheck)
+{
+  using boost::asio::ip::udp;
+ 
+  UdpFactory factory = UdpFactory();
+  
+  //to instantiate multicast face on a specific ip address, change interfaceIp
+  std::string interfaceIp = "0.0.0.0";
+  
+  shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
+  shared_ptr<UdpChannel> channel1a = factory.createChannel("127.0.0.1", "20070");
+  BOOST_CHECK_EQUAL(channel1, channel1a);
+  
+  shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
+  BOOST_CHECK_NE(channel1, channel2);
+
+  shared_ptr<UdpChannel> channel3 = factory.createChannel(interfaceIp, "20070");
+    
+  //same endpoint of a unicast channel
+  BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp,
+                                                    "224.0.0.1",
+                                                    "20070"),
+                        UdpFactory::Error,
+                        isTheSameUnicastEndpoint);
+    
+    
+  shared_ptr<MulticastUdpFace> multicastFace1 = factory.createMulticastFace(interfaceIp,
+                                                                            "224.0.0.1",
+                                                                            "20072");
+  shared_ptr<MulticastUdpFace> multicastFace1a = factory.createMulticastFace(interfaceIp,
+                                                                            "224.0.0.1",
+                                                                            "20072");
+  BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
+    
+    
+  //same endpoint of a multicast face
+  BOOST_CHECK_EXCEPTION(factory.createChannel(interfaceIp, "20072"),
+                        UdpFactory::Error,
+                        isTheSameMulticastEndpoint);
+    
+  //same multicast endpoint, different group
+  BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp,
+                                                    "224.0.0.42",
+                                                    "20072"),
+                        UdpFactory::Error,
+                        isLocalEndpointOnDifferentGroup);
+
+  BOOST_CHECK_EXCEPTION(factory.createMulticastFace(interfaceIp,
+                                                    "192.168.10.15",
+                                                    "20025"),
+                        UdpFactory::Error,
+                        isNotMulticastAddress);
+
+  
+  
+//  //Test commented because it required to be run in a machine that can resolve ipv6 query
+//  shared_ptr<UdpChannel> channel1v6 = factory.createChannel(//"::1",
+//                                                     "fe80::5e96:9dff:fe7d:9c8d%en1",
+//                                                     //"fe80::aa54:b2ff:fe08:27b8%wlan0",
+//                                                     "20070");
+//
+//  //the creation of multicastFace2 works properly. It has been disable because it needs an IP address of
+//  //an available network interface (different from the first one used)
+//  shared_ptr<MulticastUdpFace> multicastFace2 = factory.createMulticastFace("192.168.1.17",
+//                                                                            "224.0.0.1",
+//                                                                            "20073");
+//  BOOST_CHECK_NE(multicastFace1, multicastFace2);
+//
+//
+//  //ipv6 - work in progress
+//  shared_ptr<MulticastUdpFace> multicastFace3 = factory.createMulticastFace("fe80::5e96:9dff:fe7d:9c8d%en1",
+//                                                                            "FF01:0:0:0:0:0:0:2",
+//                                                                            "20073");
+//  
+//  shared_ptr<MulticastUdpFace> multicastFace4 = factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
+//                                                                            "FF01:0:0:0:0:0:0:2",
+//                                                                            "20073");
+//  
+//  BOOST_CHECK_EQUAL(multicastFace3, multicastFace4);
+//
+//  shared_ptr<MulticastUdpFace> multicastFace5 = factory.createMulticastFace("::1",
+//                                                                            "FF01:0:0:0:0:0:0:2",
+//                                                                            "20073");
+//  
+//  BOOST_CHECK_NE(multicastFace3, multicastFace5);
+//
+//  //same local ipv6 endpoint for a different multicast group
+//  BOOST_CHECK_THROW(factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
+//                                                "FE01:0:0:0:0:0:0:2",
+//                                                "20073"),
+//                    UdpFactory::Error);
+//  
+//  //same local ipv6 (expect for th port number) endpoint for a different multicast group
+//  BOOST_CHECK_THROW(factory.createMulticastFace("fe80::aa54:b2ff:fe08:27b8%wlan0",
+//                                                "FE01:0:0:0:0:0:0:2",
+//                                                "20075"),
+//                    UdpFactory::Error);
+//
+//  BOOST_CHECK_THROW(factory.createMulticastFace("fa80::20a:9dff:fef6:12ff",
+//                                                "FE12:0:0:0:0:0:0:2",
+//                                                "20075"),
+//                    UdpFactory::Error);
+//
+//  //not a multicast ipv6
+//  BOOST_CHECK_THROW(factory.createMulticastFace("fa80::20a:9dff:fef6:12ff",
+//                                                "A112:0:0:0:0:0:0:2",
+//                                                "20075"),
+//                    UdpFactory::Error);
+
+
+
+}
+
+class EndToEndFixture : protected BaseFixture
+{
+public:
+  void
+  channel1_onFaceCreated(const shared_ptr<UdpFace>& newFace)
+  {
+    BOOST_CHECK(!static_cast<bool>(m_face1));
+    m_face1 = newFace;
+    m_face1->onReceiveInterest +=
+      bind(&EndToEndFixture::face1_onReceiveInterest, this, _1);
+    m_face1->onReceiveData +=
+      bind(&EndToEndFixture::face1_onReceiveData, this, _1);
+    m_face1->onFail += 
+      bind(&EndToEndFixture::face1_onFail, this);
+    BOOST_CHECK_MESSAGE(true, "channel 1 face created");
+
+    m_faces.push_back(m_face1);
+
+    this->afterIo();
+  }
+
+  void
+  channel1_onConnectFailed(const std::string& reason)
+  {
+    BOOST_CHECK_MESSAGE(false, reason);
+
+    this->afterIo();
+  }
+  
+  void
+  face1_onReceiveInterest(const Interest& interest)
+  {
+    m_face1_receivedInterests.push_back(interest);
+
+    this->afterIo();
+  }
+  
+  void
+  face1_onReceiveData(const Data& data)
+  {
+    m_face1_receivedDatas.push_back(data);
+
+    this->afterIo();
+  }
+
+  void
+  face1_onFail()
+  {
+    m_face1.reset();
+    this->afterIo();
+  }
+
+  void
+  channel2_onFaceCreated(const shared_ptr<Face>& newFace)
+  {
+    BOOST_CHECK(!static_cast<bool>(m_face2));
+    m_face2 = newFace;
+    m_face2->onReceiveInterest +=
+      bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
+    m_face2->onReceiveData +=
+      bind(&EndToEndFixture::face2_onReceiveData, this, _1);
+    m_face2->onFail += 
+      bind(&EndToEndFixture::face2_onFail, this);
+
+    m_faces.push_back(m_face2);
+
+    BOOST_CHECK_MESSAGE(true, "channel 2 face created");
+    this->afterIo();
+  }
+  
+  void
+  channel2_onConnectFailed(const std::string& reason)
+  {
+    BOOST_CHECK_MESSAGE(false, reason);
+
+    this->afterIo();
+  }
+  
+  void
+  face2_onReceiveInterest(const Interest& interest)
+  {
+    m_face2_receivedInterests.push_back(interest);
+
+    this->afterIo();
+  }
+  
+  void
+  face2_onReceiveData(const Data& data)
+  {
+    m_face2_receivedDatas.push_back(data);
+
+    this->afterIo();
+  }
+
+  void
+  face2_onFail()
+  {
+    m_face2.reset();
+    this->afterIo();
+  }
+
+  void
+  channel3_onFaceCreated(const shared_ptr<Face>& newFace)
+  {
+    BOOST_CHECK(!static_cast<bool>(m_face1));
+    m_face3 = newFace;
+    m_faces.push_back(newFace);
+    
+    this->afterIo();
+  }
+
+  
+  void
+  channel_onFaceCreated(const shared_ptr<UdpFace>& newFace)
+  {
+    m_faces.push_back(newFace);
+    this->afterIo();
+  }
+
+  void
+  channel_onConnectFailed(const std::string& reason)
+  {
+    BOOST_CHECK_MESSAGE(false, reason);
+
+    this->afterIo();
+  }
+
+  void
+  channel_onConnectFailedOk(const std::string& reason)
+  {
+    //it's ok, it was supposed to fail
+    this->afterIo();
+  }
+
+  void
+  checkFaceList(size_t shouldBe)
+  {
+    BOOST_CHECK_EQUAL(m_faces.size(), shouldBe);
+  }
+  
+  void
+  abortTestCase(const std::string& message)
+  {
+    g_io.stop();
+    BOOST_FAIL(message);
+  }
+  
+private:
+  void
+  afterIo()
+  {
+    if (--m_ioRemaining <= 0) g_io.stop();
+  }
+
+public:
+  int m_ioRemaining;
+
+  shared_ptr<Face> m_face1;
+  std::vector<Interest> m_face1_receivedInterests;
+  std::vector<Data> m_face1_receivedDatas;
+  shared_ptr<Face> m_face2;
+  std::vector<Interest> m_face2_receivedInterests;
+  std::vector<Data> m_face2_receivedDatas;
+  
+  shared_ptr<Face> m_face3;
+
+
+  std::list< shared_ptr<Face> > m_faces;
+};
+
+
+BOOST_FIXTURE_TEST_CASE(EndToEnd, EndToEndFixture)
+{
+  UdpFactory factory = UdpFactory();
+  Scheduler scheduler(g_io); // to limit the amount of time the test may take
+
+  EventId abortEvent =
+    scheduler.scheduleEvent(time::seconds(1),
+                            bind(&EndToEndFixture::abortTestCase, this,
+                                 "UdpChannel error: cannot connect or cannot accept connection"));
+  
+  m_ioRemaining = 1;
+
+  shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
+  
+  
+  //channel2->connect("127.0.0.1", "20070",
+  //                  bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+  //                  bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+  
+  factory.createFace(FaceUri("udp4://127.0.0.1:20070"),
+                     bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+                     bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+  
+  
+  g_io.run();
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+
+  BOOST_REQUIRE(static_cast<bool>(m_face2));
+  
+  shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
+  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
+                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+  
+  
+  abortEvent =
+    scheduler.scheduleEvent(time::seconds(1),
+                            bind(&EndToEndFixture::abortTestCase, this,
+                                 "UdpChannel error: cannot send or receive Interest/Data packets"));
+
+  Interest interest1("ndn:/TpnzGvW9R");
+  Data     data1    ("ndn:/KfczhUqVix");
+  data1.setContent(0, 0);
+  Interest interest2("ndn:/QWiIMfj5sL");
+  Data     data2    ("ndn:/XNBV796f");
+  data2.setContent(0, 0);
+  Interest interest3("ndn:/QWiIhjgkj5sL");
+  Data     data3    ("ndn:/XNBV794f");
+  data3.setContent(0, 0);
+
+
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue,
+                                        reinterpret_cast<const uint8_t*>(0),
+                                        0));
+  
+  // set fake signature on data1 and data2
+  data1.setSignature(fakeSignature);
+  data2.setSignature(fakeSignature);
+  data3.setSignature(fakeSignature);
+
+  m_face2->sendInterest(interest2);
+  m_face2->sendData    (data2    );
+
+  m_ioRemaining = 3; //2 send + 1 listen return
+  g_io.run();
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+
+  BOOST_REQUIRE(static_cast<bool>(m_face1));
+  
+  m_face1->sendInterest(interest1);
+  m_face1->sendData    (data1    );
+  
+  abortEvent =
+  scheduler.scheduleEvent(time::seconds(1),
+                          bind(&EndToEndFixture::abortTestCase, this,
+                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+  m_ioRemaining = 2;
+  g_io.run();
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+
+
+  BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
+  BOOST_REQUIRE_EQUAL(m_face1_receivedDatas    .size(), 1);
+  BOOST_REQUIRE_EQUAL(m_face2_receivedInterests.size(), 1);
+  BOOST_REQUIRE_EQUAL(m_face2_receivedDatas    .size(), 1);
+  
+  BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getName(), interest2.getName());
+  BOOST_CHECK_EQUAL(m_face1_receivedDatas    [0].getName(), data2.getName());
+  BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getName(), interest1.getName());
+  BOOST_CHECK_EQUAL(m_face2_receivedDatas    [0].getName(), data1.getName());
+  
+  
+  
+  //checking if the connection accepting mechanism works properly.
+ 
+  m_face2->sendData    (data3    );
+  m_face2->sendInterest(interest3);
+
+  abortEvent =
+  scheduler.scheduleEvent(time::seconds(1),
+                          bind(&EndToEndFixture::abortTestCase, this,
+                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+  m_ioRemaining = 2;
+  g_io.run();
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+  
+  BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 2);
+  BOOST_REQUIRE_EQUAL(m_face1_receivedDatas    .size(), 2);
+  
+  BOOST_CHECK_EQUAL(m_face1_receivedInterests[1].getName(), interest3.getName());
+  BOOST_CHECK_EQUAL(m_face1_receivedDatas    [1].getName(), data3.getName());
+
+}
+
+BOOST_FIXTURE_TEST_CASE(MultipleAccepts, EndToEndFixture)
+{
+  Interest interest1("ndn:/TpnzGvW9R");
+  Interest interest2("ndn:/QWiIMfj5sL");
+  Interest interest3("ndn:/QWiIhjgkj5sL");
+
+  UdpFactory factory = UdpFactory();
+  Scheduler scheduler(g_io); // to limit the amount of time the test may take
+
+  EventId abortEvent =
+    scheduler.scheduleEvent(time::seconds(4),
+                            bind(&EndToEndFixture::abortTestCase, this,
+                                 "UdpChannel error: cannot connect or cannot accept connection"));
+  
+  shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
+  shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
+  
+  
+  
+  channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated,   this, _1),
+                   bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+  
+  channel2->connect("127.0.0.1", "20070",
+                    bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+                    bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+  
+  
+  m_ioRemaining = 1;
+  g_io.run();
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+
+  BOOST_CHECK_EQUAL(m_faces.size(), 1);
+  
+  shared_ptr<UdpChannel> channel3 = factory.createChannel("127.0.0.1", "20072");
+  channel3->connect("127.0.0.1", "20070",
+                    bind(&EndToEndFixture::channel3_onFaceCreated, this, _1),
+                    bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+  
+  shared_ptr<UdpChannel> channel4 = factory.createChannel("127.0.0.1", "20073");
+
+  BOOST_CHECK_NE(channel3, channel4);
+  
+  scheduler
+    .scheduleEvent
+    (time::seconds(0.5),
+     bind(&UdpChannel::connect, channel4,
+          "127.0.0.1", "20070",
+          // does not work without static_cast
+          static_cast<UdpChannel::FaceCreatedCallback>(bind(&EndToEndFixture::
+                                                            channel_onFaceCreated,
+                                                            this,
+                                                            _1)),
+          static_cast<UdpChannel::ConnectFailedCallback>(bind(&EndToEndFixture::
+                                                              channel_onConnectFailed,
+                                                              this,
+                                                              _1))));
+  
+  m_ioRemaining = 2; // 2 connects
+  abortEvent = 
+    scheduler.scheduleEvent(time::seconds(4),
+                            bind(&EndToEndFixture::abortTestCase, this,
+                                 "UdpChannel error: cannot connect or cannot accept multiple connections"));
+
+  scheduler.scheduleEvent(time::seconds(0.4),
+                          bind(&EndToEndFixture::checkFaceList, this, 2));
+  
+  g_io.run();
+  g_io.reset();
+  
+  BOOST_CHECK_EQUAL(m_faces.size(), 3);
+  
+  
+  m_face2->sendInterest(interest1);
+  abortEvent =
+  scheduler.scheduleEvent(time::seconds(1),
+                          bind(&EndToEndFixture::abortTestCase, this,
+                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+  m_ioRemaining = 1;
+  g_io.run();
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+  
+  BOOST_CHECK_EQUAL(m_faces.size(), 4);
+  
+  m_face3->sendInterest(interest2);
+  abortEvent =
+  scheduler.scheduleEvent(time::seconds(1),
+                          bind(&EndToEndFixture::abortTestCase, this,
+                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+  m_ioRemaining = 1;
+  g_io.run();
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+  
+  //channel1 should have created 2 faces, one when m_face2 sent an interest, one when m_face3 sent an interest
+  BOOST_CHECK_EQUAL(m_faces.size(), 5);
+  BOOST_CHECK_THROW(channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated,
+                                          this,
+                                          _1),
+                                    bind(&EndToEndFixture::channel_onConnectFailedOk,
+                                         this,
+                                         _1)),
+                    UdpChannel::Error);
+}
+  
+//Test commented because it required to be run in a machine that can resolve ipv6 query
+//BOOST_FIXTURE_TEST_CASE(EndToEndIpv6, EndToEndFixture)
+//{
+//  UdpFactory factory = UdpFactory();
+//  Scheduler scheduler(g_io); // to limit the amount of time the test may take
+//    
+//  EventId abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                              "UdpChannel error: cannot connect or cannot accept connection"));
+//    
+//  m_ioRemaining = 1;
+//    
+//  shared_ptr<UdpChannel> channel1 = factory.createChannel("::1", "20070");
+//  shared_ptr<UdpChannel> channel2 = factory.createChannel("::1", "20071");
+//    
+//  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
+//                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+//    
+//  channel2->connect("::1", "20070",
+//                    bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+//                    bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//    
+//  BOOST_REQUIRE(static_cast<bool>(m_face2));
+//    
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+//    
+//  Interest interest1("ndn:/TpnzGvW9R");
+//  Data     data1    ("ndn:/KfczhUqVix");
+//  data1.setContent(0, 0);
+//  Interest interest2("ndn:/QWiIMfj5sL");
+//  Data     data2    ("ndn:/XNBV796f");
+//  data2.setContent(0, 0);
+//  Interest interest3("ndn:/QWiIhjgkj5sL");
+//  Data     data3    ("ndn:/XNBV794f");
+//  data3.setContent(0, 0);
+//  
+//  ndn::SignatureSha256WithRsa fakeSignature;
+//  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+//    
+//  // set fake signature on data1 and data2
+//  data1.setSignature(fakeSignature);
+//  data2.setSignature(fakeSignature);
+//  data3.setSignature(fakeSignature);
+//    
+//  m_face2->sendInterest(interest2);
+//  m_face2->sendData    (data2    );
+//    
+//  m_ioRemaining = 3; //2 send + 1 listen return
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//    
+//  BOOST_REQUIRE(static_cast<bool>(m_face1));
+//    
+//  m_face1->sendInterest(interest1);
+//  m_face1->sendData    (data1    );
+//  
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+//  m_ioRemaining = 2;
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//  
+//  BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
+//  BOOST_REQUIRE_EQUAL(m_face1_receivedDatas    .size(), 1);
+//  BOOST_REQUIRE_EQUAL(m_face2_receivedInterests.size(), 1);
+//  BOOST_REQUIRE_EQUAL(m_face2_receivedDatas    .size(), 1);
+//    
+//  BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getName(), interest2.getName());
+//  BOOST_CHECK_EQUAL(m_face1_receivedDatas    [0].getName(), data2.getName());
+//  BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getName(), interest1.getName());
+//  BOOST_CHECK_EQUAL(m_face2_receivedDatas    [0].getName(), data1.getName());
+//    
+//  //checking if the connection accepting mechanism works properly.
+//    
+//  m_face2->sendData    (data3    );
+//  m_face2->sendInterest(interest3);
+//    
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+//  m_ioRemaining = 2;
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//    
+//  BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 2);
+//  BOOST_REQUIRE_EQUAL(m_face1_receivedDatas    .size(), 2);
+//    
+//  BOOST_CHECK_EQUAL(m_face1_receivedInterests[1].getName(), interest3.getName());
+//  BOOST_CHECK_EQUAL(m_face1_receivedDatas    [1].getName(), data3.getName());
+//    
+//}
+
+
+//Test commented because it required to be run in a machine that can resolve ipv6 query
+//BOOST_FIXTURE_TEST_CASE(MultipleAcceptsIpv6, EndToEndFixture)
+//{
+//  Interest interest1("ndn:/TpnzGvW9R");
+//  Interest interest2("ndn:/QWiIMfj5sL");
+//  Interest interest3("ndn:/QWiIhjgkj5sL");
+//    
+//  UdpFactory factory = UdpFactory();
+//  Scheduler scheduler(g_io); // to limit the amount of time the test may take
+//    
+//  EventId abortEvent =
+//  scheduler.scheduleEvent(time::seconds(4),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot connect or cannot accept connection"));
+//    
+//  shared_ptr<UdpChannel> channel1 = factory.createChannel("::1", "20070");
+//  shared_ptr<UdpChannel> channel2 = factory.createChannel("::1", "20071");
+//    
+//  channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated,   this, _1),
+//                   bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+//    
+//  channel2->connect("::1", "20070",
+//                    bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+//                    bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+//    
+//  m_ioRemaining = 1;
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//    
+//  BOOST_CHECK_EQUAL(m_faces.size(), 1);
+//    
+//  shared_ptr<UdpChannel> channel3 = factory.createChannel("::1", "20072");
+//  channel3->connect("::1", "20070",
+//                    bind(&EndToEndFixture::channel3_onFaceCreated, this, _1),
+//                    bind(&EndToEndFixture::channel_onConnectFailed, this, _1));
+//    
+//  shared_ptr<UdpChannel> channel4 = factory.createChannel("::1", "20073");
+//    
+//  BOOST_CHECK_NE(channel3, channel4);
+//    
+//  scheduler
+//  .scheduleEvent(time::seconds(0.5),
+//                 bind(&UdpChannel::connect, channel4,
+//                      "::1", "20070",
+//                      static_cast<UdpChannel::FaceCreatedCallback>(bind(&EndToEndFixture::
+//                                                                        channel_onFaceCreated, this, _1)),
+//                      static_cast<UdpChannel::ConnectFailedCallback>(bind(&EndToEndFixture::
+//                                                                          channel_onConnectFailed, this, _1))));
+//    
+//  m_ioRemaining = 2; // 2 connects
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(4),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot connect or cannot accept multiple connections"));
+//    
+//  scheduler.scheduleEvent(time::seconds(0.4),
+//                          bind(&EndToEndFixture::checkFaceList, this, 2));
+//    
+//  g_io.run();
+//  g_io.reset();
+//    
+//  BOOST_CHECK_EQUAL(m_faces.size(), 3);
+//    
+//    
+//  m_face2->sendInterest(interest1);
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+//  m_ioRemaining = 1;
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//    
+//  BOOST_CHECK_EQUAL(m_faces.size(), 4);
+//    
+//  m_face3->sendInterest(interest2);
+//  abortEvent =
+//  scheduler.scheduleEvent(time::seconds(1),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "UdpChannel error: cannot send or receive Interest/Data packets"));
+//  m_ioRemaining = 1;
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//    
+//  //channel1 should have created 2 faces, one when m_face2 sent an interest, one when m_face3 sent an interest
+//  BOOST_CHECK_EQUAL(m_faces.size(), 5);
+//  BOOST_CHECK_THROW(channel1->listen(bind(&EndToEndFixture::channel_onFaceCreated,
+//                                          this,
+//                                          _1),
+//                                      bind(&EndToEndFixture::channel_onConnectFailedOk,
+//                                          this,
+//                                          _1)),
+//                    UdpChannel::Error);
+//}
+
+
+BOOST_FIXTURE_TEST_CASE(FaceClosing, EndToEndFixture)
+{
+  UdpFactory factory = UdpFactory();
+  Scheduler scheduler(g_io); // to limit the amount of time the test may take
+
+  EventId abortEvent =
+    scheduler.scheduleEvent(time::seconds(4),
+                            bind(&EndToEndFixture::abortTestCase, this,
+                                 "UdpChannel error: cannot connect or cannot accept connection"));
+  
+  shared_ptr<UdpChannel> channel1 = factory.createChannel("127.0.0.1", "20070");
+  shared_ptr<UdpChannel> channel2 = factory.createChannel("127.0.0.1", "20071");
+  
+  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
+                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
+  
+  channel2->connect("127.0.0.1", "20070",
+                    bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
+                    bind(&EndToEndFixture::channel2_onConnectFailed, this, _1));
+  
+  m_ioRemaining = 1;
+  BOOST_REQUIRE_NO_THROW(g_io.run());
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+
+  BOOST_CHECK_EQUAL(channel2->size(), 1);
+
+  abortEvent =
+    scheduler.scheduleEvent(time::seconds(4),
+                            bind(&EndToEndFixture::abortTestCase, this,
+                                 "FaceClosing error: cannot properly close faces"));
+
+  BOOST_CHECK(static_cast<bool>(m_face2));
+
+  m_ioRemaining = 1;
+  // just double check that we are calling the virtual method
+  static_pointer_cast<Face>(m_face2)->close();
+  
+  BOOST_REQUIRE_NO_THROW(g_io.run());
+  g_io.reset();
+  scheduler.cancelEvent(abortEvent);
+
+  BOOST_CHECK(!static_cast<bool>(m_face2));
+  
+  BOOST_CHECK_EQUAL(channel2->size(), 0);
+}
+
+//BOOST_FIXTURE_TEST_CASE(MulticastFace, EndToEndFixture)
+//{
+//  //to instantiate multicast face on a specific ip address, change interfaceIp
+//  std::string interfaceIp = "0.0.0.0";
+//  
+//  UdpFactory factory = UdpFactory();
+//  Scheduler scheduler(g_io); // to limit the amount of time the test may take
+//  
+//  shared_ptr<MulticastUdpFace> multicastFace1 =
+//    factory.createMulticastFace(interfaceIp, "224.0.0.1", "20072");
+//  
+//  BOOST_REQUIRE(static_cast<bool>(multicastFace1));
+//  
+//  channel1_onFaceCreated(multicastFace1);
+//
+//  
+//  EventId abortEvent =
+//  scheduler.scheduleEvent(time::seconds(10),
+//                          bind(&EndToEndFixture::abortTestCase, this,
+//                               "MulticastFace error: cannot send or receive Interest/Data packets"));
+//  
+//  Interest interest1("ndn:/TpnzGvW9R");
+//  Data     data1    ("ndn:/KfczhUqVix");
+//  data1.setContent(0, 0);
+//  Interest interest2("ndn:/QWiIMfj5sL");
+//  Data     data2    ("ndn:/XNBV796f");
+//  data2.setContent(0, 0);
+//  Interest interest3("ndn:/QWiIhjgkj5sL");
+//  Data     data3    ("ndn:/XNBV794f");
+//  data3.setContent(0, 0);
+//  
+//  
+//  ndn::SignatureSha256WithRsa fakeSignature;
+//  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+//  
+//  // set fake signature on data1 and data2
+//  data1.setSignature(fakeSignature);
+//  data2.setSignature(fakeSignature);
+//  data3.setSignature(fakeSignature);
+//  
+//  multicastFace1->sendInterest(interest1);
+//  multicastFace1->sendData    (data1    );
+//  
+//  g_io.reset();
+//  m_ioRemaining = 2;
+//  g_io.run();
+//  g_io.reset();
+//  scheduler.cancelEvent(abortEvent);
+//  
+//  BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
+//  BOOST_REQUIRE_EQUAL(m_face1_receivedDatas    .size(), 1);
+//  
+//  BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getName(), interest1.getName());
+//  BOOST_CHECK_EQUAL(m_face1_receivedDatas    [0].getName(), data1.getName());
+//}
+
+  
+  
+BOOST_AUTO_TEST_SUITE_END()
+} // namespace tests
+} // namespace nfd
