Polished BMv2 protocol module

- Improved and fixed typos in javadocs
- Added missing beta API annotations
- Refactored the default interpreter implementation

Change-Id: Ibfb21d31415d8f25cc67307f8bea2871951c9a8f
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2DefaultConfiguration.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2DefaultConfiguration.java
index 53a31b9..f047306 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2DefaultConfiguration.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2DefaultConfiguration.java
@@ -18,6 +18,7 @@
 
 import com.eclipsesource.json.JsonArray;
 import com.eclipsesource.json.JsonObject;
+import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import com.google.common.collect.ImmutableList;
@@ -36,6 +37,7 @@
 /**
  * Default implementation of a BMv2 configuration backed by a JSON object.
  */
+@Beta
 public final class Bmv2DefaultConfiguration implements Bmv2Configuration {
 
     private final JsonObject json;
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FlowRuleTranslator.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FlowRuleTranslator.java
index 3fb5b11..bc768d0 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FlowRuleTranslator.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FlowRuleTranslator.java
@@ -37,9 +37,9 @@
      *  <li> action: is built using the context interpreter
      *          {@link Bmv2Interpreter#mapTreatment(org.onosproject.net.flow.TrafficTreatment, Bmv2Configuration)
      *          treatment mapping function} or the flow rule
-     *          {@link org.onosproject.bmv2.api.runtime.Bmv2ExtensionTreatment} extension treatment} (if any).
-     *  <li> timeout: if the table supports timeout, use the same as the flow rule, otherwise none (i.e. permanent
-     *          entry).
+     *          {@link org.onosproject.bmv2.api.runtime.Bmv2ExtensionTreatment extension treatment} (if any).
+     *  <li> timeout: if the table supports timeout, use the same as the flow rule, otherwise none (i.e. returns a
+     *          permanent entry).
      * </ul>
      *
      * @param rule    a flow rule
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FlowRuleTranslatorException.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FlowRuleTranslatorException.java
index 49f999d..645ac33 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FlowRuleTranslatorException.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FlowRuleTranslatorException.java
@@ -16,10 +16,13 @@
 
 package org.onosproject.bmv2.api.context;
 
+import com.google.common.annotations.Beta;
+
 /**
  * BMv2 flow rule translator exception.
  */
-public class Bmv2FlowRuleTranslatorException extends Exception {
+@Beta
+public final class Bmv2FlowRuleTranslatorException extends Exception {
 
     public Bmv2FlowRuleTranslatorException(String msg) {
         super(msg);
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2InterpreterException.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2InterpreterException.java
index 5e774ad..7c143fc 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2InterpreterException.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2InterpreterException.java
@@ -16,10 +16,13 @@
 
 package org.onosproject.bmv2.api.context;
 
+import com.google.common.annotations.Beta;
+
 /**
  * A BMv2 interpreter exception.
  */
-public class Bmv2InterpreterException extends Exception {
+@Beta
+public final class Bmv2InterpreterException extends Exception {
 
     public Bmv2InterpreterException(String message) {
         super(message);
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2Action.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2Action.java
index 0f1983f..e05803c 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2Action.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2Action.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.bmv2.api.runtime;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
 import com.google.common.collect.Lists;
 import org.onlab.util.ImmutableByteSequence;
@@ -30,6 +31,7 @@
 /**
  * An action of a BMv2 match-action table entry.
  */
+@Beta
 public final class Bmv2Action {
 
     private final String name;
@@ -58,8 +60,7 @@
     }
 
     /**
-     * Returns an immutable view of the ordered list of parameters of this
-     * action.
+     * Returns an immutable view of the list of parameters of this action.
      *
      * @return list of byte sequence
      */
@@ -106,7 +107,7 @@
         }
 
         /**
-         * Set the action name.
+         * Sets the action name.
          *
          * @param actionName a string value
          * @return this
@@ -117,7 +118,7 @@
         }
 
         /**
-         * Add a parameter at the end of the parameters list.
+         * Adds a parameter at the end of the parameters list.
          *
          * @param parameter a ByteBuffer value
          * @return this
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2Device.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2Device.java
index bff414f..c3efce3 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2Device.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2Device.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.bmv2.api.runtime;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.Objects;
 import org.onosproject.net.DeviceId;
 
@@ -27,8 +28,9 @@
 import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
- * Representation of a BMv2 device.
+ * A BMv2 device.
  */
+@Beta
 public final class Bmv2Device {
 
     public static final String N_A = "n/a";
@@ -47,9 +49,9 @@
     /**
      * Creates a new BMv2 device object.
      *
-     * @param thriftServerHost the hostname / IP address of the Thrift runtime server running on the device
-     * @param thriftServerPort the port of the Thrift runtime server running on the device
-     * @param internalDeviceId the internal device ID number
+     * @param thriftServerHost the hostname or IP address of the Thrift RPC server running on the device
+     * @param thriftServerPort the listening port used by the device Thrift RPC server
+     * @param internalDeviceId the internal numeric device ID
      */
     public Bmv2Device(String thriftServerHost, int thriftServerPort, int internalDeviceId) {
         this.thriftServerHost = checkNotNull(thriftServerHost, "host cannot be null");
@@ -68,7 +70,7 @@
     }
 
     /**
-     * Returns the hostname (or IP address) of the Thrift runtime server running on the device.
+     * Returns the hostname or IP address of the Thrift RPC server running on the device.
      *
      * @return a string value
      */
@@ -77,7 +79,7 @@
     }
 
     /**
-     * Returns the port of the Thrift runtime server running on the device.
+     * Returns the listening port of the Thrift RPC server running on the device.
      *
      * @return an integer value
      */
@@ -102,7 +104,6 @@
      */
     public DeviceId asDeviceId() {
         try {
-            // TODO: include internalDeviceId number in the deviceId URI
             return DeviceId.deviceId(new URI(SCHEME, this.thriftServerHost + ":" + this.thriftServerPort,
                                              String.valueOf(this.internalDeviceId)));
         } catch (URISyntaxException e) {
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2DeviceAgent.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2DeviceAgent.java
index 4dc3c1a..c128aeb 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2DeviceAgent.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2DeviceAgent.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.bmv2.api.runtime;
 
+import com.google.common.annotations.Beta;
 import org.apache.commons.lang3.tuple.Pair;
 import org.onlab.util.ImmutableByteSequence;
 import org.onosproject.net.DeviceId;
@@ -26,6 +27,7 @@
 /**
  * An agent to control a BMv2 device.
  */
+@Beta
 public interface Bmv2DeviceAgent {
 
     /**
@@ -43,20 +45,20 @@
     boolean ping();
 
     /**
-     * Adds a new table entry.
+     * Adds a new table entry. If successful returns a table-specific identifier of the installed entry.
      *
-     * @param entry a table entry value
-     * @return table-specific entry ID
+     * @param entry a table entry
+     * @return a long value
      * @throws Bmv2RuntimeException if any error occurs
      */
     long addTableEntry(Bmv2TableEntry entry) throws Bmv2RuntimeException;
 
     /**
-     * Modifies an existing table entry by updating its action.
+     * Modifies an existing entry at by updating its action.
      *
-     * @param tableName string value of table name
-     * @param entryId   long value of entry ID
-     * @param action    an action value
+     * @param tableName a string value
+     * @param entryId   a long value
+     * @param action    an action
      * @throws Bmv2RuntimeException if any error occurs
      */
     void modifyTableEntry(String tableName, long entryId, Bmv2Action action) throws Bmv2RuntimeException;
@@ -64,16 +66,16 @@
     /**
      * Deletes currently installed entry.
      *
-     * @param tableName string value of table name
-     * @param entryId   long value of entry ID
+     * @param tableName a string value
+     * @param entryId   a long value
      * @throws Bmv2RuntimeException if any error occurs
      */
     void deleteTableEntry(String tableName, long entryId) throws Bmv2RuntimeException;
 
     /**
-     * Sets table default action.
+     * Sets a default action for the given table.
      *
-     * @param tableName string value of table name
+     * @param tableName a string value
      * @param action    an action value
      * @throws Bmv2RuntimeException if any error occurs
      */
@@ -97,7 +99,7 @@
     List<Bmv2ParsedTableEntry> getTableEntries(String tableName) throws Bmv2RuntimeException;
 
     /**
-     * Requests the device to transmit a given byte sequence over the given port.
+     * Requests the device to transmit a given packet over the given port.
      *
      * @param portNumber a port number
      * @param packet a byte sequence
@@ -106,7 +108,7 @@
     void transmitPacket(int portNumber, ImmutableByteSequence packet) throws Bmv2RuntimeException;
 
     /**
-     * Resets the state of the switch (e.g. delete all entries, etc.).
+     * Resets the state of the switch.
      *
      * @throws Bmv2RuntimeException if any error occurs
      */
@@ -121,7 +123,7 @@
     String dumpJsonConfig() throws Bmv2RuntimeException;
 
     /**
-     * Returns the md5 sum of the JSON-formatted model configuration currently used to process packets.
+     * Returns the MD5 sum of the JSON-formatted configuration currently used to process packets.
      *
      * @return a string value
      * @throws Bmv2RuntimeException if any error occurs
@@ -139,7 +141,7 @@
     Pair<Long, Long> readTableEntryCounter(String tableName, long entryId) throws Bmv2RuntimeException;
 
     /**
-     * Returns the counter values for a given counter and index.
+     * Returns the values of a given counter instance.
      *
      * @param counterName a counter name
      * @param index       an integer value
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExactMatchParam.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExactMatchParam.java
index d02dd2d..5b55d28 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExactMatchParam.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExactMatchParam.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.bmv2.api.runtime;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import org.onlab.util.ImmutableByteSequence;
@@ -23,8 +24,9 @@
 import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
- * Representation of a BMv2 exact match parameter.
+ * A BMv2 exact match parameter.
  */
+@Beta
 public final class Bmv2ExactMatchParam implements Bmv2MatchParam {
 
     private final ImmutableByteSequence value;
@@ -45,7 +47,7 @@
     }
 
     /**
-     * Return the byte sequence value matched by this parameter.
+     * Return the byte sequence matched by this parameter.
      *
      * @return an immutable byte buffer value
      */
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionSelector.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionSelector.java
index 10bc9dc..cd8ec77 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionSelector.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionSelector.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.bmv2.api.runtime;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import org.onlab.util.KryoNamespace;
@@ -31,6 +32,7 @@
 /**
  * Extension selector for BMv2 used as a wrapper for multiple BMv2 match parameters.
  */
+@Beta
 public final class Bmv2ExtensionSelector extends AbstractExtension implements ExtensionSelector {
 
     private final KryoNamespace appKryo = new KryoNamespace.Builder()
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionTreatment.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionTreatment.java
index b4c9790..b2f65f3 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionTreatment.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionTreatment.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.bmv2.api.runtime;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import org.onlab.util.KryoNamespace;
@@ -28,16 +29,27 @@
 /**
  * Extension treatment for BMv2 used as a wrapper for a {@link Bmv2Action}.
  */
+@Beta
 public final class Bmv2ExtensionTreatment extends AbstractExtension implements ExtensionTreatment {
 
     private final KryoNamespace appKryo = new KryoNamespace.Builder().build();
     private Bmv2Action action;
 
+    /**
+     * Creates a new extension treatment for the given BMv2 action.
+     *
+     * @param action an action
+     */
     public Bmv2ExtensionTreatment(Bmv2Action action) {
         this.action = action;
     }
 
-    public Bmv2Action getAction() {
+    /**
+     * Returns the action contained by this extension selector.
+     *
+     * @return an action
+     */
+    public Bmv2Action action() {
         return action;
     }
 
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2FlowRuleWrapper.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2FlowRuleWrapper.java
index a7b5b46..31bab78 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2FlowRuleWrapper.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2FlowRuleWrapper.java
@@ -16,15 +16,17 @@
 
 package org.onosproject.bmv2.api.runtime;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.Objects;
 import org.onosproject.net.flow.FlowRule;
 
 import java.util.Date;
 
 /**
- * A wrapper class for a ONOS flow rule installed on a BMv2 device.
+ * A wrapper for a ONOS flow rule installed on a BMv2 device.
  */
-public class Bmv2FlowRuleWrapper {
+@Beta
+public final class Bmv2FlowRuleWrapper {
 
     private final FlowRule rule;
     private final long entryId;
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2LpmMatchParam.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2LpmMatchParam.java
index ee75d3b..5f280b3 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2LpmMatchParam.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2LpmMatchParam.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.bmv2.api.runtime;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import org.onlab.util.ImmutableByteSequence;
@@ -24,8 +25,9 @@
 import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
- * Representation of a BMv2 longest prefix match (LPM) parameter.
+ * A BMv2 longest prefix match (LPM) parameter.
  */
+@Beta
 public final class Bmv2LpmMatchParam implements Bmv2MatchParam {
 
     private final ImmutableByteSequence value;
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchKey.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchKey.java
index c0c6b7c..34276aa 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchKey.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchKey.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.bmv2.api.runtime;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
 import com.google.common.collect.Lists;
 import org.onlab.util.ImmutableByteSequence;
@@ -30,6 +31,7 @@
 /**
  * A match key of a BMv2 match-action table entry.
  */
+@Beta
 public final class Bmv2MatchKey {
 
     private final List<Bmv2MatchParam> matchParams;
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchParam.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchParam.java
index 3b7142f..15c750f 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchParam.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchParam.java
@@ -16,9 +16,12 @@
 
 package org.onosproject.bmv2.api.runtime;
 
+import com.google.common.annotations.Beta;
+
 /**
  * Representation of a BMv2 match parameter.
  */
+@Beta
 public interface Bmv2MatchParam {
 
     /**
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ParsedTableEntry.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ParsedTableEntry.java
index 9a32a70..bf59cf4 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ParsedTableEntry.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ParsedTableEntry.java
@@ -16,12 +16,14 @@
 
 package org.onosproject.bmv2.api.runtime;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 
 /**
  * Representation of a table entry installed on a BMv2 device.
  */
+@Beta
 public final class Bmv2ParsedTableEntry {
     private final long entryId;
     private final Bmv2MatchKey matchKey;
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2PortInfo.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2PortInfo.java
index f53a436..568d141 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2PortInfo.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2PortInfo.java
@@ -16,12 +16,14 @@
 
 package org.onosproject.bmv2.api.runtime;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 
 /**
  * Information of a port of a BMv2 device.
  */
+@Beta
 public final class Bmv2PortInfo {
 
     private final String ifaceName;
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2RuntimeException.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2RuntimeException.java
index 697c8d2..176e6f0 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2RuntimeException.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2RuntimeException.java
@@ -16,9 +16,12 @@
 
 package org.onosproject.bmv2.api.runtime;
 
+import com.google.common.annotations.Beta;
+
 /**
  * General exception of the BMv2 runtime APIs.
  */
+@Beta
 public final class Bmv2RuntimeException extends Exception {
 
     private final Code code;
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TableEntry.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TableEntry.java
index ce6bd83..6ea97e9 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TableEntry.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TableEntry.java
@@ -16,6 +16,8 @@
 
 package org.onosproject.bmv2.api.runtime;
 
+import com.google.common.annotations.Beta;
+
 import java.util.Objects;
 
 import static com.google.common.base.Preconditions.checkArgument;
@@ -24,6 +26,7 @@
 /**
  * An entry of a match-action table in a BMv2 device.
  */
+@Beta
 public final class Bmv2TableEntry {
 
     private static final int NO_PRIORITY_VALUE = -1;
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TableEntryReference.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TableEntryReference.java
index fd59fb9..6283239 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TableEntryReference.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TableEntryReference.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.bmv2.api.runtime;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import org.onosproject.net.DeviceId;
@@ -23,6 +24,7 @@
 /**
  * A reference to a table entry installed on a BMv2 device.
  */
+@Beta
 public final class Bmv2TableEntryReference {
 
 
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TernaryMatchParam.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TernaryMatchParam.java
index 60b38f0..713d532 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TernaryMatchParam.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TernaryMatchParam.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.bmv2.api.runtime;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 import org.onlab.util.ImmutableByteSequence;
@@ -26,6 +27,7 @@
 /**
  * Representation of a BMv2 ternary match parameter.
  */
+@Beta
 public final class Bmv2TernaryMatchParam implements Bmv2MatchParam {
 
     private final ImmutableByteSequence value;
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ValidMatchParam.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ValidMatchParam.java
index 38b8c2a..9312b56 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ValidMatchParam.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ValidMatchParam.java
@@ -17,6 +17,7 @@
 package org.onosproject.bmv2.api.runtime;
 
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
 
 import java.util.Objects;
@@ -24,6 +25,7 @@
 /**
  * Representation of a BMv2 valid match parameter.
  */
+@Beta
 public final class Bmv2ValidMatchParam implements Bmv2MatchParam {
 
     private final boolean flag;
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2Controller.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2Controller.java
index 62b1f55..22ba016 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2Controller.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2Controller.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.bmv2.api.service;
 
+import com.google.common.annotations.Beta;
 import org.onosproject.bmv2.api.runtime.Bmv2DeviceAgent;
 import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException;
 import org.onosproject.net.DeviceId;
@@ -23,6 +24,7 @@
 /**
  * A controller of BMv2 devices.
  */
+@Beta
 public interface Bmv2Controller {
 
     /**
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2DeviceContextService.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2DeviceContextService.java
index 7afce3d..077a294 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2DeviceContextService.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2DeviceContextService.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.bmv2.api.service;
 
+import com.google.common.annotations.Beta;
 import org.onosproject.bmv2.api.context.Bmv2DeviceContext;
 import org.onosproject.bmv2.api.context.Bmv2Interpreter;
 import org.onosproject.net.DeviceId;
@@ -23,6 +24,7 @@
 /**
  * A service for managing BMv2 device contexts.
  */
+@Beta
 public interface Bmv2DeviceContextService {
 
     /**
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2DeviceListener.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2DeviceListener.java
index dbd6d65..cb8c444 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2DeviceListener.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2DeviceListener.java
@@ -16,11 +16,13 @@
 
 package org.onosproject.bmv2.api.service;
 
+import com.google.common.annotations.Beta;
 import org.onosproject.bmv2.api.runtime.Bmv2Device;
 
 /**
  * A listener of BMv2 device events.
  */
+@Beta
 public interface Bmv2DeviceListener {
 
     /**
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2PacketListener.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2PacketListener.java
index a713dd8..32629eb 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2PacketListener.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2PacketListener.java
@@ -16,12 +16,14 @@
 
 package org.onosproject.bmv2.api.service;
 
+import com.google.common.annotations.Beta;
 import org.onlab.util.ImmutableByteSequence;
 import org.onosproject.bmv2.api.runtime.Bmv2Device;
 
 /**
  * A listener of BMv2 packet events.
  */
+@Beta
 public interface Bmv2PacketListener {
 
     /**
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2TableEntryService.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2TableEntryService.java
index 5806f10..cd25ee5 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2TableEntryService.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2TableEntryService.java
@@ -17,6 +17,7 @@
 package org.onosproject.bmv2.api.service;
 
 
+import com.google.common.annotations.Beta;
 import org.onosproject.bmv2.api.context.Bmv2FlowRuleTranslator;
 import org.onosproject.bmv2.api.runtime.Bmv2FlowRuleWrapper;
 import org.onosproject.bmv2.api.runtime.Bmv2TableEntryReference;
@@ -24,6 +25,7 @@
 /**
  * A service for managing BMv2 table entries.
  */
+@Beta
 public interface Bmv2TableEntryService {
 
     /**
diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/utils/Bmv2TranslatorUtils.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/utils/Bmv2TranslatorUtils.java
index 8d8966f..0cc102b 100644
--- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/utils/Bmv2TranslatorUtils.java
+++ b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/utils/Bmv2TranslatorUtils.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.bmv2.api.utils;
 
+import com.google.common.annotations.Beta;
 import org.onlab.util.HexString;
 import org.onlab.util.ImmutableByteSequence;
 
@@ -25,8 +26,9 @@
 import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
- * Collection of util methods to deal with flow rule translation.
+ * Collection of utility methods to deal with flow rule translation.
  */
+@Beta
 public final class Bmv2TranslatorUtils {
 
     private Bmv2TranslatorUtils() {
diff --git a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2DefaultInterpreterImpl.java b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2DefaultInterpreterImpl.java
index f5e95df..55bf60c 100644
--- a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2DefaultInterpreterImpl.java
+++ b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2DefaultInterpreterImpl.java
@@ -22,11 +22,14 @@
 import org.onosproject.bmv2.api.context.Bmv2Interpreter;
 import org.onosproject.bmv2.api.context.Bmv2InterpreterException;
 import org.onosproject.bmv2.api.runtime.Bmv2Action;
-import org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils;
+import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.flow.criteria.Criterion;
 import org.onosproject.net.flow.instructions.Instruction;
 
+import static org.onlab.util.ImmutableByteSequence.copyFrom;
+import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.ByteSequenceFitException;
+import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.fitByteSequence;
 import static org.onosproject.net.PortNumber.CONTROLLER;
 import static org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
 
@@ -37,10 +40,10 @@
 
     public static final String TABLE0 = "table0";
     public static final String SEND_TO_CPU = "send_to_cpu";
+    public static final String PORT = "port";
     public static final String DROP = "_drop";
     public static final String SET_EGRESS_PORT = "set_egress_port";
 
-    // Lazily populate field map.
     private static final ImmutableBiMap<Criterion.Type, String> CRITERION_MAP = ImmutableBiMap.of(
             Criterion.Type.IN_PORT, "standard_metadata.ingress_port",
             Criterion.Type.ETH_DST, "ethernet.dstAddr",
@@ -64,10 +67,9 @@
     public Bmv2Action mapTreatment(TrafficTreatment treatment, Bmv2Configuration configuration)
             throws Bmv2InterpreterException {
 
-
         if (treatment.allInstructions().size() == 0) {
             // No instructions means drop for us.
-            return Bmv2Action.builder().withName(DROP).build();
+            return actionWithName(DROP);
         } else if (treatment.allInstructions().size() > 1) {
             // Otherwise, we understand treatments with only 1 instruction.
             throw new Bmv2InterpreterException("Treatment has multiple instructions");
@@ -78,47 +80,38 @@
         switch (instruction.type()) {
             case OUTPUT:
                 OutputInstruction outInstruction = (OutputInstruction) instruction;
-                if (outInstruction.port() == CONTROLLER) {
-                    return Bmv2Action.builder().withName(SEND_TO_CPU).build();
+                PortNumber port = outInstruction.port();
+                if (!port.isLogical()) {
+                    return buildEgressAction(port, configuration);
+                } else if (port.equals(CONTROLLER)) {
+                    return actionWithName(SEND_TO_CPU);
                 } else {
-                    return buildEgressAction(outInstruction, configuration);
+                    throw new Bmv2InterpreterException("Egress on logical port not supported: " + port);
                 }
             case NOACTION:
-                return Bmv2Action.builder().withName(DROP).build();
+                return actionWithName(DROP);
             default:
                 throw new Bmv2InterpreterException("Instruction type not supported: " + instruction.type().name());
         }
     }
 
-
-    /**
-     * Builds an egress action equivalent to the given output instruction for the given configuration.
-     *
-     * @param instruction   an output instruction
-     * @param configuration a configuration
-     * @return a BMv2 action
-     * @throws Bmv2InterpreterException if the instruction cannot be translated to a BMv2 action
-     */
-    private Bmv2Action buildEgressAction(OutputInstruction instruction, Bmv2Configuration configuration)
+    private Bmv2Action buildEgressAction(PortNumber port, Bmv2Configuration configuration)
             throws Bmv2InterpreterException {
 
-        Bmv2Action.Builder actionBuilder = Bmv2Action.builder();
+        int portBitWidth = configuration.action(SET_EGRESS_PORT).runtimeData(PORT).bitWidth();
 
-        actionBuilder.withName(SET_EGRESS_PORT);
-
-        if (instruction.port().isLogical()) {
-            throw new Bmv2InterpreterException("Output on logic port not supported: " + instruction);
-        }
-
-        // Get the byte sequence for the out port with the right length
-        long portNumber = instruction.port().toLong();
-        int bitWidth = configuration.action(SET_EGRESS_PORT).runtimeData("port").bitWidth();
         try {
-            ImmutableByteSequence outPort = Bmv2TranslatorUtils.fitByteSequence(
-                    ImmutableByteSequence.copyFrom(portNumber), bitWidth);
-            return Bmv2Action.builder().withName(SET_EGRESS_PORT).addParameter(outPort).build();
-        } catch (Bmv2TranslatorUtils.ByteSequenceFitException e) {
+            ImmutableByteSequence portBs = fitByteSequence(copyFrom(port.toLong()), portBitWidth);
+            return Bmv2Action.builder()
+                    .withName(SET_EGRESS_PORT)
+                    .addParameter(portBs)
+                    .build();
+        } catch (ByteSequenceFitException e) {
             throw new Bmv2InterpreterException(e.getMessage());
         }
     }
+
+    private Bmv2Action actionWithName(String name) {
+        return Bmv2Action.builder().withName(name).build();
+    }
 }
diff --git a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2FlowRuleTranslatorImpl.java b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2FlowRuleTranslatorImpl.java
index b3c1e8a..ef9427e 100644
--- a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2FlowRuleTranslatorImpl.java
+++ b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2FlowRuleTranslatorImpl.java
@@ -241,7 +241,7 @@
 
         if (extTreatment.type() == ExtensionTreatmentTypes.BMV2_ACTION.type()) {
             if (extTreatment instanceof Bmv2ExtensionTreatment) {
-                return ((Bmv2ExtensionTreatment) extTreatment).getAction();
+                return ((Bmv2ExtensionTreatment) extTreatment).action();
             } else {
                 throw new Bmv2FlowRuleTranslatorException("Unable to decode treatment extension: " + extTreatment);
             }