diff --git a/src/main/java/com/intel/jndn/mock/FaceExtension.java b/src/main/java/com/intel/jndn/mock/FaceExtension.java
new file mode 100644
index 0000000..3d6af4a
--- /dev/null
+++ b/src/main/java/com/intel/jndn/mock/FaceExtension.java
@@ -0,0 +1,114 @@
+/*
+ * 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.Data;
+import net.named_data.jndn.Face;
+import net.named_data.jndn.ForwardingFlags;
+import net.named_data.jndn.Interest;
+import net.named_data.jndn.InterestFilter;
+import net.named_data.jndn.Name;
+import net.named_data.jndn.OnData;
+import net.named_data.jndn.OnInterest;
+import net.named_data.jndn.OnInterestCallback;
+import net.named_data.jndn.OnRegisterFailed;
+import net.named_data.jndn.OnTimeout;
+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.setScope(interestTemplate.getScope());
+			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, ForwardingFlags flags,
+			WireFormat wireFormat) throws IOException, net.named_data.jndn.security.SecurityException;
+
+	public abstract long registerPrefix(Name prefix, final OnInterest onInterest,
+			OnRegisterFailed onRegisterFailed, 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 6a9a11a..878040f 100644
--- a/src/main/java/com/intel/jndn/mock/MockFace.java
+++ b/src/main/java/com/intel/jndn/mock/MockFace.java
@@ -14,6 +14,7 @@
 package com.intel.jndn.mock;
 
 import java.io.IOException;
+import java.nio.ByteBuffer;
 import java.util.HashMap;
 import java.util.Map.Entry;
 import java.util.logging.Logger;
@@ -21,14 +22,17 @@
 import net.named_data.jndn.Face;
 import net.named_data.jndn.ForwardingFlags;
 import net.named_data.jndn.Interest;
+import net.named_data.jndn.InterestFilter;
 import net.named_data.jndn.Name;
 import net.named_data.jndn.Node;
 import net.named_data.jndn.OnData;
 import net.named_data.jndn.OnInterest;
+import net.named_data.jndn.OnInterestCallback;
 import net.named_data.jndn.OnRegisterFailed;
 import net.named_data.jndn.OnTimeout;
 import net.named_data.jndn.encoding.EncodingException;
 import net.named_data.jndn.encoding.WireFormat;
+import net.named_data.jndn.security.SecurityException;
 import net.named_data.jndn.transport.Transport;
 
 /**
@@ -51,7 +55,7 @@
  *
  * @author Andrew Brown <andrew.brown@intel.com>
  */
-public class MockFace extends Face {
+public class MockFace extends FaceExtension {
 
   private static final Logger logger = Logger.getLogger(MockFace.class.getName());
   private final Node node_;
@@ -119,7 +123,7 @@
     else if (registeredPrefixId != -1) {
       logger.fine("Found handler for: " + interestName);
       MockOnInterestHandler handler = handlerMap.get(findRegisteredHandler(interest));
-      handler.onInterest.onInterest(handler.prefix, interest, node_.getTransport(), registeredPrefixId);
+      handler.signal(interest, registeredPrefixId);
     } // log failure
     else {
       logger.warning("No response found for interest (aborting): " + interestName);
@@ -153,6 +157,7 @@
 
     Name prefix;
     OnInterest onInterest;
+    OnInterestCallback onInterestCallback;
     ForwardingFlags flags;
 
     public MockOnInterestHandler(Name prefix, OnInterest onInterest, ForwardingFlags flags) {
@@ -160,6 +165,21 @@
       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);
+      }
+    }
   }
 
   /**
@@ -189,287 +209,6 @@
   }
 
   /**
-   * Send the Interest through the transport, read the entire response and call
-   * onData(interest, data). This uses the default
-   * WireFormat.getDefaultWireFormat().
-   *
-   * @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.
-   * @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) throws IOException {
-    return expressInterest(interest, onData, onTimeout, WireFormat.getDefaultWireFormat());
-  }
-
-  /**
-   * Send the Interest through the transport, read the entire response and call
-   * onData(interest, data). Ignore if the interest times out.
-   *
-   * @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 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, WireFormat wireFormat) throws IOException {
-    return expressInterest(interest, onData, null, wireFormat);
-  }
-
-  /**
-   * Send the Interest through the transport, read the entire response and call
-   * onData(interest, data). Ignore if the interest times out. This uses the
-   * default WireFormat.getDefaultWireFormat().
-   *
-   * @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.
-   * @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) throws IOException {
-    return expressInterest(interest, onData, null, WireFormat.getDefaultWireFormat());
-  }
-
-  /**
-   * Encode name as an Interest. If interestTemplate is not null, use its
-   * interest selectors. Send the interest through the transport, read the
-   * entire response and call onData(interest, data).
-   *
-   * @param name A Name for the interest. This copies the Name.
-   * @param interestTemplate If not null, copy interest selectors from the
-   * template. This does not keep a pointer to the Interest object.
-   * @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(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.setScope(interestTemplate.getScope());
-      interest.setInterestLifetimeMilliseconds(
-              interestTemplate.getInterestLifetimeMilliseconds());
-      // Don't copy the nonce.
-    } else {
-      interest.setInterestLifetimeMilliseconds(4000.0);
-    }
-
-    return expressInterest(interest, onData, onTimeout, wireFormat);
-  }
-
-  /**
-   * Encode name as an Interest. If interestTemplate is not null, use its
-   * interest selectors. Send the interest through the transport, read the
-   * entire response and call onData(interest, data). Use a default interest
-   * lifetime.
-   *
-   * @param name A Name for the interest. This copies the Name.
-   * @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(Name name, OnData onData, OnTimeout onTimeout,
-          WireFormat wireFormat) throws IOException {
-    return expressInterest(name, null, onData, onTimeout, wireFormat);
-  }
-
-  /**
-   * Encode name as an Interest. If interestTemplate is not null, use its
-   * interest selectors. Send the interest through the transport, read the
-   * entire response and call onData(interest, data). Ignore if the interest
-   * times out.
-   *
-   * @param name A Name for the interest. This copies the Name.
-   * @param interestTemplate If not null, copy interest selectors from the
-   * template. This does not keep a pointer to the Interest object.
-   * @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 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(Name name, Interest interestTemplate, OnData onData,
-          WireFormat wireFormat) throws IOException {
-    return expressInterest(name, interestTemplate, onData, null, wireFormat);
-  }
-
-  /**
-   * Encode name as an Interest. If interestTemplate is not null, use its
-   * interest selectors. Send the interest through the transport, read the
-   * entire response and call onData(interest, data). This uses the default
-   * WireFormat.getDefaultWireFormat().
-   *
-   * @param name A Name for the interest. This copies the Name.
-   * @param interestTemplate If not null, copy interest selectors from the
-   * template. This does not keep a pointer to the Interest object.
-   * @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.
-   * @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(Name name, Interest interestTemplate, OnData onData,
-          OnTimeout onTimeout) throws IOException {
-    return expressInterest(name, interestTemplate, onData, onTimeout,
-            WireFormat.getDefaultWireFormat());
-  }
-
-  /**
-   * Encode name as an Interest. If interestTemplate is not null, use its
-   * interest selectors. Send the interest through the transport, read the
-   * entire response and call onData(interest, data). Ignore if the interest
-   * times out. This uses the default WireFormat.getDefaultWireFormat().
-   *
-   * @param name A Name for the interest. This copies the Name.
-   * @param interestTemplate If not null, copy interest selectors from the
-   * template. This does not keep a pointer to the Interest object.
-   * @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.
-   * @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(Name name, Interest interestTemplate, OnData onData) throws IOException {
-    return expressInterest(name, interestTemplate, onData, null, WireFormat.getDefaultWireFormat());
-  }
-
-  /**
-   * Encode name as an Interest. If interestTemplate is not null, use its
-   * interest selectors. Send the interest through the transport, read the
-   * entire response and call onData(interest, data). Use a default interest
-   * lifetime. This uses the default WireFormat.getDefaultWireFormat().
-   *
-   * @param name A Name for the interest. This copies the Name.
-   * @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.
-   * @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(Name name, OnData onData, OnTimeout onTimeout) throws IOException {
-    return expressInterest(name, null, onData, onTimeout, WireFormat.getDefaultWireFormat());
-  }
-
-  /**
-   * Encode name as an Interest. If interestTemplate is not null, use its
-   * interest selectors. Send the interest through the transport, read the
-   * entire response and call onData(interest, data). Use a default interest
-   * lifetime. Ignore if the interest times out.
-   *
-   * @param name A Name for the interest. This copies the Name.
-   * @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 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(Name name, OnData onData, WireFormat wireFormat) throws IOException {
-    return expressInterest(name, null, onData, null, wireFormat);
-  }
-
-  /**
-   * Encode name as an Interest. If interestTemplate is not null, use its
-   * interest selectors. Send the interest through the transport, read the
-   * entire response and call onData(interest, data). Use a default interest
-   * lifetime. Ignore if the interest times out. This uses the default
-   * WireFormat.getDefaultWireFormat().
-   *
-   * @param name A Name for the interest. This copies the Name.
-   * @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.
-   * @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(Name name, OnData onData) throws IOException {
-    return expressInterest(name, null, onData, null, WireFormat.getDefaultWireFormat());
-  }
-
-  /**
-   * Remove the pending interest entry with the pendingInterestId from the
-   * pending interest table. This does not affect another pending interest with
-   * a different pendingInterestId, even if it has the same interest name. If
-   * there is no entry with the pendingInterestId, do nothing.
-   *
-   * @param pendingInterestId The ID returned from expressInterest.
-   */
-//  public void removePendingInterest(long pendingInterestId) {
-//    node_.removePendingInterest(pendingInterestId);
-//  }
-  /**
    * 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
@@ -498,101 +237,28 @@
   public long registerPrefix(Name prefix, OnInterest onInterest, OnRegisterFailed onRegisterFailed,
           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())
+    if (!getTransport().getIsConnected()) {
       getTransport().connect(node_.getConnectionInfo(), node_);
-    
+    }
+
     lastRegisteredId++;
     handlerMap.put(lastRegisteredId, new MockOnInterestHandler(prefix, onInterest, flags));
     return lastRegisteredId;
   }
 
-  /**
-   * Register prefix with the connected NDN hub and call onInterest when a
-   * matching interest is received. This uses the default
-   * WireFormat.getDefaultWireFormat().
-   *
-   * @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.
-   * @return The lastRegisteredId prefix ID which can be used with
-   * removeRegisteredPrefix.
-   * @throws IOException For I/O error in sending the registration request.
-   */
   @Override
-  public long registerPrefix(Name prefix, OnInterest onInterest, OnRegisterFailed onRegisterFailed,
-          ForwardingFlags flags) throws IOException, net.named_data.jndn.security.SecurityException {
-    return registerPrefix(prefix, onInterest, onRegisterFailed, flags,
-            WireFormat.getDefaultWireFormat());
+  public long registerPrefix(Name prefix, OnInterestCallback onInterest, OnRegisterFailed onRegisterFailed, ForwardingFlags flags, WireFormat wireFormat) throws IOException, SecurityException {
+    // since we don't send an Interest, ensure the transport is connected
+    if (!getTransport().getIsConnected()) {
+      getTransport().connect(node_.getConnectionInfo(), node_);
+    }
+
+    lastRegisteredId++;
+    handlerMap.put(lastRegisteredId, new MockOnInterestHandler(prefix, onInterest, flags));
+    return lastRegisteredId;
   }
 
   /**
-   * Register prefix with the connected NDN hub and call onInterest when a
-   * matching interest is received. Use default ForwardingFlags.
-   *
-   * @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 wireFormat A WireFormat object used to encode the message.
-   * @return The lastRegisteredId 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, OnInterest onInterest, OnRegisterFailed onRegisterFailed,
-          WireFormat wireFormat) throws IOException, net.named_data.jndn.security.SecurityException {
-    return registerPrefix(prefix, onInterest, onRegisterFailed, new ForwardingFlags(), wireFormat);
-  }
-
-  /**
-   * Register prefix with the connected NDN hub and call onInterest when a
-   * matching interest is received. This uses the default
-   * WireFormat.getDefaultWireFormat(). Use default ForwardingFlags.
-   *
-   * @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).
-   * @return The lastRegisteredId 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, OnInterest onInterest,
-          OnRegisterFailed onRegisterFailed) throws IOException, net.named_data.jndn.security.SecurityException {
-    return registerPrefix(prefix, onInterest, onRegisterFailed, new ForwardingFlags(),
-            WireFormat.getDefaultWireFormat());
-  }
-
-  /**
-   * Remove the lastRegisteredId prefix entry with the registeredPrefixId from
-   * the lastRegisteredId prefix table. This does not affect another
-   * lastRegisteredId prefix with a different registeredPrefixId, even if it has
-   * the same prefix name. If there is no entry with the registeredPrefixId, do
-   * nothing.
-   *
-   * @param registeredPrefixId The ID returned from registerPrefix.
-   */
-//  public void removeRegisteredPrefix(long registeredPrefixId) {
-//    handlerMap.remove(registeredPrefixId);
-//  }
-  /**
    * 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
@@ -610,10 +276,39 @@
     node_.processEvents();
   }
 
-  /**
-   * Shut down and disconnect this Face.
-   */
-//  public void shutdown() {
-//    node_.shutdown();
-//  }
+  @Override
+  public void removeRegisteredPrefix(long registeredPrefixId) {
+    handlerMap.remove(registeredPrefixId);
+  }
+
+  @Override
+  public long setInterestFilter(InterestFilter filter, OnInterestCallback onInterest) {
+    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+  }
+
+  @Override
+  public void unsetInterestFilter(long interestFilterId) {
+    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+  }
+
+  @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();
+  }
+
 }
diff --git a/src/test/java/com/intel/jndn/mock/MockFaceTest.java b/src/test/java/com/intel/jndn/mock/MockFaceTest.java
index 6bbbdda..afab856 100644
--- a/src/test/java/com/intel/jndn/mock/MockFaceTest.java
+++ b/src/test/java/com/intel/jndn/mock/MockFaceTest.java
@@ -150,7 +150,7 @@
   public void testRegistrationConnectsTransport() throws IOException, SecurityException {
     MockFace face = new MockFace();
     assertFalse(face.getTransport().getIsConnected());
-    face.registerPrefix(new Name("/fake/prefix"), null, null);
+    face.registerPrefix(new Name("/fake/prefix"), (OnInterest) null, null);
     assertTrue(face.getTransport().getIsConnected());
   }
 }
