diff --git a/AUTHORS.md b/AUTHORS.md
new file mode 100644
index 0000000..7970b30
--- /dev/null
+++ b/AUTHORS.md
@@ -0,0 +1,5 @@
+jndn-mock authors and contributors
+==================================
+
+* Andrew Brown        <andrew.brown@intel.com>
+* Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
diff --git a/src/main/java/com/intel/jndn/mock/FaceExtension.java b/src/main/java/com/intel/jndn/mock/FaceExtension.java
deleted file mode 100644
index b3b9e3b..0000000
--- a/src/main/java/com/intel/jndn/mock/FaceExtension.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * jndn-mock
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 3, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
- * more details.
- */
-package com.intel.jndn.mock;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-import net.named_data.jndn.*;
-import net.named_data.jndn.encoding.EncodingException;
-import net.named_data.jndn.encoding.WireFormat;
-import net.named_data.jndn.util.Blob;
-
-/**
- * Provides help for extending {@link Face}; this should be an interface but
- * until it is we need a way to know what is the minimal set of methods to
- * override.
- *
- * @author Andrew Brown <andrew.brown@intel.com>
- */
-public abstract class FaceExtension extends Face {
-
-	public long expressInterest(Interest interest, OnData onData, OnTimeout onTimeout,
-			WireFormat wireFormat) throws IOException {
-		return expressInterest(interest, onData, onTimeout, wireFormat);
-	}
-
-	public long expressInterest(Interest interest, OnData onData, OnTimeout onTimeout) throws IOException {
-		return expressInterest(interest, onData, onTimeout, WireFormat.getDefaultWireFormat());
-	}
-
-	public long expressInterest(Interest interest, OnData onData, WireFormat wireFormat) throws IOException {
-		return expressInterest(interest, onData, null, wireFormat);
-	}
-
-	public long expressInterest(Interest interest, OnData onData) throws IOException {
-		return expressInterest(interest, onData, null, WireFormat.getDefaultWireFormat());
-	}
-
-	public long expressInterest(Name name, Interest interestTemplate, OnData onData, OnTimeout onTimeout,
-			WireFormat wireFormat) throws IOException {
-		Interest interest = new Interest(name);
-		if (interestTemplate != null) {
-			interest.setMinSuffixComponents(interestTemplate.getMinSuffixComponents());
-			interest.setMaxSuffixComponents(interestTemplate.getMaxSuffixComponents());
-			interest.setKeyLocator(interestTemplate.getKeyLocator());
-			interest.setExclude(interestTemplate.getExclude());
-			interest.setChildSelector(interestTemplate.getChildSelector());
-			interest.setMustBeFresh(interestTemplate.getMustBeFresh());
-			interest.setInterestLifetimeMilliseconds(
-					interestTemplate.getInterestLifetimeMilliseconds());
-		} else {
-			interest.setInterestLifetimeMilliseconds(4000.0);
-		}
-
-		return expressInterest(interest, onData, onTimeout, wireFormat);
-	}
-
-	public abstract long registerPrefix(Name prefix,
-																			OnInterestCallback onInterest, OnRegisterFailed onRegisterFailed,
-																			OnRegisterSuccess onRegisterSuccess, ForwardingFlags flags,
-																			WireFormat wireFormat) throws IOException, net.named_data.jndn.security.SecurityException;
-
-	public abstract void removeRegisteredPrefix(long registeredPrefixId);
-
-	public abstract long setInterestFilter(InterestFilter filter, OnInterestCallback onInterest);
-
-	public long setInterestFilter(Name prefix, OnInterestCallback onInterest) {
-		return setInterestFilter(new InterestFilter(prefix), onInterest);
-	}
-
-	public abstract void unsetInterestFilter(long interestFilterId);
-
-	public abstract void putData(Data data, WireFormat wireFormat) throws IOException;
-
-	public void putData(Data data) throws IOException {
-		putData(data, WireFormat.getDefaultWireFormat());
-	}
-
-	public abstract void send(ByteBuffer encoding) throws IOException;
-
-	public void send(Blob encoding) throws IOException {
-		send(encoding.buf());
-	}
-
-	public abstract void processEvents() throws IOException, EncodingException;
-
-	public abstract boolean isLocal() throws IOException;
-
-	public abstract void shutdown();
-}
diff --git a/src/main/java/com/intel/jndn/mock/MockFace.java b/src/main/java/com/intel/jndn/mock/MockFace.java
index c36b16e..8b78329 100644
--- a/src/main/java/com/intel/jndn/mock/MockFace.java
+++ b/src/main/java/com/intel/jndn/mock/MockFace.java
@@ -1,6 +1,6 @@
 /*
  * jndn-mock
- * Copyright (c) 2015, Intel Corporation.
+ * Copyright (c) 2013-2015 Regents of the University of California.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU Lesser General Public License,
@@ -13,286 +13,325 @@
  */
 package com.intel.jndn.mock;
 
+import net.named_data.jndn.*;
+import net.named_data.jndn.encoding.ElementListener;
+import net.named_data.jndn.encoding.ElementReader;
+import net.named_data.jndn.encoding.EncodingException;
+import net.named_data.jndn.encoding.TlvWireFormat;
+import net.named_data.jndn.encoding.tlv.Tlv;
+import net.named_data.jndn.encoding.tlv.TlvDecoder;
+import net.named_data.jndn.encoding.tlv.TlvEncoder;
+import net.named_data.jndn.security.KeyChain;
+import net.named_data.jndn.security.SecurityException;
+import net.named_data.jndn.transport.Transport;
+import net.named_data.jndn.util.Blob;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.Map.Entry;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.logging.Logger;
 
-import net.named_data.jndn.*;
-import net.named_data.jndn.encoding.EncodingException;
-import net.named_data.jndn.encoding.WireFormat;
-import net.named_data.jndn.security.SecurityException;
-
-/**
- * <p>
- * Use the MockTransport to mock sending data over the network. Allows for
- * testing NDN applications while simulating network IO. TODO implement longest
- * prefix match here for comprehensive testing.
- * </p>
- * <p>
- * Usage
- * </p>
- * <pre><code>
- * Face mockFace = new MockFace();
- * mockFace.registerPrefix(...); // as usual
- * mockFace.expressInterest(...); // as usual
- *
- * // also, simply inject a response that will be returned for an expressed interest
- * mockFace.addResponse(interestName, data);
- * </pre></code>
- *
- * @author Andrew Brown <andrew.brown@intel.com>
+/** A client-side face for unit testing
  */
-public class MockFace extends FaceExtension {
+public class MockFace extends Face
+{
+  public interface SignalOnSendInterest {
+    void emit(Interest interest) throws EncodingException, SecurityException;
+  }
+
+  public interface SignalOnSendData {
+    void emit(Data data);
+  }
+
+  /**
+   * Options for MockFace
+   */
+  public static class Options
+  {
+    /** If true, packets sent out of MockFace will be appended to a container
+     */
+    boolean enablePacketLogging = false;
+
+    /**
+     * If true, prefix registration command will be automatically replied with a successful response
+     */
+    boolean enableRegistrationReply = false;
+  }
+
+  final public static Options DEFAULT_OPTIONS = new Options(){{ enablePacketLogging=true; enableRegistrationReply=true; }};
+
+  /**
+   * Create MockFace that logs packets in sentInterests and sentData and emulates NFD prefix registration
+   */
+  public MockFace() throws SecurityException {
+    this(DEFAULT_OPTIONS);
+  }
+
+  /**
+   * Create MockFace with the specified options
+   * <p>
+   * To create Face that does not log packets:
+   * <pre>
+   *   new MockFace(new Options());
+   *   // use onSendInterest.add(handler) and onSendData.add(handler)
+   *   // to add custom logic when Interest or Data packet are sent
+   *   // from the upper level (to transport)
+   * </pre>
+   *
+   * To create Face that just logs packets in sentInterests and sentData:
+   * <pre>
+   *   new MockFace(new Options(){{ enablePacketLogging=true; }});
+   * </pre>
+   */
+  public MockFace(Options options) throws SecurityException {
+    super(new MockFaceTransport(), null);
+    m_transport = (MockFaceTransport)node_.getTransport();
+    m_keychain = MockKeyChain.configure(new Name("/mock/key"));
+    setCommandSigningInfo(m_keychain, m_keychain.getDefaultCertificateName());
+
+    m_transport.onSendBlock = new MockFaceTransport.OnSendBlockSignal() {
+      @Override
+      public void emit(ByteBuffer buffer) throws EncodingException, SecurityException {
+        // @todo Implement NDNLP processing
+
+        if (buffer.get(0) == Tlv.Interest || buffer.get(0) == Tlv.Data) {
+          TlvDecoder decoder = new TlvDecoder(buffer);
+          if (decoder.peekType(Tlv.Interest, buffer.remaining())) {
+            Interest interest = new Interest();
+            interest.wireDecode(buffer, TlvWireFormat.get());
+
+            for (SignalOnSendInterest signal : onSendInterest) {
+              signal.emit(interest);
+            }
+          } else if (decoder.peekType(Tlv.Data, buffer.remaining())) {
+            Data data = new Data();
+            data.wireDecode(buffer, TlvWireFormat.get());
+
+            for (SignalOnSendData signal : onSendData) {
+              signal.emit(data);
+            }
+          }
+        }
+        else {
+          logger.info("Received an unknown packet");
+        }
+      }
+    };
+
+    if (options.enablePacketLogging) {
+      onSendInterest.add(new SignalOnSendInterest() {
+        @Override
+        public void emit(Interest interest) {
+          sentInterests.add(interest);
+        }
+      });
+
+      onSendData.add(new SignalOnSendData() {
+        @Override
+        public void emit(Data data) {
+          sentData.add(data);
+        }
+      });
+    }
+
+    if (options.enableRegistrationReply) {
+      onSendInterest.add(new SignalOnSendInterest() {
+        @Override
+        public void emit(Interest interest) throws EncodingException, SecurityException {
+          final Name localhostRegistration = new Name("/localhost/nfd/rib");
+          if (!interest.getName().getPrefix(3).equals(localhostRegistration)) {
+            return;
+          }
+
+          ControlParameters params = new ControlParameters();
+          params.wireDecode(interest.getName().get(-5).getValue());
+          params.setFaceId(1);
+          params.setOrigin(0);
+
+          if (interest.getName().get(3).toString().equals("register")) {
+            params.setCost(0);
+          }
+
+          // TODO: replace with jNDN ControlResponse encoding when available
+          //       http://redmine.named-data.net/issues/3455
+          TlvEncoder encoder = new TlvEncoder(256);
+          int saveLength = encoder.getLength();
+          encoder.writeBuffer(params.wireEncode().buf());
+          encoder.writeBlobTlv(Tlv.NfdCommand_StatusText, new Blob("OK").buf());
+          encoder.writeNonNegativeIntegerTlv(Tlv.NfdCommand_StatusCode, 200);
+          encoder.writeTypeAndLength(Tlv.NfdCommand_ControlResponse, encoder.getLength() - saveLength);
+
+          Data data = new Data();
+          data.setName(interest.getName());
+          data.setContent(new Blob(encoder.getOutput(), false));
+          m_keychain.sign(data);
+
+          receive(data);
+        }
+      });
+    }
+  }
+
+  /**
+   * Mock reception of the Interest packet on the Face (from transport)
+   */
+  public void receive(Interest interest) throws EncodingException {
+    m_transport.receive(interest.wireEncode().buf());
+  }
+
+  /**
+   * Mock reception of the Data packet on the Face (from transport)
+   */
+  public void receive(Data data) throws EncodingException {
+    m_transport.receive(data.wireEncode().buf());
+  }
+
+  public Transport getTransport() {
+    return m_transport;
+  }
+
+  //////////////////////////////////////////////////////////////////////////////
+  //////////////////////////////////////////////////////////////////////////////
+  //////////////////////////////////////////////////////////////////////////////
+
+  /**
+   * Internal transport for MockFace
+   */
+  private static class MockFaceTransport extends Transport {
+    public interface OnSendBlockSignal {
+      void emit(ByteBuffer buffer) throws EncodingException, SecurityException;
+    }
+
+    public void
+    receive(ByteBuffer block) throws EncodingException {
+      synchronized (m_recvBuffer) {
+        m_recvBuffer.add(block.duplicate());
+      }
+    }
+
+    // from Transport
+
+    @Override
+    public boolean isLocal(ConnectionInfo connectionInfo) {
+      return true;
+    }
+
+    @Override
+    public boolean isAsync() {
+      return false;
+    }
+
+    @Override
+    public void connect(Transport.ConnectionInfo connectionInfo,
+                        ElementListener elementListener, Runnable onConnected) {
+      logger.fine("Connecting...");
+      connected = true;
+      elementReader = new ElementReader(elementListener);
+      if (onConnected != null) {
+        onConnected.run();
+      }
+    }
+
+    @Override
+    public void send(ByteBuffer data) throws IOException {
+      logger.fine("Sending " + (data.capacity() - data.position()) + " bytes");
+
+      try {
+        onSendBlock.emit(data);
+      } catch (EncodingException e) {
+        logger.info("TLV decoding error: " + e.toString());
+      } catch (SecurityException e) {
+        logger.info("Signing error: " + e.toString());
+      }
+    }
+
+    @Override
+    public void processEvents() throws IOException, EncodingException {
+      if (!getIsConnected()) {
+        logger.warning("Not connnected...");
+      }
+
+      while (true) {
+        ByteBuffer block = null;
+        synchronized (m_recvBuffer) {
+          if (!m_recvBuffer.isEmpty()) {
+            block = m_recvBuffer.remove(0);
+          }
+        }
+        if (block == null) {
+          break;
+        }
+        elementReader.onReceivedData(block);
+      }
+    }
+
+    @Override
+    public boolean getIsConnected() {
+      return connected;
+    }
+
+    @Override
+    public void close() throws IOException {
+      logger.fine("Closing...");
+      connected = false;
+    }
+
+    //////////////////////////////////////////////////////////////////////////////
+
+    public OnSendBlockSignal onSendBlock;
+
+    //////////////////////////////////////////////////////////////////////////////
+
+    private static final Logger logger = Logger.getLogger(MockFaceTransport.class.getName());
+
+    private boolean connected;
+    private ElementReader elementReader;
+    private final List<ByteBuffer> m_recvBuffer = new LinkedList<ByteBuffer>();
+  }
+
+  //////////////////////////////////////////////////////////////////////////////
+  //////////////////////////////////////////////////////////////////////////////
+  //////////////////////////////////////////////////////////////////////////////
+
+  /**
+   * Interests sent out of this MockFace
+   * <p>
+   * Sent Interests are appended to this container if options.enablePacketLogger is true.
+   * User of this class is responsible for cleaning up the container, if necessary.
+   * After .expressInterest, .processEvents must be called before the Interest would show up here.
+   */
+  public List<Interest> sentInterests = new ArrayList<Interest>();
+
+  /**
+   * Data sent out of this MockFace
+   * <p>
+   * Sent Data are appended to this container if options.enablePacketLogger is true.
+   * User of this class is responsible for cleaning up the container, if necessary.
+   * After .put, .processEvents must be called before the Data would show up here.
+   */
+  public List<Data> sentData = new ArrayList<Data>();
+
+  /**
+   * Emits whenever an Interest is sent
+   * <p>
+   * After .expressInterest, .processEvents must be called before this signal would be emitted.
+   */
+  public List<SignalOnSendInterest> onSendInterest = new ArrayList<SignalOnSendInterest>();
+
+  /**
+   * Emits whenever a Data packet is sent
+   * <p>
+   * After .putData, .processEvents must be called before this signal would be emitted.
+   */
+  public List<SignalOnSendData> onSendData = new ArrayList<SignalOnSendData>();
+
+  //////////////////////////////////////////////////////////////////////////////
+  //////////////////////////////////////////////////////////////////////////////
+  //////////////////////////////////////////////////////////////////////////////
 
   private static final Logger logger = Logger.getLogger(MockFace.class.getName());
-  private final Node node_;
-  HashMap<String, Data> responseMap = new HashMap<String, Data>();
-  HashMap<Long, MockOnInterestHandler> handlerMap = new HashMap<Long, MockOnInterestHandler>();
-  long lastPendingInterestId = 0;
-  long lastInterestFilterId = 0;
-  long lastRegisteredPrefixId = 0;
-
-  /**
-   * Create a new Face to mock communication over the network; all packets are
-   * maintained in memory
-   */
-  public MockFace() {
-    node_ = new Node(new MockTransport(), null);
-  }
-
-  /**
-   * @return a reference to the current MockTransport
-   */
-  public MockTransport getTransport() {
-    return (MockTransport) node_.getTransport();
-  }
-
-  /**
-   * Add a response Data packet to send immediately when an Interest with a
-   * matching name is received; will continue to respond with the same packet
-   * over multiple requests. This will preempt any registered OnInterest
-   * handlers.
-   *
-   * @param name
-   * @param data
-   */
-  public void addResponse(Name name, Data data) {
-    logger.fine("Added response for: " + name.toUri());
-    responseMap.put(name.toUri(), data);
-  }
-
-  /**
-   * Stop sending a response for the given name.
-   *
-   * @param name
-   */
-  public void removeResponse(Name name) {
-    logger.fine("Removed response for: " + name.toUri());
-    responseMap.remove(name);
-  }
-
-  /**
-   * Handle incoming Interest packets; when an Interest is expressed through
-   * expressInterest(), this will run to determine if: 1) any responses have
-   * been registered or 2) if any OnInterest handlers have been registered. If
-   * one of these two succeeds, this method then re-directs the Interest from
-   * traveling down the network stack and returns data.
-   *
-   * @param interest
-   */
-  protected void handleIncomingRequests(Interest interest) {
-    String interestName = interest.getName().toUri();
-    long registeredPrefixId = findRegisteredHandler(interest);
-    // check if response registered
-    if (responseMap.containsKey(interestName)) {
-      logger.fine("Found response for: " + interestName);
-      Data data = responseMap.get(interestName);
-      ((MockTransport) node_.getTransport()).respondWith(data);
-    } // check if handler registered
-    else if (registeredPrefixId != -1) {
-      logger.fine("Found handler for: " + interestName);
-      MockOnInterestHandler handler = handlerMap.get(findRegisteredHandler(interest));
-      handler.signal(interest, registeredPrefixId);
-    } // log failure
-    else {
-      logger.warning("No response found for interest (aborting): " + interestName);
-    }
-  }
-
-  /**
-   * Find a handler that matches the incoming interest; currently, the only
-   * flags supported are the ChildInherit flags.
-   *
-   * @param interest
-   * @return
-   */
-  protected long findRegisteredHandler(Interest interest) {
-    for (Entry<Long, MockOnInterestHandler> entry : handlerMap.entrySet()) {
-      MockOnInterestHandler handler = entry.getValue();
-      if (handler.flags.getChildInherit() && handler.prefix.match(interest.getName())) {
-        return entry.getKey();
-      }
-      if (handler.prefix.equals(interest.getName())) {
-        return entry.getKey();
-      }
-    }
-    return -1;
-  }
-
-  /**
-   * Helper class for holding references to OnInterest handlers
-   */
-  class MockOnInterestHandler {
-
-    Name prefix;
-    OnInterest onInterest;
-    OnInterestCallback onInterestCallback;
-    ForwardingFlags flags;
-
-    public MockOnInterestHandler(Name prefix, OnInterest onInterest, ForwardingFlags flags) {
-      this.prefix = prefix;
-      this.onInterest = onInterest;
-      this.flags = flags;
-    }
-    
-    public MockOnInterestHandler(Name prefix, OnInterestCallback onInterestCallback, ForwardingFlags flags) {
-      this.prefix = prefix;
-      this.onInterestCallback = onInterestCallback;
-      this.flags = flags;
-    }
-    
-    public void signal(Interest interest, long registeredPrefixId){
-      if(onInterest != null){
-        onInterest.onInterest(prefix, interest, node_.getTransport(), registeredPrefixId);
-      }
-      if(onInterestCallback != null){
-        onInterestCallback.onInterest(prefix, interest, MockFace.this, registeredPrefixId, null);
-      }
-    }
-  }
-
-  /**
-   * Send the Interest through the transport, read the entire response and call
-   * onData(interest, data).
-   *
-   * @param interest The Interest to send. This copies the Interest.
-   * @param onData When a matching data packet is received, this calls
-   * onData.onData(interest, data) where interest is the interest given to
-   * expressInterest and data is the received Data object. NOTE: You must not
-   * change the interest object - if you need to change it then make a copy.
-   * @param onTimeout If the interest times out according to the interest
-   * lifetime, this calls onTimeout.onTimeout(interest) where interest is the
-   * interest given to expressInterest. If onTimeout is null, this does not use
-   * it.
-   * @param wireFormat A WireFormat object used to encode the message.
-   * @return The pending interest ID which can be used with
-   * removePendingInterest.
-   * @throws IOException For I/O error in sending the interest.
-   */
-  @Override
-  public long expressInterest(Interest interest, OnData onData, OnTimeout onTimeout,
-          WireFormat wireFormat) throws IOException {
-    long id = lastPendingInterestId++;
-    node_.expressInterest(id, interest, onData, onTimeout, wireFormat, this);
-    handleIncomingRequests(interest);
-    return id;
-  }
-
-  /**
-   * Register prefix with the connected NDN hub and call onInterest when a
-   * matching interest is received. If you have not called
-   * setCommandSigningInfo, this assumes you are connecting to NDNx. If you have
-   * called setCommandSigningInfo, this first sends an NFD registration request,
-   * and if that times out then this sends an NDNx registration request. If you
-   * need to register a prefix with NFD, you must first call
-   * setCommandSigningInfo.
-   *
-   * @param prefix A Name for the prefix to register. This copies the Name.
-   * @param onInterest When an interest is received which matches the name
-   * prefix, this calls onInterest.onInterest(prefix, interest, transport,
-   * registeredPrefixId). NOTE: You must not change the prefix object - if you
-   * need to change it then make a copy.
-   * @param onRegisterFailed If register prefix fails for any reason, this calls
-   * onRegisterFailed.onRegisterFailed(prefix).
-   * @param flags The flags for finer control of which interests are forwarded
-   * to the application.
-   * @param wireFormat A WireFormat object used to encode the message.
-   * @return The lastRegisteredPrefixId prefix ID which can be used with
- removeRegisteredPrefix.
-   * @throws IOException For I/O error in sending the registration request.
-   * @throws SecurityException If signing a command interest for NFD and cannot
-   * find the private key for the certificateName.
-   */
-  @Override
-  public long registerPrefix(Name prefix,
-                             OnInterestCallback onInterest, OnRegisterFailed onRegisterFailed,
-                             OnRegisterSuccess onRegisterSuccess, ForwardingFlags flags,
-                             WireFormat wireFormat) throws IOException, net.named_data.jndn.security.SecurityException {
-    // since we don't send an Interest, ensure the transport is connected
-    if (!getTransport().getIsConnected()) {
-      getTransport().connect(node_.getConnectionInfo(), node_, null);
-    }
-
-    lastRegisteredPrefixId++;
-    handlerMap.put(lastRegisteredPrefixId, new MockOnInterestHandler(prefix, onInterest, flags));
-    return lastRegisteredPrefixId;
-  }
-
-  /**
-   * Process any packets to receive and call callbacks such as onData,
-   * onInterest or onTimeout. This returns immediately if there is no data to
-   * receive. This blocks while calling the callbacks. 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. Since processEvents modifies the pending
-   * interest table, your application should make sure that it calls
-   * processEvents in the same thread as expressInterest (which also modifies
-   * the pending interest table). 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.
-   */
-  @Override
-  public void processEvents() throws IOException, EncodingException {
-    // Just call Node's processEvents.
-    node_.processEvents();
-  }
-
-  @Override
-  public void removeRegisteredPrefix(long registeredPrefixId) {
-    handlerMap.remove(registeredPrefixId);
-  }
-
-  @Override
-  public long setInterestFilter(InterestFilter filter, OnInterestCallback onInterest) {
-    long id = lastInterestFilterId++;
-    node_.setInterestFilter(id, filter, onInterest, this);
-    return id;
-  }
-
-  @Override
-  public void unsetInterestFilter(long interestFilterId) {
-    node_.unsetInterestFilter(interestFilterId);
-  }
-
-  @Override
-  public void putData(Data data, WireFormat wireFormat) throws IOException {
-    node_.putData(data, wireFormat);
-  }
-
-  @Override
-  public void send(ByteBuffer encoding) throws IOException {
-    node_.send(encoding);
-  }
-
-  @Override
-  public boolean isLocal() throws IOException {
-    return true;
-  }
-
-  @Override
-  public void shutdown() {
-    node_.shutdown();
-  }
-
+  private MockFaceTransport m_transport;
+  private KeyChain m_keychain;
 }
diff --git a/src/main/java/com/intel/jndn/mock/MockKeyChain.java b/src/main/java/com/intel/jndn/mock/MockKeyChain.java
index 2ac92cf..87b82ec 100644
--- a/src/main/java/com/intel/jndn/mock/MockKeyChain.java
+++ b/src/main/java/com/intel/jndn/mock/MockKeyChain.java
@@ -37,7 +37,6 @@
    * @throws net.named_data.jndn.security.SecurityException
    */
   public static KeyChain configure(Name name) throws net.named_data.jndn.security.SecurityException {
-    // access key chain in ~/.ndn; create if necessary 
     PrivateKeyStorage keyStorage = new MemoryPrivateKeyStorage();
     IdentityStorage identityStorage = new MemoryIdentityStorage();
     KeyChain keyChain = new KeyChain(new IdentityManager(identityStorage, keyStorage),
@@ -45,8 +44,7 @@
 
     // create keys, certs if necessary
     if (!identityStorage.doesIdentityExist(name)) {
-      Name keyName = keyChain.createIdentity(name);
-      keyChain.setDefaultKeyForIdentity(keyName, name);
+      keyChain.createIdentityAndCertificate(name);
     }
 
     // set default identity
diff --git a/src/main/java/com/intel/jndn/mock/MockTransport.java b/src/main/java/com/intel/jndn/mock/MockTransport.java
deleted file mode 100644
index c48fa07..0000000
--- a/src/main/java/com/intel/jndn/mock/MockTransport.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * jndn-mock
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 3, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
- * more details.
- */
-package com.intel.jndn.mock;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.logging.Logger;
-import net.named_data.jndn.Data;
-import net.named_data.jndn.Interest;
-import net.named_data.jndn.encoding.ElementListener;
-import net.named_data.jndn.encoding.ElementReader;
-import net.named_data.jndn.encoding.EncodingException;
-import net.named_data.jndn.transport.Transport;
-
-/**
- * Mock the transport class Example: ...
- *
- * @author Andrew Brown <andrew.brown@intel.com>
- */
-public class MockTransport extends Transport {
-
-  public final static int BUFFER_CAPACITY = 1024 * 1024; // allocate 1MB buffer
-  private static final Logger logger = Logger.getLogger(MockTransport.class.getName());
-  protected boolean connected;
-  protected ElementReader elementReader;
-  private ByteBuffer buffer = ByteBuffer.allocate(BUFFER_CAPACITY);
-  protected ByteBuffer sentBuffer = ByteBuffer.allocate(BUFFER_CAPACITY);
-  protected List<Data> sentDataPackets = new ArrayList<>();
-  protected List<Interest> sentInterestPackets = new ArrayList<>();
-
-  /**
-   * This transport is always local
-   *
-   * @param connectionInfo
-   * @return
-   */
-  public boolean isLocal(Transport.ConnectionInfo connectionInfo) {
-    return true;
-  }
-
-  /**
-   * Place data in the receive queue; when processEvents() is called, the
-   * calling application will receive these bytes.
-   *
-   * @param response
-   */
-  public void respondWith(ByteBuffer response) {
-    buffer.put(response);
-  }
-
-  /**
-   * Place data in the receive queue; when processEvents() is called, the
-   * calling application will receive this packet.
-   *
-   * @param response
-   */
-  public void respondWith(Data response) {
-    respondWith(response.wireEncode().buf());
-  }
-
-  /**
-   * Place data in the receive queue; when processEvents() is called, the
-   * calling application will receive this packet.
-   *
-   * @param request
-   */
-  public void respondWith(Interest request) {
-    respondWith(request.wireEncode().buf());
-  }
-
-  /**
-   * Inspect the bytes sent using this transport.
-   *
-   * @return
-   */
-  public ByteBuffer getSentBuffer() {
-    return sentBuffer;
-  }
-
-  /**
-   * Inspect the list of data packets sent using this transport; the alternative
-   * is to inspect getSentBuffer().
-   *
-   * @return
-   */
-  public List<Data> getSentDataPackets() {
-    return sentDataPackets;
-  }
-
-  /**
-   * Inspect the list of interest packets sent using this transport; the
-   * alternative is to inspect getSentBuffer().
-   *
-   * @return
-   */
-  public List<Interest> getSentInterestPackets() {
-    return sentInterestPackets;
-  }
-
-  /**
-   * Clear all sent and to-be-received data
-   */
-  public void clear() {
-    buffer = ByteBuffer.allocate(BUFFER_CAPACITY);
-    sentBuffer = ByteBuffer.allocate(BUFFER_CAPACITY);
-    sentDataPackets.clear();
-    sentInterestPackets.clear();
-  }
-
-  /**
-   * Mock the connection startup; calls this processEvents().
-   *
-   * @param connectionInfo
-   * @param elementListener
-   * @throws IOException
-   */
-  @Override
-  public void connect(Transport.ConnectionInfo connectionInfo,
-          ElementListener elementListener, Runnable onConnected) throws IOException {
-    logger.fine("Connecting...");
-    connected = true;
-    elementReader = new ElementReader(elementListener);
-    if (onConnected != null) {
-      onConnected.run();
-    }
-  }
-
-  /**
-   * Mock sending data to the host; access the data as bytes using
-   * getSentBuffer() or as packets with getSentDataPackets().
-   *
-   * @param data The buffer of data to send. This reads from position() to
-   * limit(), but does not change the position.
-   * @throws IOException For I/O error.
-   */
-  @Override
-  public void send(ByteBuffer data) throws IOException {
-    logger.fine("Sending " + (data.capacity() - data.position()) + " bytes");
-
-    // add to sent bytes
-    buffer.put(data);
-    data.flip();
-    sentBuffer.put(data);
-    data.flip();
-
-    // add to sent packets
-    byte first = data.get();
-    if (first == 5) {
-      data.position(0);
-      addSentInterest(data);
-    } else if (first == 6) {
-      data.position(0);
-      addSentData(data);
-    } else {
-      logger.warning("Unknown TLV packet type; cannot parse.");
-    }
-  }
-
-  /**
-   * Helper method to parse Data packets.
-   *
-   * @param data
-   */
-  protected void addSentData(ByteBuffer data) {
-    Data packet = new Data();
-    try {
-      packet.wireDecode(data);
-      sentDataPackets.add(packet);
-    } catch (EncodingException e) {
-      logger.warning("Failed to parse bytes into a data packet");
-    }
-  }
-
-  /**
-   * Helper method to parse Interest packets.
-   *
-   * @param data
-   */
-  protected void addSentInterest(ByteBuffer data) {
-    Interest packet = new Interest();
-    try {
-      packet.wireDecode(data);
-      sentInterestPackets.add(packet);
-    } catch (EncodingException e) {
-      logger.warning("Failed to parse bytes into an interest packet");
-    }
-  }
-
-  /**
-   * Process any data to receive and clear the input buffer; to mock incoming
-   * Data packets, add data to the buffer with respondWith().
-   *
-   * @throws IOException For I/O error.
-   * @throws EncodingException For invalid encoding.
-   */
-  @Override
-  public void processEvents() throws IOException, EncodingException {
-    if (!getIsConnected()) {
-      logger.warning("Not connnected, aborting...");
-      return;
-    }
-
-    // trace data sent
-    logger.finer(String.format("Processing buffer (position: %s, limit: %s, capacity: %s): %s", buffer.position(), buffer.limit(), buffer.capacity(), Arrays.toString(buffer.array())));
-
-    // pass data up to face
-    ByteBuffer temp = copy(buffer);
-    temp.flip();
-
-    // reset buffer
-    buffer = ByteBuffer.allocate(BUFFER_CAPACITY);
-
-    elementReader.onReceivedData(temp);
-  }
-
-  /**
-   * Copy one buffer to a new buffer, preserving the source buffer's position
-   * and limit.
-   *
-   * @param source the source buffer
-   * @return a copied buffer
-   */
-  private ByteBuffer copy(ByteBuffer source) {
-    ByteBuffer dest = ByteBuffer.allocate(source.capacity());
-
-    int saveLimit = source.limit();
-    int savePosition = source.position();
-    source.flip();
-
-    dest.put(source);
-
-    source.limit(saveLimit);
-    source.position(savePosition);
-
-    return dest;
-  }
-
-  /**
-   * Check if the transport is connected.
-   *
-   * @return true if connected.
-   */
-  @Override
-  public boolean getIsConnected() {
-    return connected;
-  }
-
-  /**
-   * Close the connection.
-   *
-   * @throws IOException For I/O error.
-   */
-  @Override
-  public void close() throws IOException {
-    logger.fine("Closing...");
-    connected = false;
-  }
-
-  @Override
-  public boolean isAsync() {
-    return false;
-  }
-}
diff --git a/src/test/java/com/intel/jndn/mock/MockFaceTest.java b/src/test/java/com/intel/jndn/mock/MockFaceTest.java
index f68c331..144a05e 100644
--- a/src/test/java/com/intel/jndn/mock/MockFaceTest.java
+++ b/src/test/java/com/intel/jndn/mock/MockFaceTest.java
@@ -19,168 +19,230 @@
 import net.named_data.jndn.*;
 import net.named_data.jndn.encoding.EncodingException;
 import net.named_data.jndn.security.SecurityException;
-import net.named_data.jndn.transport.Transport;
 import net.named_data.jndn.util.Blob;
+import org.junit.Before;
 import org.junit.Test;
+
 import static org.junit.Assert.*;
 
 /**
  * Test MockFace functionality
- *
- * @author Andrew Brown <andrew.brown@intel.com>
  */
 public class MockFaceTest {
+  @Before
+  public void setup() throws SecurityException {
+    face = new MockFace();
+    counter = 0;
+    recvData = null;
+    isTimeout = false;
+    exception = null;
+  }
 
-  /**
-   * Setup logging
-   */
-  private static final Logger logger = Logger.getLogger(MockFaceTest.class.getName());
+  /////////////////////////////////////////////////////////////////////////////
 
-  /**
-   * Test setting responses for specific names
-   *
-   * @throws java.io.IOException
-   * @throws net.named_data.jndn.encoding.EncodingException
-   */
   @Test
-  public void testWithResponses() throws IOException, EncodingException {
-    MockFace face = new MockFace();
+  public void ExpressInterest() throws IOException, EncodingException, InterruptedException {
+    // make request
+    expressInterest("/test/with/responses");
 
-    // add response
+    run(2);
+
+    // add response (after face is connectd)
     Data response = new Data(new Name("/test/with/responses"));
     response.setContent(new Blob("..."));
-    face.addResponse(new Name("/test/with/responses"), response);
+    face.receive(response);
 
-    // make request
-    final TestCounter count = new TestCounter();
-    logger.info("Express interest: /test/with/responses");
-    face.expressInterest(new Interest(new Name("/test/with/responses")), new OnData() {
-      @Override
-      public void onData(Interest interest, Data data) {
-        count.inc();
-        logger.fine("Received data");
-        assertEquals(data.getContent().buf(), new Blob("...").buf());
-      }
-    });
+    run(20);
 
-    // process face until a response is received
-    int allowedLoops = 100;
-    while (count.get() == 0 && allowedLoops > 0) {
-      allowedLoops--;
-      face.processEvents();
-    }
-    assertEquals(1, count.get());
+    assertNotEquals(recvData, null);
+    assertEquals(isTimeout, false);
+    assertEquals(recvData.getName().toString(), "/test/with/responses");
+    assertEquals(recvData.getContent().buf(), new Blob("...").buf());
   }
 
-  /**
-   * Test serving data dynamically with OnInterest handlers
-   *
-   * @throws net.named_data.jndn.encoding.EncodingException
-   * @throws java.io.IOException
-   * @throws net.named_data.jndn.security.SecurityException
-   */
   @Test
-  public void testWithHandlers() throws EncodingException, IOException, net.named_data.jndn.security.SecurityException {
-    MockFace face = new MockFace();
+  public void ExpressInterest2() throws IOException, EncodingException, InterruptedException {
+    // add response (before face is connected)
+    Data response = new Data(new Name("/test/with/responses"));
+    response.setContent(new Blob("..."));
+    face.receive(response);
 
-    // add interest handler
-    logger.info("Register prefix: /test/with/responses");
-    face.registerPrefix(new Name("/test/with/handlers"), new OnInterestCallback() {
-      @Override
-      public void onInterest(Name prefix, Interest interest, Face face, long interestFilterId, InterestFilter filter) {
-        logger.fine("Received interest, responding: " + interest.getName().toUri());
-        Data response = new Data(new Name("/test/with/handlers"));
-        response.setContent(new Blob("..."));
-        try {
-          face.putData(response);
-        } catch (IOException e) {
-          fail("Failed to send encoded data packet.");
+    // make request
+    expressInterest("/test/with/responses");
+
+    run(20);
+
+    assertNotEquals(recvData, null);
+    assertEquals(isTimeout, false);
+    assertEquals(recvData.getName().toString(), "/test/with/responses");
+    assertEquals(recvData.getContent().buf(), new Blob("...").buf());
+  }
+
+  @Test
+  public void ExpressInterestTimeout() throws IOException, EncodingException, InterruptedException {
+    // make request
+    expressInterest("/some/name");
+
+    run(20);
+
+    assertEquals(recvData, null);
+    assertEquals(isTimeout, true);
+  }
+
+  @Test
+  public void RegisterPrefix() throws IOException, SecurityException, EncodingException, InterruptedException {
+    class State {
+      boolean regFailed = false;
+      boolean regSucceed = false;
+    }
+    final State state = new State();
+
+    logger.info("Register prefix: /test/with/handlers");
+    face.registerPrefix(new Name("/test/with/handlers"),
+      new OnInterestCallback() {
+        @Override
+        public void onInterest(Name prefix, Interest interest, Face face, long interestFilterId, InterestFilter filter) {
+          logger.info("Received interest, responding: " + interest.getName().toUri());
+          Data response = new Data(new Name("/test/with/handlers"));
+          response.setContent(new Blob("..."));
+          try {
+            face.putData(response);
+          } catch (IOException e) {
+            exception = e;
+          }
+          counter++;
+        }
+      },
+      new OnRegisterFailed() {
+        @Override
+        public void onRegisterFailed(Name prefix) {
+          logger.info("Prefix registration fails: " + prefix);
+          state.regFailed = true;
+          counter++;
+        }
+      },
+      new OnRegisterSuccess() {
+        @Override
+        public void onRegisterSuccess(Name prefix, long registeredPrefixId) {
+          logger.info("Prefix registration succeed: " + prefix);
+          state.regSucceed = true;
+          counter++;
         }
       }
-    }, null);
+    );
+
+    run(100, 1);
+    assertTrue(state.regSucceed);
+    assertFalse(state.regFailed);
 
     // make request
-    final TestCounter count = new TestCounter();
-    logger.info("Express interest: /test/with/responses");
-    face.expressInterest(new Interest(new Name("/test/with/handlers")), new OnData() {
-      @Override
-      public void onData(Interest interest, Data data) {
-        count.inc();
-        logger.fine("Received data");
-        assertEquals(data.getContent().buf(), new Blob("...").buf());
-      }
-    });
+    face.receive(new Interest(new Name("/test/with/handlers")));
 
-    // process faces until a response is received
-    int allowedLoops = 100;
-    while (count.get() == 0 && allowedLoops > 0) {
-      allowedLoops--;
-      face.processEvents();
-    }
-    assertEquals(1, count.get());
+    run(100, 2);
+
+    assertNull(exception);
+
+    assertEquals(face.sentData.size(), 1);
+    assertFalse(isTimeout);
+    assertEquals("/test/with/handlers", face.sentData.get(0).getName().toString());
+    assertEquals(new Blob("...").buf(), face.sentData.get(0).getContent().buf());
   }
 
-  /**
-   * Ensure registering a prefix connects the underlying transport
-   *
-   * @throws IOException
-   * @throws SecurityException
-   */
   @Test
-  public void testRegistrationConnectsTransport() throws IOException, SecurityException {
-    MockFace face = new MockFace();
+  public void RegistrationPrefixConnectTransport() throws IOException, SecurityException {
     assertFalse(face.getTransport().getIsConnected());
-    face.registerPrefix(new Name("/fake/prefix"), (OnInterest) null, null);
+    face.registerPrefix(new Name("/fake/prefix"), (OnInterestCallback) null, (OnRegisterFailed) null,
+      (OnRegisterSuccess) null);
     assertTrue(face.getTransport().getIsConnected());
   }
-  
-  /**
-   * Test that interest filters work as expected
-   */
+
   @Test
-  public void testInterestFilters() throws IOException, SecurityException, EncodingException {
-    MockFace face = new MockFace();
-    
-    final TestCounter count = new TestCounter();
-    face.setInterestFilter(new InterestFilter("/a/b"), new OnInterestCallback() {
+  public void SetInterestFilter() throws IOException, SecurityException, EncodingException, InterruptedException {
+    class State {
+      boolean regFailed = false;
+      boolean regSucceed = false;
+    }
+    final State state = new State();
+
+    // connect transport
+    face.registerPrefix(new Name("/fake/prefix"), (OnInterestCallback) null, new OnRegisterFailed() {
       @Override
-      public void onInterest(Name prefix, Interest interest, Face face, long interestFilterId, InterestFilter filter) {
-        count.inc();
+      public void onRegisterFailed(Name prefix) {
+        state.regFailed = true;
+        counter++;
+      }
+    }, new OnRegisterSuccess() {
+      @Override
+      public void onRegisterSuccess(Name prefix, long registeredPrefixId) {
+        state.regSucceed = true;
+        counter++;
       }
     });
-    
-    face.expressInterest(new Interest(new Name("/a/b")).setInterestLifetimeMilliseconds(100), null);
-    face.processEvents();
-    
-    assertEquals(1, count.get());
-  }
-  
-  @Test
-  public void testResponseFromInsideElementReader() throws IOException, SecurityException, EncodingException{
-    MockFace face = new MockFace();
+
+    // set filter
     face.setInterestFilter(new InterestFilter("/a/b"), new OnInterestCallback() {
       @Override
       public void onInterest(Name prefix, Interest interest, Face face, long interestFilterId, InterestFilter filter) {
-        try {
-          face.putData(new Data(interest.getName()).setContent(new Blob("......")));
-        } catch (IOException ex) {
-          fail("Failed to put data.");
+        counter++;
+      }
+    });
+
+    face.receive(new Interest(new Name("/a/b")).setInterestLifetimeMilliseconds(100));
+
+    run(10, 2);
+
+    assertEquals(2, counter);
+    assertTrue(state.regSucceed);
+    assertFalse(state.regFailed);
+  }
+
+  /////////////////////////////////////////////////////////////////////////////
+
+  private void
+  run(int limit, int maxCounter) throws IOException, EncodingException, InterruptedException {
+    // process face until a response is received
+    int allowedLoops = limit;
+    while (counter < maxCounter && allowedLoops > 0) {
+      allowedLoops--;
+      face.processEvents();
+      Thread.sleep(100);
+    }
+  }
+  
+  private void
+  run(int limit) throws IOException, EncodingException, InterruptedException {
+    run(limit, 1);
+  }
+
+  private void
+  expressInterest(String name) throws IOException {
+    logger.info("Express interest: " + name);
+    face.expressInterest(new Interest(new Name(name)).setInterestLifetimeMilliseconds(1000), new
+        OnData() {
+          @Override
+          public void onData(Interest interest, Data data) {
+            counter++;
+            logger.fine("Received data");
+            recvData = data;
+          }
+        },
+      new OnTimeout() {
+        @Override
+        public void onTimeout(Interest interest) {
+          logger.fine("Received timeout");
+          counter++;
+          isTimeout = true;
         }
-      }
-    });
-    
-    final TestCounter count = new TestCounter();
-    face.expressInterest(new Interest(new Name("/a/b/c")), new OnData() {
-      @Override
-      public void onData(Interest interest, Data data) {
-        logger.info("Data returned: " + data.getContent().toString());
-        count.inc();
-      }
-    });
-    assertEquals(0, count.get());
-    
-    face.processEvents();
-    face.processEvents(); // the second processEvents() is required because the InterestFilter sends data from within the first processEvents loop
-    assertEquals(1, count.get());
+      });
   }
+
+  /////////////////////////////////////////////////////////////////////////////
+
+  private static final Logger logger = Logger.getLogger(MockFaceTest.class.getName());
+
+  private MockFace face;
+  private int counter;
+  private Data recvData = null;
+  private boolean isTimeout = false;
+  private Exception exception = null;
 }
diff --git a/src/test/java/com/intel/jndn/mock/MockTransportTest.java b/src/test/java/com/intel/jndn/mock/MockTransportTest.java
deleted file mode 100644
index dfbf514..0000000
--- a/src/test/java/com/intel/jndn/mock/MockTransportTest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * jndn-mock
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 3, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
- * more details.
- */
-package com.intel.jndn.mock;
-
-import java.io.IOException;
-import java.util.logging.Logger;
-import net.named_data.jndn.Data;
-import net.named_data.jndn.Face;
-import net.named_data.jndn.Interest;
-import net.named_data.jndn.Name;
-import net.named_data.jndn.OnData;
-import net.named_data.jndn.OnTimeout;
-import net.named_data.jndn.encoding.EncodingException;
-import net.named_data.jndn.util.Blob;
-import org.junit.Test;
-import static org.junit.Assert.*;
-
-/**
- * Mock the transport class TODO add face.registerPrefix() example
- *
- * @author Andrew Brown <andrew.brown@intel.com>
- */
-public class MockTransportTest {
-
-  /**
-   * Setup logging
-   */
-  private static final Logger logger = Logger.getLogger(MockTransportTest.class.getName());
-
-  /**
-   * Test sending a Data packet.
-   *
-   * @throws java.io.IOException
-   * @throws net.named_data.jndn.encoding.EncodingException
-   */
-  @Test
-  public void testSendData() throws IOException, EncodingException {
-    MockTransport transport = new MockTransport();
-    Face face = new Face(transport, null);
-
-    // setup return data
-    Data response = new Data(new Name("/a/b/c"));
-    response.setContent(new Blob("..."));
-    transport.respondWith(response);
-
-    // express interest on the face
-    final TestCounter count = new TestCounter();
-    face.expressInterest(new Interest(new Name("/a/b/c")), new OnData() {
-      @Override
-      public void onData(Interest interest, Data data) {
-        count.inc();
-        logger.fine("Received data");
-        assertEquals(data.getContent().buf(), new Blob("...").buf());
-      }
-    });
-
-    // process the face until one response
-    while (count.get() == 0) {
-      face.processEvents();
-    }
-
-    // check for sent packets
-    assertEquals(0, transport.getSentDataPackets().size());
-    assertEquals(1, transport.getSentInterestPackets().size());
-  }
-
-  /**
-   * Test sending multiple Data packets.
-   *
-   * @throws java.io.IOException
-   * @throws net.named_data.jndn.encoding.EncodingException
-   */
-  @Test
-  public void testSendMultipleData() throws IOException, EncodingException {
-    MockTransport transport = new MockTransport();
-    Face face = new Face(transport, null);
-
-    // setup return data
-    Data response1 = new Data(new Name("/a/b/c/1"));
-    response1.setContent(new Blob("..."));
-    transport.respondWith(response1);
-    Data response2 = new Data(new Name("/a/b/c/2"));
-    response2.setContent(new Blob("..."));
-    transport.respondWith(response2);
-
-    // express interest on the face
-    final TestCounter count = new TestCounter();
-    face.expressInterest(new Interest(new Name("/a/b/c/1")), new OnData() {
-      @Override
-      public void onData(Interest interest, Data data) {
-        count.inc();
-        logger.fine("Received data");
-        assertEquals(data.getContent().buf(), new Blob("...").buf());
-      }
-    });
-
-    // process the face until one response received
-    while (count.get() == 0) {
-      face.processEvents();
-    }
-
-    // check for sent packets
-    assertEquals(0, transport.getSentDataPackets().size());
-    assertEquals(1, transport.getSentInterestPackets().size());
-
-    // express interest again, but this time it should time out because there 
-    // is no data left on the wire; the first processEvents() has already 
-    // picked it up
-    final TestCounter count2 = new TestCounter();
-    Interest failingInterest = new Interest(new Name("/a/b/c/2"));
-    failingInterest.setInterestLifetimeMilliseconds(50);
-    face.expressInterest(failingInterest, new OnData() {
-      @Override
-      public void onData(Interest interest, Data data) {
-        count2.inc();
-        fail("Should not return data; data should already be cleared");
-      }
-    }, new OnTimeout() {
-      @Override
-      public void onTimeout(Interest interest) {
-        count2.inc();
-        assertTrue(true);
-      }
-    });
-
-    // process the face until timeout
-    while (count2.get() == 0) {
-      face.processEvents();
-    }
-
-    // check for sent packets
-    assertEquals(0, transport.getSentDataPackets().size());
-    assertEquals(2, transport.getSentInterestPackets().size());
-  }
-
-  /**
-   * Test for buffer overflow exceptions
-   */
-  @Test
-  public void testBufferOverflowException() throws IOException {
-    MockTransport transport = new MockTransport();
-
-    Interest interest = buildInterest();
-    Data data = buildData();
-    assertTrue(data.wireEncode().size() > interest.wireEncode().size());
-
-    transport.send(interest.wireEncode().buf());
-    transport.send(data.wireEncode().buf());
-  }
-  
-  /**
-   * Verify that processing no events does not cause errors
-   */
-  @Test
-  public void testProcessNoEvents() throws IOException, EncodingException{
-    MockFace face = new MockFace();
-    face.expressInterest((Name) null, null);
-    face.processEvents();
-    face.processEvents();
-  }
-
-  private Data buildData() {
-    Data data = new Data(new Name("/a/b/c/1"));
-    data.setContent(new Blob("............................................"));
-    data.getMetaInfo().setFreshnessPeriod(1000);
-    return data;
-  }
-
-  private Interest buildInterest() {
-    Interest interest = new Interest(new Name("/a/b/c"));
-    interest.setInterestLifetimeMilliseconds(50);
-    return interest;
-  }
-}
diff --git a/src/test/java/com/intel/jndn/mock/TestCounter.java b/src/test/java/com/intel/jndn/mock/TestCounter.java
deleted file mode 100644
index 3627ac4..0000000
--- a/src/test/java/com/intel/jndn/mock/TestCounter.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * jndn-mock
- * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 3, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
- * more details.
- */
-package com.intel.jndn.mock;
-
-/**
- *
- * @author Andrew Brown <andrew.brown@intel.com>
- */
-public class TestCounter {
-
-  private int count = 0;
-
-  public void inc() {
-    count++;
-  }
-
-  public int get() {
-    return count;
-  }
-}
