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;
-  }
-}
