diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c7ccd3b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,27 @@
+# Created by https://www.gitignore.io
+
+### Maven ###
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+
+
+### Java ###
+*.class
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+# Linux temporary files
+*~
diff --git a/nb-configuration.xml b/nb-configuration.xml
new file mode 100644
index 0000000..38ca257
--- /dev/null
+++ b/nb-configuration.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project-shared-configuration>
+    <!--
+This file contains additional configuration written by modules in the NetBeans IDE.
+The configuration is intended to be shared among all the users of project and
+therefore it is assumed to be part of version control checkout.
+Without this configuration present, some functionality in the IDE may be limited or fail altogether.
+-->
+    <properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
+        <!--
+Properties that influence various parts of the IDE, especially code formatting and the like. 
+You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
+That way multiple projects can share the same settings (useful for formatting rules for example).
+Any value defined here will override the pom.xml file value but is only applicable to the current project.
+-->
+        <org-netbeans-modules-editor-indent.CodeStyle.usedProfile>project</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>
+        <org-netbeans-modules-editor-indent.CodeStyle.project.spaces-per-tab>2</org-netbeans-modules-editor-indent.CodeStyle.project.spaces-per-tab>
+        <org-netbeans-modules-editor-indent.CodeStyle.project.tab-size>4</org-netbeans-modules-editor-indent.CodeStyle.project.tab-size>
+        <org-netbeans-modules-editor-indent.CodeStyle.project.indent-shift-width>2</org-netbeans-modules-editor-indent.CodeStyle.project.indent-shift-width>
+        <org-netbeans-modules-editor-indent.CodeStyle.project.expand-tabs>true</org-netbeans-modules-editor-indent.CodeStyle.project.expand-tabs>
+        <org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width>80</org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width>
+        <org-netbeans-modules-editor-indent.CodeStyle.project.text-line-wrap>none</org-netbeans-modules-editor-indent.CodeStyle.project.text-line-wrap>
+        <org-netbeans-modules-editor-indent.text.x-fortran.CodeStyle.project.text-limit-width>132</org-netbeans-modules-editor-indent.text.x-fortran.CodeStyle.project.text-limit-width>
+        <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaces-per-tab>2</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaces-per-tab>
+        <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.tab-size>4</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.tab-size>
+        <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.indent-shift-width>2</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.indent-shift-width>
+        <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.expand-tabs>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.expand-tabs>
+        <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.text-limit-width>80</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.text-limit-width>
+        <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.text-line-wrap>none</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.text-line-wrap>
+    </properties>
+</project-shared-configuration>
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..1ac549e
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.intel.jndn.mock</groupId>
+  <artifactId>jndn-mock</artifactId>
+  <version>0.9.1</version>
+  <packaging>jar</packaging>
+  <description>Tools for testing NDN Java code without using network IO</description>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <maven.compiler.source>1.7</maven.compiler.source>
+    <maven.compiler.target>1.7</maven.compiler.target>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>net.named_data.jndn</groupId>
+      <artifactId>jndn</artifactId>
+      <version>RELEASE</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-api</artifactId>
+      <version>2.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+      <version>2.1</version>
+    </dependency>
+    <!-- Test dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.10</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <repositories>
+    <repository>
+      <id>ubit-artifactory-or.intel.com</id>
+      <name>IT Artifactory (libs)</name>
+      <url>https://ubit-artifactory-or.intel.com/artifactory/libs-release-local</url>
+    </repository>
+  </repositories>
+  <distributionManagement>
+    <repository>
+      <id>ubit-artifactory-or.intel.com</id>
+      <name>ubit-artifactory-or.intel.com-releases</name>
+      <url>https://ubit-artifactory-or.intel.com/artifactory/libs-release-local</url>
+    </repository>
+    <snapshotRepository>
+      <id>ubit-artifactory-or.intel.com</id>
+      <name>ubit-artifactory-or.intel.com-snapshots</name>
+      <url>https://ubit-artifactory-or.intel.com/artifactory/libs-snapshot-local</url>
+    </snapshotRepository>
+  </distributionManagement>
+</project>
\ No newline at end of file
diff --git a/src/main/java/com/intel/jndn/mock/MockFace.java b/src/main/java/com/intel/jndn/mock/MockFace.java
new file mode 100644
index 0000000..8fb1f39
--- /dev/null
+++ b/src/main/java/com/intel/jndn/mock/MockFace.java
@@ -0,0 +1,572 @@
+/*
+ * File name: MockTransport.java
+ * 
+ * Purpose: Use the MockTransport to mock sending data over the network.
+ * 
+ * © Copyright Intel Corporation. All rights reserved.
+ * Intel Corporation, 2200 Mission College Boulevard,
+ * Santa Clara, CA 95052-8119, USA
+ */
+package com.intel.jndn.mock;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map.Entry;
+import net.named_data.jndn.Data;
+import net.named_data.jndn.ForwardingFlags;
+import net.named_data.jndn.Interest;
+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.OnRegisterFailed;
+import net.named_data.jndn.OnTimeout;
+import net.named_data.jndn.encoding.EncodingException;
+import net.named_data.jndn.encoding.WireFormat;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+/**
+ *
+ * @author Andrew Brown <andrew.brown@intel.com>
+ */
+public class MockFace {
+
+  private static final Logger logger = LogManager.getLogger();
+  private final Node node_;
+  HashMap<String, Data> responseMap = new HashMap<>();
+  HashMap<Long, MockOnInterestHandler> handlerMap = new HashMap<>();
+  long lastRegisteredId = 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);
+  }
+
+  /**
+   * 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.debug("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.debug("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.debug("Found response for: " + interestName);
+      Data data = responseMap.get(interestName);
+      ((MockTransport) node_.getTransport()).respondWith(data);
+    } // check if handler registered
+    else if (registeredPrefixId != -1) {
+      logger.debug("Found handler for: " + interestName);
+      MockOnInterestHandler handler = handlerMap.get(findRegisteredHandler(interest));
+      handler.onInterest.onInterest(handler.prefix, interest, node_.getTransport(), registeredPrefixId);
+    } // log failure
+    else {
+      logger.warn("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;
+    ForwardingFlags flags;
+
+    public MockOnInterestHandler(Name prefix, OnInterest onInterest, ForwardingFlags flags) {
+      this.prefix = prefix;
+      this.onInterest = onInterest;
+      this.flags = flags;
+    }
+  }
+
+  /**
+   * 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.
+   */
+  public long expressInterest(Interest interest, OnData onData, OnTimeout onTimeout,
+          WireFormat wireFormat) throws IOException {
+    long id = node_.expressInterest(interest, onData, onTimeout, wireFormat);
+    handleIncomingRequests(interest);
+    return id;
+  }
+
+  /**
+   * 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.
+   */
+  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.
+   */
+  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.
+   */
+  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.
+   */
+  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.
+   */
+  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.
+   */
+  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.
+   */
+  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.
+   */
+  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.
+   */
+  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.
+   */
+  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.
+   */
+  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
+   * 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 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.
+   */
+  public long registerPrefix(Name prefix, OnInterest onInterest, OnRegisterFailed onRegisterFailed,
+          ForwardingFlags flags, WireFormat wireFormat) throws IOException, net.named_data.jndn.security.SecurityException {
+    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.
+   */
+  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());
+  }
+
+  /**
+   * 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.
+   */
+  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.
+   */
+  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
+   * 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.
+   */
+  public void processEvents() throws IOException, EncodingException {
+    // Just call Node's processEvents.
+    node_.processEvents();
+  }
+
+  /**
+   * Shut down and disconnect this Face.
+   */
+  public void shutdown() {
+    node_.shutdown();
+  }
+}
diff --git a/src/main/java/com/intel/jndn/mock/MockTransport.java b/src/main/java/com/intel/jndn/mock/MockTransport.java
new file mode 100644
index 0000000..0704f94
--- /dev/null
+++ b/src/main/java/com/intel/jndn/mock/MockTransport.java
@@ -0,0 +1,234 @@
+/*
+ * File name: MockTransport.java
+ * 
+ * Purpose: Provide testing functionality for running NDN unit tests without
+ * connecting to the network or requiring an NFD installed.
+ * 
+ * © Copyright Intel Corporation. All rights reserved.
+ * Intel Corporation, 2200 Mission College Boulevard,
+ * Santa Clara, CA 95052-8119, USA
+ */
+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 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;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+/**
+ * Mock the transport class Example: ...
+ *
+ * @author Andrew Brown <andrew.brown@intel.com>
+ */
+public class MockTransport extends Transport {
+
+  public final static int BUFFER_CAPACITY = 2000;
+  private static final Logger logger = LogManager.getLogger();
+  protected boolean connected;
+  protected ElementReader elementReader;
+  protected 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<>();
+
+  /**
+   * 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) throws IOException {
+    logger.debug("Connecting...");
+    connected = true;
+    elementReader = new ElementReader(elementListener);
+  }
+
+  /**
+   * 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.debug("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.warn("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.warn("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.warn("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.warn("Not connnected, aborting...");
+      return;
+    }
+
+    // trace data sent
+    logger.trace(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
+    buffer.limit(buffer.position());
+    buffer.position(0);
+    elementReader.onReceivedData(buffer);
+
+    // reset buffer
+    buffer = ByteBuffer.allocate(BUFFER_CAPACITY);
+  }
+
+  /**
+   * 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.debug("Closing...");
+    connected = false;
+  }
+}
diff --git a/src/main/resources/log4j2-test.xml b/src/main/resources/log4j2-test.xml
new file mode 100644
index 0000000..602b5ab
--- /dev/null
+++ b/src/main/resources/log4j2-test.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="WARN">
+  <Appenders>
+    <Console name="Console" target="SYSTEM_OUT">
+      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Root level="info">
+      <AppenderRef ref="Console"/>
+    </Root>
+  </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..0dac33a
--- /dev/null
+++ b/src/main/resources/log4j2.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="WARN">
+  <Appenders>
+    <Console name="Console" target="SYSTEM_OUT">
+      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Root level="warn">
+      <AppenderRef ref="Console"/>
+    </Root>
+  </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/src/test/java/com/intel/jndn/mock/MockFaceTest.java b/src/test/java/com/intel/jndn/mock/MockFaceTest.java
new file mode 100644
index 0000000..66db3a2
--- /dev/null
+++ b/src/test/java/com/intel/jndn/mock/MockFaceTest.java
@@ -0,0 +1,133 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.intel.jndn.mock;
+
+import java.io.IOException;
+import net.named_data.jndn.Data;
+import net.named_data.jndn.Interest;
+import net.named_data.jndn.Name;
+import net.named_data.jndn.OnData;
+import net.named_data.jndn.OnInterest;
+import net.named_data.jndn.encoding.EncodingException;
+import net.named_data.jndn.transport.Transport;
+import net.named_data.jndn.util.Blob;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Andrew Brown <andrew.brown@intel.com>
+ */
+public class MockFaceTest {
+
+  /**
+   * Setup logging
+   */
+  private static final Logger logger = LogManager.getLogger();
+
+  /**
+   * 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();
+
+    // add response
+    Data response = new Data(new Name("/test/with/responses"));
+    response.setContent(new Blob("..."));
+    face.addResponse(new Name("/test/with/responses"), response);
+
+    // make request
+    final Counter count = new Counter();
+    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.debug("Received data");
+        assertEquals(data.getContent().buf(), new Blob("...").buf());
+      }
+    });
+
+    // process face until a response is received
+    int allowedLoops = 100;
+    while (count.get() == 0 && allowedLoops > 0) {
+      allowedLoops--;
+      face.processEvents();
+    }
+    assertEquals(1, count.get());
+  }
+
+  /**
+   * 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();
+
+    // add interest handler
+    logger.info("Register prefix: /test/with/responses");
+    face.registerPrefix(new Name("/test/with/handlers"), new OnInterest() {
+      @Override
+      public void onInterest(Name prefix, Interest interest, Transport transport, long registeredPrefixId) {
+        logger.debug("Received interest, responding: " + interest.getName().toUri());
+        Data response = new Data(new Name("/test/with/handlers"));
+        response.setContent(new Blob("..."));
+        try {
+          transport.send(response.wireEncode().buf());
+        } catch (IOException e) {
+          fail("Failed to send encoded data packet.");
+        }
+      }
+    }, null);
+
+    // make request
+    final Counter count = new Counter();
+    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.debug("Received data");
+        assertEquals(data.getContent().buf(), new Blob("...").buf());
+      }
+    });
+
+    // process faces until a response is received
+    int allowedLoops = 100;
+    while (count.get() == 0 && allowedLoops > 0) {
+      allowedLoops--;
+      face.processEvents();
+    }
+    assertEquals(1, count.get());
+  }
+  
+  // TODO add childInherit test
+
+  /**
+   * Count reference
+   */
+  class Counter {
+
+    int count = 0;
+
+    public void inc() {
+      count++;
+    }
+
+    public int get() {
+      return count;
+    }
+  }
+}
diff --git a/src/test/java/com/intel/jndn/mock/MockTransportTest.java b/src/test/java/com/intel/jndn/mock/MockTransportTest.java
new file mode 100644
index 0000000..44ad258
--- /dev/null
+++ b/src/test/java/com/intel/jndn/mock/MockTransportTest.java
@@ -0,0 +1,159 @@
+/*
+ * File name: MockTransportTest.java
+ * 
+ * Purpose: Test the MockTransport
+ * 
+ * © Copyright Intel Corporation. All rights reserved.
+ * Intel Corporation, 2200 Mission College Boulevard,
+ * Santa Clara, CA 95052-8119, USA
+ */
+package com.intel.jndn.mock;
+
+import java.io.IOException;
+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.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+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 = LogManager.getLogger();
+
+  /**
+   * 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 Counter count = new Counter();
+    face.expressInterest(new Interest(new Name("/a/b/c")), new OnData() {
+      @Override
+      public void onData(Interest interest, Data data) {
+        count.inc();
+        logger.debug("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 Counter count = new Counter();
+    face.expressInterest(new Interest(new Name("/a/b/c/1")), new OnData() {
+      @Override
+      public void onData(Interest interest, Data data) {
+        count.inc();
+        logger.debug("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 Counter count2 = new Counter();
+    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());
+  }
+
+  /**
+   * Count reference
+   */
+  class Counter {
+
+    int count = 0;
+
+    public void inc() {
+      count++;
+    }
+
+    public int get() {
+      return count;
+    }
+  }
+}
