Merge pull request #5 from named-data/master

Upstream from Gerrit
diff --git a/build.gradle b/build.gradle
index 95bdd2d..3f3cab6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,9 +5,15 @@
   }
 }
 
+plugins {
+  id "org.sonarqube" version "1.2"
+  id 'net.saliman.cobertura' version '2.3.0'
+}
+
 apply plugin: 'java'
 apply plugin: 'maven'
 apply plugin: 'signing'
+apply plugin: 'checkstyle'
 
 group = 'com.intel.jndn.mock'
 version = '1.0.1'
@@ -22,9 +28,17 @@
   mavenCentral()
 }
 
+configurations {
+  checkstyleConfig
+}
+
 dependencies {
   compile 'net.named-data:jndn:0.10'
+
   testCompile 'junit:junit:4.12'
+  testRuntime 'org.slf4j:slf4j-api:1.7.16'
+
+  checkstyleConfig "com.puppycrawl.tools:checkstyle:6.15"
 }
 
 task javadocJar(type: Jar) {
@@ -47,6 +61,13 @@
   outputs.upToDateWhen { false }
 }
 
+tasks.withType(Checkstyle) {
+  checkstyleClasspath = project.configurations.checkstyleConfig
+  checkstyleTest {
+    configFile file('config/checkstyle/checkstyle-test.xml')
+  }
+}
+
 if (JavaVersion.current().isJava8Compatible()) {
   allprojects {
     tasks.withType(Javadoc) {
@@ -120,3 +141,7 @@
     }
   }
 }
+
+cobertura {
+  coverageFormats = ['html', 'xml']
+}
diff --git a/config/checkstyle/checkstyle-test.xml b/config/checkstyle/checkstyle-test.xml
new file mode 100644
index 0000000..81b48ec
--- /dev/null
+++ b/config/checkstyle/checkstyle-test.xml
@@ -0,0 +1,183 @@
+<?xml version="1.0"?>
+<!DOCTYPE module PUBLIC
+          "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
+          "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+
+<!--
+
+  Based on http://checkstyle.sourceforge.net/sun_style.html, the
+  Checkstyle configuration that checks the sun coding conventions from:
+
+    - the Java Language Specification at
+      http://java.sun.com/docs/books/jls/second_edition/html/index.html
+
+    - the Sun Code Conventions at http://java.sun.com/docs/codeconv/
+
+    - the Javadoc guidelines at
+      http://java.sun.com/j2se/javadoc/writingdoccomments/index.html
+
+    - the JDK Api documentation http://java.sun.com/j2se/docs/api/index.html
+
+    - some best practices
+
+  Checkstyle is very configurable. Be sure to read the documentation at
+  http://checkstyle.sourceforge.net (or in your downloaded distribution).
+
+  Most Checks are configurable, be sure to consult the documentation.
+
+  To completely disable a check, just comment it out or delete it from the file.
+
+  Finally, it is worth reading the documentation.
+
+-->
+
+<module name="Checker">
+    <!--
+        If you set the basedir property below, then all reported file
+        names will be relative to the specified directory. See
+        http://checkstyle.sourceforge.net/5.x/config.html#Checker
+
+        <property name="basedir" value="${basedir}"/>
+    -->
+
+    <property name="fileExtensions" value="java, properties, xml"/>
+
+    <!-- Checks that a package-info.java file exists for each package.     -->
+    <!-- See http://checkstyle.sourceforge.net/config_javadoc.html#JavadocPackage -->
+    <!--<module name="JavadocPackage"/>-->
+
+    <!-- Checks whether files end with a new line.                        -->
+    <!-- See http://checkstyle.sourceforge.net/config_misc.html#NewlineAtEndOfFile -->
+    <module name="NewlineAtEndOfFile"/>
+
+    <!-- Checks that property files contain the same keys.         -->
+    <!-- See http://checkstyle.sourceforge.net/config_misc.html#Translation -->
+    <module name="Translation"/>
+
+    <!-- Checks for Size Violations.                    -->
+    <!-- See http://checkstyle.sourceforge.net/config_sizes.html -->
+    <module name="FileLength"/>
+
+    <!-- Checks for whitespace                               -->
+    <!-- See http://checkstyle.sourceforge.net/config_whitespace.html -->
+    <module name="FileTabCharacter"/>
+
+    <!-- Miscellaneous other checks.                   -->
+    <!-- See http://checkstyle.sourceforge.net/config_misc.html -->
+    <module name="RegexpSingleline">
+       <property name="format" value="\s+$"/>
+       <property name="minimum" value="0"/>
+       <property name="maximum" value="0"/>
+       <property name="message" value="Line has trailing spaces."/>
+    </module>
+
+    <!-- Checks for Headers                                -->
+    <!-- See http://checkstyle.sourceforge.net/config_header.html   -->
+    <!-- <module name="Header"> -->
+    <!--   <property name="headerFile" value="${checkstyle.header.file}"/> -->
+    <!--   <property name="fileExtensions" value="java"/> -->
+    <!-- </module> -->
+
+    <module name="TreeWalker">
+
+        <!-- Checks for Javadoc comments.                     -->
+        <!-- See http://checkstyle.sourceforge.net/config_javadoc.html -->
+        <!--<module name="JavadocMethod">-->
+            <!--<property name="excludeScope" value="private"/>-->
+        <!--</module>-->
+        <module name="JavadocType">
+            <property name="excludeScope" value="private"/>
+        </module>
+        <module name="JavadocVariable">
+            <property name="excludeScope" value="private"/>
+        </module>
+        <module name="JavadocStyle"/>
+
+        <!-- Checks for Naming Conventions.                  -->
+        <!-- See http://checkstyle.sourceforge.net/config_naming.html -->
+        <module name="ConstantName"/>
+        <module name="LocalFinalVariableName"/>
+        <module name="LocalVariableName"/>
+        <module name="MemberName"/>
+        <module name="MethodName"/>
+        <module name="PackageName"/>
+        <module name="ParameterName"/>
+        <module name="StaticVariableName"/>
+        <module name="TypeName"/>
+
+        <!-- Checks for imports                              -->
+        <!-- See http://checkstyle.sourceforge.net/config_import.html -->
+        <module name="AvoidStarImport"/>
+        <module name="IllegalImport"/> <!-- defaults to sun.* packages -->
+        <module name="RedundantImport"/>
+        <module name="UnusedImports">
+            <property name="processJavadoc" value="false"/>
+        </module>
+
+        <!-- Checks for Size Violations.                    -->
+        <!-- See http://checkstyle.sourceforge.net/config_sizes.html -->
+        <module name="LineLength">
+            <property name="max" value="120"/>
+        </module>
+        <module name="MethodLength"/>
+        <module name="ParameterNumber"/>
+
+        <!-- Checks for whitespace                               -->
+        <!-- See http://checkstyle.sourceforge.net/config_whitespace.html -->
+        <module name="EmptyForIteratorPad"/>
+        <module name="GenericWhitespace"/>
+        <module name="MethodParamPad"/>
+        <module name="NoWhitespaceAfter"/>
+        <module name="NoWhitespaceBefore"/>
+        <module name="OperatorWrap">
+            <property name="option" value="eol"/>
+        </module>
+        <module name="ParenPad"/>
+        <module name="TypecastParenPad"/>
+        <module name="WhitespaceAfter"/>
+        <module name="WhitespaceAround"/>
+
+        <!-- Modifier Checks                                    -->
+        <!-- See http://checkstyle.sourceforge.net/config_modifiers.html -->
+        <module name="ModifierOrder"/>
+        <module name="RedundantModifier"/>
+
+        <!-- Checks for blocks. You know, those {}'s         -->
+        <!-- See http://checkstyle.sourceforge.net/config_blocks.html -->
+        <module name="AvoidNestedBlocks"/>
+        <module name="EmptyBlock"/>
+        <module name="LeftCurly"/>
+        <module name="NeedBraces"/>
+        <module name="RightCurly"/>
+
+        <!-- Checks for common coding problems               -->
+        <!-- See http://checkstyle.sourceforge.net/config_coding.html -->
+        <module name="AvoidInlineConditionals"/>
+        <module name="EmptyStatement"/>
+        <module name="EqualsHashCode"/>
+        <!-- <module name="HiddenField"/> -->
+        <module name="IllegalInstantiation"/>
+        <module name="InnerAssignment"/>
+        <!--<module name="MagicNumber"/>-->
+        <module name="MissingSwitchDefault"/>
+        <module name="SimplifyBooleanExpression"/>
+        <module name="SimplifyBooleanReturn"/>
+
+        <!-- Checks for class design                         -->
+        <!-- See http://checkstyle.sourceforge.net/config_design.html -->
+        <!--<module name="DesignForExtension"/>-->
+        <module name="FinalClass"/>
+        <module name="HideUtilityClassConstructor"/>
+        <module name="InterfaceIsType"/>
+        <!--<module name="VisibilityModifier"/>-->
+
+        <!-- Miscellaneous other checks.                   -->
+        <!-- See http://checkstyle.sourceforge.net/config_misc.html -->
+        <module name="ArrayTypeStyle"/>
+        <module name="FinalParameters"/>
+        <!--<module name="TodoComment"/>-->
+        <module name="UpperEll"/>
+
+    </module>
+
+</module>
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
new file mode 100644
index 0000000..86eda33
--- /dev/null
+++ b/config/checkstyle/checkstyle.xml
@@ -0,0 +1,185 @@
+<?xml version="1.0"?>
+<!DOCTYPE module PUBLIC
+          "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
+          "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+
+<!--
+
+  Based on http://checkstyle.sourceforge.net/sun_style.html, the
+  Checkstyle configuration that checks the sun coding conventions from:
+
+    - the Java Language Specification at
+      http://java.sun.com/docs/books/jls/second_edition/html/index.html
+
+    - the Sun Code Conventions at http://java.sun.com/docs/codeconv/
+
+    - the Javadoc guidelines at
+      http://java.sun.com/j2se/javadoc/writingdoccomments/index.html
+
+    - the JDK Api documentation http://java.sun.com/j2se/docs/api/index.html
+
+    - some best practices
+
+  Checkstyle is very configurable. Be sure to read the documentation at
+  http://checkstyle.sourceforge.net (or in your downloaded distribution).
+
+  Most Checks are configurable, be sure to consult the documentation.
+
+  To completely disable a check, just comment it out or delete it from the file.
+
+  Finally, it is worth reading the documentation.
+
+-->
+
+<module name="Checker">
+    <!--
+        If you set the basedir property below, then all reported file
+        names will be relative to the specified directory. See
+        http://checkstyle.sourceforge.net/5.x/config.html#Checker
+
+        <property name="basedir" value="${basedir}"/>
+    -->
+
+    <property name="fileExtensions" value="java, properties, xml"/>
+
+    <!-- Checks that a package-info.java file exists for each package.     -->
+    <!-- See http://checkstyle.sourceforge.net/config_javadoc.html#JavadocPackage -->
+    <module name="JavadocPackage"/>
+
+    <!-- Checks whether files end with a new line.                        -->
+    <!-- See http://checkstyle.sourceforge.net/config_misc.html#NewlineAtEndOfFile -->
+    <module name="NewlineAtEndOfFile"/>
+
+    <!-- Checks that property files contain the same keys.         -->
+    <!-- See http://checkstyle.sourceforge.net/config_misc.html#Translation -->
+    <module name="Translation"/>
+
+    <!-- Checks for Size Violations.                    -->
+    <!-- See http://checkstyle.sourceforge.net/config_sizes.html -->
+    <module name="FileLength"/>
+
+    <!-- Checks for whitespace                               -->
+    <!-- See http://checkstyle.sourceforge.net/config_whitespace.html -->
+    <module name="FileTabCharacter"/>
+
+    <!-- Miscellaneous other checks.                   -->
+    <!-- See http://checkstyle.sourceforge.net/config_misc.html -->
+    <module name="RegexpSingleline">
+       <property name="format" value="\s+$"/>
+       <property name="minimum" value="0"/>
+       <property name="maximum" value="0"/>
+       <property name="message" value="Line has trailing spaces."/>
+    </module>
+
+    <!-- Checks for Headers                                -->
+    <!-- See http://checkstyle.sourceforge.net/config_header.html   -->
+    <!-- <module name="Header"> -->
+    <!--   <property name="headerFile" value="${checkstyle.header.file}"/> -->
+    <!--   <property name="fileExtensions" value="java"/> -->
+    <!-- </module> -->
+
+    <module name="TreeWalker">
+
+        <!-- Checks for Javadoc comments.                     -->
+        <!-- See http://checkstyle.sourceforge.net/config_javadoc.html -->
+        <module name="JavadocMethod">
+            <property name="excludeScope" value="private"/>
+        </module>
+        <module name="JavadocType">
+            <property name="excludeScope" value="private"/>
+        </module>
+        <module name="JavadocVariable">
+            <property name="excludeScope" value="private"/>
+        </module>
+        <module name="JavadocStyle"/>
+
+        <!-- Checks for Naming Conventions.                  -->
+        <!-- See http://checkstyle.sourceforge.net/config_naming.html -->
+        <module name="ConstantName"/>
+        <module name="LocalFinalVariableName"/>
+        <module name="LocalVariableName"/>
+        <module name="MemberName"/>
+        <module name="MethodName"/>
+        <module name="PackageName"/>
+        <module name="ParameterName"/>
+        <module name="StaticVariableName"/>
+        <module name="TypeName"/>
+
+        <!-- Checks for imports                              -->
+        <!-- See http://checkstyle.sourceforge.net/config_import.html -->
+        <module name="AvoidStarImport"/>
+        <module name="IllegalImport"/> <!-- defaults to sun.* packages -->
+        <module name="RedundantImport"/>
+        <module name="UnusedImports">
+            <property name="processJavadoc" value="false"/>
+        </module>
+
+        <!-- Checks for Size Violations.                    -->
+        <!-- See http://checkstyle.sourceforge.net/config_sizes.html -->
+        <module name="LineLength">
+            <property name="max" value="120"/>
+        </module>
+        <module name="MethodLength"/>
+        <module name="ParameterNumber"/>
+
+        <!-- Checks for whitespace                               -->
+        <!-- See http://checkstyle.sourceforge.net/config_whitespace.html -->
+        <module name="EmptyForIteratorPad"/>
+        <module name="GenericWhitespace"/>
+        <module name="MethodParamPad"/>
+        <module name="NoWhitespaceAfter"/>
+        <module name="NoWhitespaceBefore"/>
+        <module name="OperatorWrap">
+            <property name="option" value="eol"/>
+        </module>
+        <module name="ParenPad"/>
+        <module name="TypecastParenPad"/>
+        <module name="WhitespaceAfter"/>
+        <module name="WhitespaceAround"/>
+
+        <!-- Modifier Checks                                    -->
+        <!-- See http://checkstyle.sourceforge.net/config_modifiers.html -->
+        <module name="ModifierOrder"/>
+        <module name="RedundantModifier"/>
+
+        <!-- Checks for blocks. You know, those {}'s         -->
+        <!-- See http://checkstyle.sourceforge.net/config_blocks.html -->
+        <module name="AvoidNestedBlocks"/>
+        <module name="EmptyBlock"/>
+        <module name="LeftCurly"/>
+        <module name="NeedBraces"/>
+        <module name="RightCurly"/>
+
+        <!-- Checks for common coding problems               -->
+        <!-- See http://checkstyle.sourceforge.net/config_coding.html -->
+        <module name="AvoidInlineConditionals"/>
+        <module name="EmptyStatement"/>
+        <module name="EqualsHashCode"/>
+        <!-- <module name="HiddenField"/> -->
+        <module name="IllegalInstantiation"/>
+        <module name="InnerAssignment"/>
+        <module name="MagicNumber"/>
+        <module name="MissingSwitchDefault"/>
+        <module name="SimplifyBooleanExpression"/>
+        <module name="SimplifyBooleanReturn"/>
+
+        <!-- Checks for class design                         -->
+        <!-- See http://checkstyle.sourceforge.net/config_design.html -->
+        <!--<module name="DesignForExtension"/>-->
+        <module name="FinalClass"/>
+        <module name="HideUtilityClassConstructor"/>
+        <module name="InterfaceIsType"/>
+        <module name="VisibilityModifier">
+            <property name="publicMemberPattern" value="^(on|sent).*$"/>
+        </module>
+
+        <!-- Miscellaneous other checks.                   -->
+        <!-- See http://checkstyle.sourceforge.net/config_misc.html -->
+        <module name="ArrayTypeStyle"/>
+        <module name="FinalParameters"/>
+        <!--<module name="TodoComment"/>-->
+        <module name="UpperEll"/>
+
+    </module>
+
+</module>
diff --git a/src/main/java/com/intel/jndn/mock/MockFace.java b/src/main/java/com/intel/jndn/mock/MockFace.java
index 89a9c97..8980fa7 100644
--- a/src/main/java/com/intel/jndn/mock/MockFace.java
+++ b/src/main/java/com/intel/jndn/mock/MockFace.java
@@ -13,7 +13,12 @@
  */
 package com.intel.jndn.mock;
 
-import net.named_data.jndn.*;
+import net.named_data.jndn.ControlParameters;
+import net.named_data.jndn.ControlResponse;
+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.encoding.EncodingException;
 import net.named_data.jndn.encoding.TlvWireFormat;
 import net.named_data.jndn.encoding.tlv.Tlv;
@@ -29,57 +34,132 @@
 import java.util.logging.Logger;
 
 /**
- * A client-side face for unit testing
+ * A client-side face for unit testing.
  *
  * @author Alexander Afanasyev, <aa@cs.ucla.edu>
  * @author Andrew Brown <andrew.brown@intel.com>
  */
 public class MockFace extends Face {
+  /**
+   * 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 final List<Interest> sentInterests = new ArrayList<>();
 
   /**
-   * API for handling {@link Interest}s
+   * 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 final List<Data> sentData = new ArrayList<>();
+
+  /**
+   * Emits whenever an Interest is sent.
+   * <p/>
+   * After .expressInterest, .processEvents must be called before this signal
+   * would be emitted.
+   */
+  public final List<SignalOnSendInterest> onSendInterest = new ArrayList<>();
+
+  /**
+   * Emits whenever a Data packet is sent.
+   * <p/>
+   * After .putData, .processEvents must be called before this signal would be
+   * emitted.
+   */
+  public final List<SignalOnSendData> onSendData = new ArrayList<>();
+
+  private static final Logger LOGGER = Logger.getLogger(MockFace.class.getName());
+  private MockFaceTransport transport;
+  private KeyChain keyChain;
+
+  /////////////////////////////////////////////////////////////////////////////
+
+  /**
+   * API for handling {@link Interest}s.
    */
   public interface SignalOnSendInterest {
-    void emit(Interest interest) throws EncodingException, SecurityException;
+    /**
+     * Callback called when an Interest is sent out through face (towards NFD).
+     * @param interest interest being sent out
+     */
+    void emit(final Interest interest);
   }
 
   /**
-   * API for handling {@link Data}s
+   * API for handling {@link Data}s.
    */
   public interface SignalOnSendData {
-    void emit(Data data);
+    /**
+     * Callback called when a Data is sent out through face (towards NFD).
+     *
+     * @param data data being sent out
+     */
+    void emit(final Data data);
   }
 
   /**
-   * Options for MockFace
+   * Options for MockFace.
    */
   public static class Options {
+    private boolean enablePacketLogging = false;
+    private boolean enableRegistrationReply = false;
 
     /**
-     * If true, packets sent out of MockFace will be appended to a container
+     * @return true if packet logging is enabled
      */
-    boolean enablePacketLogging = false;
+    public boolean isEnablePacketLogging() {
+      return enablePacketLogging;
+    }
 
     /**
-     * If true, prefix registration command will be automatically replied with a
-     * successful response
+     * Enable/disable packet logging.
+     *
+     * @param enablePacketLogging If true, packets sent out of MockFace will be appended to a container
+     * @return this
      */
-    boolean enableRegistrationReply = false;
+    public Options setEnablePacketLogging(final boolean enablePacketLogging) {
+      this.enablePacketLogging = enablePacketLogging;
+      return this;
+    }
+
+    /**
+     * @return true if prefix registration mocking is enabled
+     */
+    public boolean isEnableRegistrationReply() {
+      return enableRegistrationReply;
+    }
+
+    /**
+     * Enable/disable prefix registration mocking.
+     *
+     * @param enableRegistrationReply If true, prefix registration command will be automatically replied with a
+     *                                successful response
+     * @return this
+     */
+    public Options setEnableRegistrationReply(final boolean enableRegistrationReply) {
+      this.enableRegistrationReply = enableRegistrationReply;
+      return this;
+    }
   }
 
   /**
-   * Default options
+   * Default options.
    */
-  public static final Options DEFAULT_OPTIONS = new Options() {
-    {
-      enablePacketLogging = true;
-      enableRegistrationReply = true;
-    }
-  };
+  public static final Options DEFAULT_OPTIONS = new Options()
+                                                  .setEnablePacketLogging(true)
+                                                  .setEnableRegistrationReply(true);
 
   /**
    * Create MockFace that logs packets in {@link #sentInterests} and
-   * {@link #sentData} and emulates NFD prefix registration
+   * {@link #sentData} and emulates NFD prefix registration.
    *
    * @throws SecurityException should not be thrown by this test class
    */
@@ -88,7 +168,7 @@
   }
 
   /**
-   * Create MockFace with the specified options
+   * Create MockFace with the specified options.
    * <p>
    * To create Face that does not log packets:
    * <pre>
@@ -105,7 +185,7 @@
    *
    * @param options see {@link Options}
    */
-  public MockFace(Options options) {
+  public MockFace(final Options options) {
     super(new MockFaceTransport(), null);
     transport = (MockFaceTransport) node_.getTransport();
     transport.setOnSendBlock(new OnIncomingPacket());
@@ -118,111 +198,133 @@
       throw new Error(ex);
     }
 
-    if (options.enablePacketLogging) {
+    if (options.isEnablePacketLogging()) {
       onSendInterest.add(new SignalOnSendInterest() {
         @Override
-        public void emit(Interest interest) {
+        public void emit(final Interest interest) {
           sentInterests.add(interest);
         }
       });
 
       onSendData.add(new SignalOnSendData() {
         @Override
-        public void emit(Data data) {
+        public void emit(final Data data) {
           sentData.add(data);
         }
       });
     }
 
-    if (options.enableRegistrationReply) {
+    if (options.isEnableRegistrationReply()) {
       onSendInterest.add(new OnPrefixRegistration());
     }
   }
 
   /**
-   * Route incoming packets to the correct callbacks
+   * Route incoming packets to the correct callbacks.
    */
   private class OnIncomingPacket implements MockFaceTransport.OnSendBlockSignal {
-
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void emit(ByteBuffer buffer) throws EncodingException, SecurityException {
+    public void emit(final ByteBuffer buffer) {
       // @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());
+      try {
+        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 (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);
+            for (SignalOnSendData signal : onSendData) {
+              signal.emit(data);
+            }
           }
+        } else {
+          LOGGER.info("Received an unknown packet");
         }
-      } else {
-        LOGGER.info("Received an unknown packet");
+      } catch (EncodingException e) {
+        LOGGER.log(Level.INFO, "Failed to decode incoming packet", e);
       }
     }
   }
 
   /**
-   * Handle prefix registration requests
+   * Handle prefix registration requests.
    */
   private class OnPrefixRegistration implements SignalOnSendInterest {
+    private static final int STATUS_CODE_OK = 200;
+    private static final int CONTROL_PARAMETERS_NAME_OFFSET = -5;
+    private static final int CONTROL_COMMAND_NAME_OFFSET = 3;
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void emit(Interest interest) throws EncodingException, SecurityException {
+    public void emit(final Interest interest) {
       final Name localhostRegistration = new Name("/localhost/nfd/rib");
-      if (!interest.getName().getPrefix(3).equals(localhostRegistration)) {
+      if (!interest.getName().getPrefix(localhostRegistration.size()).equals(localhostRegistration) ||
+          interest.getName().get(CONTROL_COMMAND_NAME_OFFSET).toString().equals("register")) {
         return;
       }
 
       ControlParameters params = new ControlParameters();
-      params.wireDecode(interest.getName().get(-5).getValue());
-      params.setFaceId(1);
-      params.setOrigin(0);
-
-      if ("register".equals(interest.getName().get(3).toString())) {
+      try {
+        params.wireDecode(interest.getName().get(CONTROL_PARAMETERS_NAME_OFFSET).getValue());
+        params.setFaceId(1);
+        params.setOrigin(0);
         params.setCost(0);
+      } catch (EncodingException e) {
+        throw new IllegalArgumentException("", e);
       }
 
       ControlResponse response = new ControlResponse();
-      response.setStatusCode(200);
+      response.setStatusCode(STATUS_CODE_OK);
       response.setStatusText("OK");
       response.setBodyAsControlParameters(params);
 
       Data data = new Data();
       data.setName(interest.getName());
       data.setContent(response.wireEncode());
-      keyChain.sign(data);
+      try {
+        keyChain.sign(data);
+      } catch (SecurityException e) {
+        LOGGER.log(Level.FINE, "MockKeyChain signing failed", e);
+      }
 
-      receive(data);
+      try {
+        receive(data);
+      } catch (EncodingException e) {
+        LOGGER.log(Level.INFO, "Failed to encode ControlReposnse data", e);
+      }
     }
   }
 
   /**
-   * Mock reception of the Interest packet on the Face (from transport)
+   * Mock reception of the Interest packet on the Face (from transport).
    *
    * @param interest the mock-remote interest to add to the PIT
    * @throws EncodingException if packet encoding fails (it should not)
    */
-  public void receive(Interest interest) throws EncodingException {
+  public void receive(final Interest interest) throws EncodingException {
     transport.receive(interest.wireEncode().buf());
   }
 
   /**
-   * Mock reception of the Data packet on the Face (from transport)
+   * Mock reception of the Data packet on the Face (from transport).
    *
    * @param data the mock-remote data to add to the CS
    * @throws EncodingException if packet encoding fails (it should not)
    */
-  public void receive(Data data) throws EncodingException {
+  public void receive(final Data data) throws EncodingException {
     transport.receive(data.wireEncode().buf());
   }
 
@@ -232,44 +334,4 @@
   public Transport getTransport() {
     return transport;
   }
-
-  /**
-   * 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 final List<Interest> sentInterests = new ArrayList<>();
-
-  /**
-   * 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 final List<Data> sentData = new ArrayList<>();
-
-  /**
-   * Emits whenever an Interest is sent
-   * <p>
-   * After .expressInterest, .processEvents must be called before this signal
-   * would be emitted.
-   */
-  public final List<SignalOnSendInterest> onSendInterest = new ArrayList<>();
-
-  /**
-   * Emits whenever a Data packet is sent
-   * <p>
-   * After .putData, .processEvents must be called before this signal would be
-   * emitted.
-   */
-  public final List<SignalOnSendData> onSendData = new ArrayList<>();
-
-  private static final Logger LOGGER = Logger.getLogger(MockFace.class.getName());
-  private MockFaceTransport transport;
-  private KeyChain keyChain;
 }
diff --git a/src/main/java/com/intel/jndn/mock/MockKeyChain.java b/src/main/java/com/intel/jndn/mock/MockKeyChain.java
index b367808..1a0bafb 100644
--- a/src/main/java/com/intel/jndn/mock/MockKeyChain.java
+++ b/src/main/java/com/intel/jndn/mock/MockKeyChain.java
@@ -21,16 +21,18 @@
 import net.named_data.jndn.security.identity.MemoryPrivateKeyStorage;
 import net.named_data.jndn.security.identity.PrivateKeyStorage;
 import net.named_data.jndn.security.policy.SelfVerifyPolicyManager;
+import net.named_data.jndn.security.SecurityException;
 
 /**
- * Create an in-memory key chain for use in NDN-related tests
+ * Create an in-memory key chain for use in NDN-related tests.
  *
  * @author Andrew Brown <andrew.brown@intel.com>
  */
-public class MockKeyChain {
-
+public final class MockKeyChain {
+  /**
+   * Do not allow instances of this key chain.
+   */
   private MockKeyChain() {
-    // do not allow instances of this key chain
   }
 
   /**
@@ -39,9 +41,9 @@
    * @param name the name of the default identity to create
    * @return an in-memory {@link KeyChain} configured with the name as the
    * default identity
-   * @throws net.named_data.jndn.security.SecurityException
+   * @throws SecurityException if failed to create mock identity
    */
-  public static KeyChain configure(Name name) throws net.named_data.jndn.security.SecurityException {
+  public static KeyChain configure(final Name name) throws SecurityException {
     PrivateKeyStorage keyStorage = new MemoryPrivateKeyStorage();
     IdentityStorage identityStorage = new MemoryIdentityStorage();
     KeyChain keyChain = new KeyChain(new IdentityManager(identityStorage, keyStorage),
diff --git a/src/main/java/com/intel/jndn/mock/MockTransport.java b/src/main/java/com/intel/jndn/mock/MockTransport.java
index 1fd935d..df437e0 100644
--- a/src/main/java/com/intel/jndn/mock/MockTransport.java
+++ b/src/main/java/com/intel/jndn/mock/MockTransport.java
@@ -22,7 +22,6 @@
 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.security.SecurityException;
 import net.named_data.jndn.transport.Transport;
 
 /**
@@ -33,21 +32,32 @@
  * @author Andrew Brown <andrew.brown@intel.com>
  */
 class MockFaceTransport extends Transport {
+  private OnSendBlockSignal onSendBlock;
+  private static final Logger LOGGER = Logger.getLogger(MockFaceTransport.class.getName());
+  private boolean connected;
+  private ElementReader elementReader;
+  private final List<ByteBuffer> receiveBuffer = new LinkedList<>();
+
+  /////////////////////////////////////////////////////////////////////////////
 
   /**
-   * API for buffer handling
+   * API for buffer handling.
    */
   public interface OnSendBlockSignal {
-    void emit(ByteBuffer buffer) throws EncodingException, SecurityException;
+    /**
+     * Callback called when an ByteBuffer is sent (from NFD towards app).
+     *
+     * @param buffer buffer being sent thourgh face (from NFD towards app)
+     */
+    void emit(ByteBuffer buffer);
   }
 
   /**
-   * Receive some bytes to add to the mock socket
+   * Receive some bytes to add to the mock socket.
    *
    * @param block the byte buffer
-   * @throws EncodingException
    */
-  public void receive(ByteBuffer block) throws EncodingException {
+  public void receive(final ByteBuffer block) {
     synchronized (receiveBuffer) {
       receiveBuffer.add(block.duplicate());
     }
@@ -57,7 +67,7 @@
    * {@inheritDoc}
    */
   @Override
-  public boolean isLocal(Transport.ConnectionInfo connectionInfo) {
+  public boolean isLocal(final Transport.ConnectionInfo connectionInfo) {
     return true;
   }
 
@@ -73,8 +83,8 @@
    * {@inheritDoc}
    */
   @Override
-  public void connect(Transport.ConnectionInfo connectionInfo,
-          ElementListener elementListener, Runnable onConnected) {
+  public void connect(final Transport.ConnectionInfo connectionInfo,
+                      final ElementListener elementListener, final Runnable onConnected) {
     LOGGER.fine("Connecting...");
     connected = true;
     elementReader = new ElementReader(elementListener);
@@ -87,16 +97,10 @@
    * {@inheritDoc}
    */
   @Override
-  public void send(ByteBuffer data) throws IOException {
-    LOGGER.log(Level.FINE, "Sending {0} bytes", data.capacity() - data.position());
+  public void send(final ByteBuffer buffer) throws IOException {
+    LOGGER.log(Level.FINE, "Sending {0} bytes", buffer.capacity() - buffer.position());
 
-    try {
-      onSendBlock.emit(data);
-    } catch (EncodingException e) {
-      LOGGER.log(Level.WARNING, "Failed to decode packet", e);
-    } catch (SecurityException e) {
-      LOGGER.log(Level.WARNING, "Failed signature", e);
-    }
+    onSendBlock.emit(buffer);
   }
 
   /**
@@ -144,13 +148,7 @@
    * ideally this would be hidden completely but the super() call in MockFace
    * requires this callback to be set after the parent constructor is called
    */
-  public void setOnSendBlock(OnSendBlockSignal onSendBlock) {
+  public void setOnSendBlock(final OnSendBlockSignal onSendBlock) {
     this.onSendBlock = onSendBlock;
   }
-
-  private OnSendBlockSignal onSendBlock;
-  private static final Logger LOGGER = Logger.getLogger(MockFaceTransport.class.getName());
-  private boolean connected;
-  private ElementReader elementReader;
-  private final List<ByteBuffer> receiveBuffer = new LinkedList<>();
 }
diff --git a/src/main/java/com/intel/jndn/mock/package-info.java b/src/main/java/com/intel/jndn/mock/package-info.java
new file mode 100644
index 0000000..21dcda2
--- /dev/null
+++ b/src/main/java/com/intel/jndn/mock/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * NDN Face mocking classes.
+ */
+package com.intel.jndn.mock;
diff --git a/src/test/java/com/intel/jndn/mock/MockFaceTest.java b/src/test/java/com/intel/jndn/mock/MockFaceTest.java
index 32a8d35..7c8bbc9 100644
--- a/src/test/java/com/intel/jndn/mock/MockFaceTest.java
+++ b/src/test/java/com/intel/jndn/mock/MockFaceTest.java
@@ -13,22 +13,43 @@
  */
 package com.intel.jndn.mock;
 
-import java.io.IOException;
-import java.util.logging.Logger;
-
-import net.named_data.jndn.*;
+import net.named_data.jndn.Data;
+import net.named_data.jndn.Face;
+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.OnInterestCallback;
+import net.named_data.jndn.OnRegisterFailed;
+import net.named_data.jndn.OnRegisterSuccess;
+import net.named_data.jndn.OnTimeout;
 import net.named_data.jndn.encoding.EncodingException;
 import net.named_data.jndn.security.SecurityException;
 import net.named_data.jndn.util.Blob;
 import org.junit.Before;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
+import java.io.IOException;
+import java.util.logging.Logger;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 /**
- * Test MockFace functionality
+ * Test MockFace functionality.
  */
 public class MockFaceTest {
+  private static final Logger LOG = Logger.getLogger(MockFaceTest.class.getName());
+  private MockFace face;
+  private int counter;
+  private Data recvData = null;
+  private boolean isTimeout = false;
+  private Exception exception = null;
+
+  /////////////////////////////////////////////////////////////////////////////
 
   @Before
   public void setup() throws SecurityException {
@@ -96,11 +117,12 @@
     }
     final State state = new State();
 
-    logger.info("Register prefix: /test/with/handlers");
+    LOG.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());
+      public void onInterest(final Name prefix, final Interest interest, final Face face, final long interestFilterId,
+                             final InterestFilter filter) {
+        LOG.info("Received interest, responding: " + interest.getName().toUri());
         Data response = new Data(new Name("/test/with/handlers"));
         response.setContent(new Blob("..."));
         try {
@@ -112,15 +134,15 @@
       }
     }, new OnRegisterFailed() {
       @Override
-      public void onRegisterFailed(Name prefix) {
-        logger.info("Prefix registration fails: " + prefix);
+      public void onRegisterFailed(final Name prefix) {
+        LOG.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);
+      public void onRegisterSuccess(final Name prefix, final long registeredPrefixId) {
+        LOG.info("Prefix registration succeed: " + prefix);
         state.regSucceed = true;
         counter++;
       }
@@ -162,13 +184,13 @@
     // connect transport
     face.registerPrefix(new Name("/fake/prefix"), (OnInterestCallback) null, new OnRegisterFailed() {
       @Override
-      public void onRegisterFailed(Name prefix) {
+      public void onRegisterFailed(final Name prefix) {
         state.regFailed = true;
         counter++;
       }
     }, new OnRegisterSuccess() {
       @Override
-      public void onRegisterSuccess(Name prefix, long registeredPrefixId) {
+      public void onRegisterSuccess(final Name prefix, final long registeredPrefixId) {
         state.regSucceed = true;
         counter++;
       }
@@ -177,7 +199,8 @@
     // set filter
     face.setInterestFilter(new InterestFilter("/a/b"), new OnInterestCallback() {
       @Override
-      public void onInterest(Name prefix, Interest interest, Face face, long interestFilterId, InterestFilter filter) {
+      public void onInterest(final Name prefix, final Interest interest, final Face face, final long interestFilterId,
+                             final InterestFilter filter) {
         counter++;
       }
     });
@@ -191,9 +214,66 @@
     assertFalse(state.regFailed);
   }
 
+  @Test
+  public void testMockWithoutPacketLogging() throws Exception {
+    face = new MockFace(new MockFace.Options().setEnablePacketLogging(false));
+
+    // make request
+    expressInterest("/test/with/responses");
+    run(2);
+
+    assertEquals(0, face.sentInterests.size());
+  }
+
+  @Test
+  public void testMockWithoutMockRegistrationReply() throws Exception {
+    face = new MockFace(new MockFace.Options().setEnableRegistrationReply(false));
+
+    class State {
+      boolean regFailed = false;
+      boolean regSucceed = false;
+    }
+    final State state = new State();
+
+    LOG.info("Register prefix: /test/with/handlers");
+    face.registerPrefix(new Name("/test/with/handlers"), new OnInterestCallback() {
+      @Override
+      public void onInterest(final Name prefix, final Interest interest, final Face face, final long interestFilterId,
+                             final InterestFilter filter) {
+        LOG.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(final Name prefix) {
+        LOG.info("Prefix registration fails: " + prefix);
+        state.regFailed = true;
+        counter++;
+      }
+    }, new OnRegisterSuccess() {
+      @Override
+      public void onRegisterSuccess(final Name prefix, final long registeredPrefixId) {
+        LOG.info("Prefix registration succeed: " + prefix);
+        state.regSucceed = true;
+        counter++;
+      }
+    });
+
+    run(100, 1);
+    assertFalse(state.regSucceed);
+    assertTrue(state.regFailed);
+  }
+
   /////////////////////////////////////////////////////////////////////////////
 
-  private void run(int limit, int maxCounter) throws IOException, EncodingException, InterruptedException {
+  private void run(final int limit, final int maxCounter) throws IOException, EncodingException, InterruptedException {
     // process face until a response is received
     int allowedLoops = limit;
     while (counter < maxCounter && allowedLoops > 0) {
@@ -202,36 +282,27 @@
       Thread.sleep(100);
     }
   }
-  
-  private void run(int limit) throws IOException, EncodingException, InterruptedException {
+
+  private void run(final int limit) throws IOException, EncodingException, InterruptedException {
     run(limit, 1);
   }
 
-  private void expressInterest(String name) throws IOException {
-    logger.info("Express interest: " + name);
+  private void expressInterest(final String name) throws IOException {
+    LOG.info("Express interest: " + name);
     face.expressInterest(new Interest(new Name(name)).setInterestLifetimeMilliseconds(1000), new OnData() {
       @Override
-      public void onData(Interest interest, Data data) {
+      public void onData(final Interest interest, final Data data) {
         counter++;
-        logger.fine("Received data");
+        LOG.fine("Received data");
         recvData = data;
       }
     }, new OnTimeout() {
       @Override
-      public void onTimeout(Interest interest) {
-        logger.fine("Received timeout");
+      public void onTimeout(final Interest interest) {
+        LOG.fine("Received timeout");
         counter++;
         isTimeout = true;
       }
     });
   }
-
-  /////////////////////////////////////////////////////////////////////////////
-
-  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/MockKeyChainTest.java b/src/test/java/com/intel/jndn/mock/MockKeyChainTest.java
index a599ae9..86d3b13 100644
--- a/src/test/java/com/intel/jndn/mock/MockKeyChainTest.java
+++ b/src/test/java/com/intel/jndn/mock/MockKeyChainTest.java
@@ -16,10 +16,12 @@
 import net.named_data.jndn.Name;
 import net.named_data.jndn.security.KeyChain;
 import org.junit.Test;
-import static org.junit.Assert.*;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 /**
- * Test MockKeyChain
+ * Test MockKeyChain.
  *
  * @author Andrew Brown <andrew.brown@intel.com>
  */