Renamed devicemanager, flowprogrammer, linkdiscovery and util packages

net.onrc.onos.ofcontroller.devicemanager.* => net.onrc.onos.core.devicemanager.*
net.onrc.onos.ofcontroller.flowprogrammer.* => net.onrc.onos.core.flowprogrammer.*
net.onrc.onos.ofcontroller.linkdiscovery.* => net.onrc.onos.core.linkdiscovery.*
net.onrc.onos.ofcontroller.util.* => net.onrc.onos.core.util.*

Change-Id: Iaa865af552e8fb3a589e73d006569ac79f5a0f08
diff --git a/src/main/java/net/onrc/onos/core/util/FlowEntryAction.java b/src/main/java/net/onrc/onos/core/util/FlowEntryAction.java
new file mode 100644
index 0000000..da86ed3
--- /dev/null
+++ b/src/main/java/net/onrc/onos/core/util/FlowEntryAction.java
@@ -0,0 +1,1677 @@
+package net.onrc.onos.core.util;
+
+import net.floodlightcontroller.util.MACAddress;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * The class representing a single Flow Entry action.
+ *
+ * A Flow Entry action that needs to be applied to each packet.
+ * Note that it contains only a single action. Multiple actions are
+ * listed in a list inside @ref FlowEntryActions.
+ */
+public class FlowEntryAction {
+    /**
+     * Special action values.
+     *
+     * Those values are taken as-is from the OpenFlow-v1.0.0 specification
+     * (pp 21-22).
+     */
+    public enum ActionValues {
+	ACTION_OUTPUT		((short)0x0),	// Output to switch port
+	ACTION_SET_VLAN_VID	((short)0x1),	// Set the 802.1q VLAN id
+	ACTION_SET_VLAN_PCP	((short)0x2),	// Set the 802.1q priority
+	ACTION_STRIP_VLAN	((short)0x3),	// Strip the 802.1q header
+	ACTION_SET_DL_SRC	((short)0x4),	// Ethernet source address
+	ACTION_SET_DL_DST	((short)0x5),	// Ethernet destination address
+	ACTION_SET_NW_SRC	((short)0x6),	// IP source address
+	ACTION_SET_NW_DST	((short)0x7),	// IP destination address
+	ACTION_SET_NW_TOS	((short)0x8),	// IP ToS (DSCP field, 6 bits)
+	ACTION_SET_TP_SRC	((short)0x9),	// TCP/UDP source port
+	ACTION_SET_TP_DST	((short)0xa),	// TCP/UDP destination port
+	ACTION_ENQUEUE		((short)0xb),	// Output to queue on port
+	ACTION_VENDOR		((short)0xffff); // Vendor-specific
+
+	private final short value;	// The value
+
+	/**
+	 * Constructor for a given value.
+	 *
+	 * @param value the value to use for the initialization.
+	 */
+	private ActionValues(short value) {
+	    this.value = value;
+	}
+
+	/**
+	 * Get the value.
+	 *
+	 * @return the value.
+	 */
+	public short getValue() { return value; }
+    }
+
+    /**
+     * Action structure for ACTION_OUTPUT: Output to switch port.
+     */
+    public static class ActionOutput {
+	private Port port;	// Output port
+	private short maxLen;	// Max. length (in bytes) to send to controller
+				// if the port is set to PORT_CONTROLLER
+
+	/**
+	 * Default constructor.
+	 */
+	public ActionOutput() {
+	    this.port = null;
+	    this.maxLen = 0;
+	}
+
+	/**
+	 * Copy constructor.
+	 *
+	 * @param other the object to copy from.
+	 */
+	public ActionOutput(ActionOutput other) {
+	    if (other.port != null)
+		this.port = new Port(other.port);
+	    this.maxLen = other.maxLen;
+	}
+
+	/**
+	 * Constructor from a string.
+	 *
+	 * The string has the following form:
+	 *  [port=XXX maxLen=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public ActionOutput(String actionStr) {
+	    this.fromString(actionStr);
+	}
+
+	/**
+	 * Constructor for a given output port and maximum length.
+	 *
+	 * @param port the output port to set.
+	 * @param maxLen the maximum length (in bytes) to send to controller
+	 * if the port is set to PORT_CONTROLLER.
+	 */
+	public ActionOutput(Port port, short maxLen) {
+	    this.port = port;
+	    this.maxLen = maxLen;
+	}
+
+	/**
+	 * Constructor for a given output port.
+	 *
+	 * @param port the output port to set.
+	 */
+	public ActionOutput(Port port) {
+	    this.port = port;
+	    this.maxLen = 0;
+	}
+
+	/**
+	 * Get the output port.
+	 *
+	 * @return the output port.
+	 */
+	@JsonProperty("port")
+	public Port port() {
+	    return this.port;
+	}
+
+	/**
+	 * Get the maximum length (in bytes) to send to controller if the
+	 * port is set to PORT_CONTROLLER.
+	 *
+	 * @return the maximum length (in bytes) to send to controller if the
+	 * port is set to PORT_CONTROLLER.
+	 */
+	@JsonProperty("maxLen")
+	public short maxLen() {
+	    return this.maxLen;
+	}
+
+	/**
+	 * Convert the action to a string.
+	 *
+	 * The string has the following form:
+	 *  [port=XXX maxLen=XXX]
+	 *
+	 * @return the action as a string.
+	 */
+	@Override
+	public String toString() {
+	    String ret = "[";
+	    ret += "port=" + port.toString();
+	    ret += " maxLen=" + maxLen;
+	    ret += "]";
+
+	    return ret;
+	}
+
+	/**
+	 * Convert a string to an action.
+	 *
+	 * The string has the following form:
+	 *  [port=XXX maxLen=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public void fromString(String actionStr) {
+	    String[] parts = actionStr.split(" ");
+	    String decode = null;
+
+	    // Decode the "port=XXX" part
+	    if (parts.length > 0)
+		decode = parts[0];
+	    if (decode != null) {
+		String[] tokens = decode.split("port=");
+		if (tokens.length > 1 && tokens[1] != null) {
+		    try {
+			Short valueShort = Short.valueOf(tokens[1]);
+			port = new Port(valueShort);
+		    } catch (NumberFormatException e) {
+			throw new IllegalArgumentException("Invalid action string");
+		    }
+		}
+	    } else {
+		throw new IllegalArgumentException("Invalid action string");
+	    }
+
+	    // Decode the "maxLen=XXX" part
+	    decode = null;
+	    if (parts.length > 1)
+		decode = parts[1];
+	    if (decode != null) {
+		decode = decode.replace("]", "");
+		String[] tokens = decode.split("maxLen=");
+		if (tokens.length > 1 && tokens[1] != null) {
+		    try {
+			maxLen = Short.valueOf(tokens[1]);
+		    } catch (NumberFormatException e) {
+			throw new IllegalArgumentException("Invalid action string");
+		    }
+		}
+	    } else {
+		throw new IllegalArgumentException("Invalid action string");
+	    }
+	}
+    }
+
+    /**
+     * Action structure for ACTION_SET_VLAN_VID: Set the 802.1q VLAN id
+     */
+    public static class ActionSetVlanId {
+	private short vlanId;		// The VLAN ID to set
+
+	/**
+	 * Default constructor.
+	 */
+	public ActionSetVlanId() {
+	    this.vlanId = 0;
+	}
+
+	/**
+	 * Copy constructor.
+	 *
+	 * @param other the object to copy from.
+	 */
+	public ActionSetVlanId(ActionSetVlanId other) {
+	    this.vlanId = other.vlanId;
+	}
+
+	/**
+	 * Constructor from a string.
+	 *
+	 * The string has the following form:
+	 *  [vlanId=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public ActionSetVlanId(String actionStr) {
+	    this.fromString(actionStr);
+	}
+
+	/**
+	 * Constructor for a given VLAN ID.
+	 *
+	 * @param vlanId the VLAN ID to set.
+	 */
+	public ActionSetVlanId(short vlanId) {
+	    this.vlanId = vlanId;
+	}
+
+	/**
+	 * Get the VLAN ID.
+	 *
+	 * @return the VLAN ID.
+	 */
+	@JsonProperty("vlanId")
+	public short vlanId() {
+	    return this.vlanId;
+	}
+
+	/**
+	 * Convert the action to a string.
+	 *
+	 * The string has the following form:
+	 *  [vlanId=XXX]
+	 *
+	 * @return the action as a string.
+	 */
+	@Override
+	public String toString() {
+	    String ret = "[";
+	    ret += "vlanId=" + this.vlanId;
+	    ret += "]";
+
+	    return ret;
+	}
+
+	/**
+	 * Convert a string to an action.
+	 *
+	 * The string has the following form:
+	 *  [vlanId=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public void fromString(String actionStr) {
+	    String[] parts = actionStr.split("vlanId=");
+	    String decode = null;
+
+	    // Decode the value
+	    if (parts.length > 1)
+		decode = parts[1];
+	    if (decode != null) {
+		decode = decode.replace("]", "");
+		try {
+		    vlanId = Short.valueOf(decode);
+		} catch (NumberFormatException e) {
+		    throw new IllegalArgumentException("Invalid action string");
+		}
+	    } else {
+		throw new IllegalArgumentException("Invalid action string");
+	    }
+	}
+    }
+
+    /**
+     * Action structure for ACTION_SET_VLAN_PCP: Set the 802.1q priority
+     */
+    public static class ActionSetVlanPriority {
+	private byte vlanPriority;	// The VLAN priority to set
+
+	/**
+	 * Default constructor.
+	 */
+	public ActionSetVlanPriority() {
+	    this.vlanPriority = 0;
+	}
+
+	/**
+	 * Copy constructor.
+	 *
+	 * @param other the object to copy from.
+	 */
+	public ActionSetVlanPriority(ActionSetVlanPriority other) {
+	    this.vlanPriority = other.vlanPriority;
+	}
+
+	/**
+	 * Constructor from a string.
+	 *
+	 * The string has the following form:
+	 *  [vlanPriority=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public ActionSetVlanPriority(String actionStr) {
+	    this.fromString(actionStr);
+	}
+
+	/**
+	 * Constructor for a given VLAN priority.
+	 *
+	 * @param vlanPriority the VLAN priority to set.
+	 */
+	public ActionSetVlanPriority(byte vlanPriority) {
+	    this.vlanPriority = vlanPriority;
+	}
+
+	/**
+	 * Get the VLAN priority.
+	 *
+	 * @return the VLAN priority.
+	 */
+	@JsonProperty("vlanPriority")
+	public byte vlanPriority() {
+	    return this.vlanPriority;
+	}
+
+	/**
+	 * Convert the action to a string.
+	 *
+	 * The string has the following form:
+	 *  [vlanPriority=XXX]
+	 *
+	 * @return the action as a string.
+	 */
+	@Override
+	public String toString() {
+	    String ret = "[";
+	    ret += "vlanPriority=" + this.vlanPriority;
+	    ret += "]";
+
+	    return ret;
+	}
+
+	/**
+	 * Convert a string to an action.
+	 *
+	 * The string has the following form:
+	 *  [vlanPriority=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public void fromString(String actionStr) {
+	    String[] parts = actionStr.split("vlanPriority=");
+	    String decode = null;
+
+	    // Decode the value
+	    if (parts.length > 1)
+		decode = parts[1];
+	    if (decode != null) {
+		decode = decode.replace("]", "");
+		try {
+		    vlanPriority = Byte.valueOf(decode);
+		} catch (NumberFormatException e) {
+		    throw new IllegalArgumentException("Invalid action string");
+		}
+	    } else {
+		throw new IllegalArgumentException("Invalid action string");
+	    }
+	}
+    }
+
+    /**
+     * Action structure for ACTION_STRIP_VLAN: Strip the 802.1q header
+     */
+    public static class ActionStripVlan {
+	private boolean stripVlan;	// If true, strip the VLAN header
+
+	/**
+	 * Default constructor.
+	 */
+	public ActionStripVlan() {
+	    this.stripVlan = false;
+	}
+
+	/**
+	 * Copy constructor.
+	 *
+	 * @param other the object to copy from.
+	 */
+	public ActionStripVlan(ActionStripVlan other) {
+	    this.stripVlan = other.stripVlan;
+	}
+
+	/**
+	 * Constructor from a string.
+	 *
+	 * The string has the following form:
+	 *  [stripVlan=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public ActionStripVlan(String actionStr) {
+	    this.fromString(actionStr);
+	}
+
+	/**
+	 * Constructor for a given boolean flag.
+	 *
+	 * @param stripVlan if true, strip the VLAN header.
+	 */
+	public ActionStripVlan(boolean stripVlan) {
+	    this.stripVlan = stripVlan;
+	}
+
+	/**
+	 * Get the boolean flag whether the VLAN header should be stripped.
+	 *
+	 * @return the boolean flag whether the VLAN header should be stripped.
+	 */
+	@JsonProperty("stripVlan")
+	public boolean stripVlan() {
+	    return this.stripVlan;
+	}
+
+	/**
+	 * Convert the action to a string.
+	 *
+	 * The string has the following form:
+	 *  [stripVlan=XXX]
+	 *
+	 * @return the action as a string.
+	 */
+	@Override
+	public String toString() {
+	    String ret = "[";
+	    ret += "stripVlan=" + this.stripVlan;
+	    ret += "]";
+
+	    return ret;
+	}
+
+	/**
+	 * Convert a string to an action.
+	 *
+	 * The string has the following form:
+	 *  [stripVlan=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public void fromString(String actionStr) {
+	    String[] parts = actionStr.split("stripVlan=");
+	    String decode = null;
+
+	    // Decode the value
+	    if (parts.length > 1)
+		decode = parts[1];
+	    if (decode != null) {
+		decode = decode.replace("]", "");
+		stripVlan = Boolean.valueOf(decode);
+	    } else {
+		throw new IllegalArgumentException("Invalid action string");
+	    }
+	}
+    }
+
+    /**
+     * Action structure for ACTION_SET_DL_SRC and ACTION_SET_DL_DST:
+     * Set the Ethernet source/destination address.
+     */
+    public static class ActionSetEthernetAddr {
+	private MACAddress addr;	// The MAC address to set
+
+	/**
+	 * Default constructor.
+	 */
+	public ActionSetEthernetAddr() {
+	    this.addr = null;
+	}
+
+	/**
+	 * Copy constructor.
+	 *
+	 * @param other the object to copy from.
+	 */
+	public ActionSetEthernetAddr(ActionSetEthernetAddr other) {
+	    if (other.addr != null)
+		this.addr = MACAddress.valueOf(other.addr.toLong());
+	}
+
+	/**
+	 * Constructor from a string.
+	 *
+	 * The string has the following form:
+	 *  [addr=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public ActionSetEthernetAddr(String actionStr) {
+	    this.fromString(actionStr);
+	}
+
+	/**
+	 * Constructor for a given MAC address.
+	 *
+	 * @param addr the MAC address to set.
+	 */
+	public ActionSetEthernetAddr(MACAddress addr) {
+	    this.addr = addr;
+	}
+
+	/**
+	 * Get the MAC address.
+	 *
+	 * @return the MAC address.
+	 */
+	@JsonProperty("addr")
+	public MACAddress addr() {
+	    return this.addr;
+	}
+
+	/**
+	 * Convert the action to a string.
+	 *
+	 * The string has the following form:
+	 *  [addr=XXX]
+	 *
+	 * @return the action as a string.
+	 */
+	@Override
+	public String toString() {
+	    String ret = "[";
+	    ret += "addr=" + addr.toString();
+	    ret += "]";
+
+	    return ret;
+	}
+
+	/**
+	 * Convert a string to an action.
+	 *
+	 * The string has the following form:
+	 *  [addr=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public void fromString(String actionStr) {
+	    String[] parts = actionStr.split("addr=");
+	    String decode = null;
+
+	    // Decode the value
+	    if (parts.length > 1)
+		decode = parts[1];
+	    if (decode != null) {
+		decode = decode.replace("]", "");
+		try {
+		    addr = MACAddress.valueOf(decode);
+		} catch (IllegalArgumentException e) {
+		    throw new IllegalArgumentException("Invalid action string");
+		}
+	    } else {
+		throw new IllegalArgumentException("Invalid action string");
+	    }
+	}
+    }
+
+    /**
+     * Action structure for ACTION_SET_NW_SRC and ACTION_SET_NW_DST:
+     * Set the IPv4 source/destination address.
+     */
+    public static class ActionSetIPv4Addr {
+	private IPv4 addr;		// The IPv4 address to set
+
+	/**
+	 * Default constructor.
+	 */
+	public ActionSetIPv4Addr() {
+	    this.addr = null;
+	}
+
+	/**
+	 * Copy constructor.
+	 *
+	 * @param other the object to copy from.
+	 */
+	public ActionSetIPv4Addr(ActionSetIPv4Addr other) {
+	    if (other.addr != null)
+		this.addr = new IPv4(other.addr);
+	}
+
+	/**
+	 * Constructor from a string.
+	 *
+	 * The string has the following form:
+	 *  [addr=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public ActionSetIPv4Addr(String actionStr) {
+	    this.fromString(actionStr);
+	}
+
+	/**
+	 * Constructor for a given IPv4 address.
+	 *
+	 * @param addr the IPv4 address to set.
+	 */
+	public ActionSetIPv4Addr(IPv4 addr) {
+	    this.addr = addr;
+	}
+
+	/**
+	 * Get the IPv4 address.
+	 *
+	 * @return the IPv4 address.
+	 */
+	@JsonProperty("addr")
+	public IPv4 addr() {
+	    return this.addr;
+	}
+
+	/**
+	 * Convert the action to a string.
+	 *
+	 * The string has the following form:
+	 *  [addr=XXX]
+	 *
+	 * @return the action as a string.
+	 */
+	@Override
+	public String toString() {
+	    String ret = "[";
+	    ret += "addr=" + addr.toString();
+	    ret += "]";
+
+	    return ret;
+	}
+
+	/**
+	 * Convert a string to an action.
+	 *
+	 * The string has the following form:
+	 *  [addr=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public void fromString(String actionStr) {
+	    String[] parts = actionStr.split("addr=");
+	    String decode = null;
+
+	    // Decode the value
+	    if (parts.length > 1)
+		decode = parts[1];
+	    if (decode != null) {
+		decode = decode.replace("]", "");
+		try {
+		    addr = new IPv4(decode);
+		} catch (IllegalArgumentException e) {
+		    throw new IllegalArgumentException("Invalid action string");
+		}
+	    } else {
+		throw new IllegalArgumentException("Invalid action string");
+	    }
+	}
+    }
+
+    /**
+     * Action structure for ACTION_SET_NW_TOS:
+     * Set the IP ToS (DSCP field, 6 bits).
+     */
+    public static class ActionSetIpToS {
+	private byte ipToS;	// The IP ToS to set DSCP field, 6 bits)
+
+	/**
+	 * Default constructor.
+	 */
+	public ActionSetIpToS() {
+	    this.ipToS = 0;
+	}
+
+	/**
+	 * Copy constructor.
+	 *
+	 * @param other the object to copy from.
+	 */
+	public ActionSetIpToS(ActionSetIpToS other) {
+	    this.ipToS = other.ipToS;
+	}
+
+	/**
+	 * Constructor from a string.
+	 *
+	 * The string has the following form:
+	 *  [ipToS=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public ActionSetIpToS(String actionStr) {
+	    this.fromString(actionStr);
+	}
+
+	/**
+	 * Constructor for a given IP ToS (DSCP field, 6 bits).
+	 *
+	 * @param ipToS the IP ToS (DSCP field, 6 bits) to set.
+	 */
+	public ActionSetIpToS(byte ipToS) {
+	    this.ipToS = ipToS;
+	}
+
+	/**
+	 * Get the IP ToS (DSCP field, 6 bits).
+	 *
+	 * @return the IP ToS (DSCP field, 6 bits).
+	 */
+	@JsonProperty("ipToS")
+	public byte ipToS() {
+	    return this.ipToS;
+	}
+
+	/**
+	 * Convert the action to a string.
+	 *
+	 * The string has the following form:
+	 *  [ipToS=XXX]
+	 *
+	 * @return the action as a string.
+	 */
+	@Override
+	public String toString() {
+	    String ret = "[";
+	    ret += "ipToS=" + ipToS;
+	    ret += "]";
+
+	    return ret;
+	}
+
+	/**
+	 * Convert a string to an action.
+	 *
+	 * The string has the following form:
+	 *  [ipToS=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public void fromString(String actionStr) {
+	    String[] parts = actionStr.split("ipToS=");
+	    String decode = null;
+
+	    // Decode the value
+	    if (parts.length > 1)
+		decode = parts[1];
+	    if (decode != null) {
+		decode = decode.replace("]", "");
+		try {
+		    ipToS = Byte.valueOf(decode);
+		} catch (NumberFormatException e) {
+		    throw new IllegalArgumentException("Invalid action string");
+		}
+	    } else {
+		throw new IllegalArgumentException("Invalid action string");
+	    }
+	}
+    }
+
+    /**
+     * Action structure for ACTION_SET_TP_SRC and ACTION_SET_TP_DST:
+     * Set the TCP/UDP source/destination port.
+     */
+    public static class ActionSetTcpUdpPort {
+	private short port;		// The TCP/UDP port to set
+
+	/**
+	 * Default constructor.
+	 */
+	public ActionSetTcpUdpPort() {
+	    this.port = 0;
+	}
+
+	/**
+	 * Copy constructor.
+	 *
+	 * @param other the object to copy from.
+	 */
+	public ActionSetTcpUdpPort(ActionSetTcpUdpPort other) {
+	    this.port = other.port;
+	}
+
+	/**
+	 * Constructor from a string.
+	 *
+	 * The string has the following form:
+	 *  [port=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public ActionSetTcpUdpPort(String actionStr) {
+	    this.fromString(actionStr);
+	}
+
+	/**
+	 * Constructor for a given TCP/UDP port.
+	 *
+	 * @param port the TCP/UDP port to set.
+	 */
+	public ActionSetTcpUdpPort(short port) {
+	    this.port = port;
+	}
+
+	/**
+	 * Get the TCP/UDP port.
+	 *
+	 * @return the TCP/UDP port.
+	 */
+	@JsonProperty("port")
+	public short port() {
+	    return this.port;
+	}
+
+	/**
+	 * Convert the action to a string.
+	 *
+	 * The string has the following form:
+	 *  [port=XXX]
+	 *
+	 * @return the action as a string.
+	 */
+	@Override
+	public String toString() {
+	    String ret = "[";
+	    ret += "port=" + port;
+	    ret += "]";
+
+	    return ret;
+	}
+
+	/**
+	 * Convert a string to an action.
+	 *
+	 * The string has the following form:
+	 *  [port=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public void fromString(String actionStr) {
+	    String[] parts = actionStr.split("port=");
+	    String decode = null;
+
+	    // Decode the value
+	    if (parts.length > 1)
+		decode = parts[1];
+	    if (decode != null) {
+		decode = decode.replace("]", "");
+		try {
+		    port = Short.valueOf(decode);
+		} catch (NumberFormatException e) {
+		    throw new IllegalArgumentException("Invalid action string");
+		}
+	    } else {
+		throw new IllegalArgumentException("Invalid action string");
+	    }
+	}
+    }
+
+    /**
+     * Action structure for ACTION_ENQUEUE: Output to queue on port.
+     */
+    public static class ActionEnqueue {
+	private Port port;	// Port that queue belongs. Should
+				// refer to a valid physical port
+				// (i.e. < PORT_MAX) or PORT_IN_PORT
+	private int queueId;	// Where to enqueue the packets
+
+	/**
+	 * Default constructor.
+	 */
+	public ActionEnqueue() {
+	    this.port = null;
+	    this.queueId = 0;
+	}
+
+	/**
+	 * Copy constructor.
+	 *
+	 * @param other the object to copy from.
+	 */
+	public ActionEnqueue(ActionEnqueue other) {
+	    if (other.port != null)
+		this.port = new Port(other.port);
+	    this.queueId = other.queueId;
+	}
+
+	/**
+	 * Constructor from a string.
+	 *
+	 * The string has the following form:
+	 *  [port=XXX queueId=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public ActionEnqueue(String actionStr) {
+	    this.fromString(actionStr);
+	}
+
+	/**
+	 * Constructor for a given port and queue ID.
+	 *
+	 * @param port the port to set.
+	 * @param queueId the queue ID on the port.
+	 */
+	public ActionEnqueue(Port port, int queueId) {
+	    this.port = port;
+	    this.queueId = queueId;
+	}
+
+	/**
+	 * Get the port.
+	 *
+	 * @return the port.
+	 */
+	@JsonProperty("port")
+	public Port port() {
+	    return this.port;
+	}
+
+	/**
+	 * Get the queue ID.
+	 *
+	 * @return the queue ID.
+	 */
+	@JsonProperty("queueId")
+	public int queueId() {
+	    return this.queueId;
+	}
+
+	/**
+	 * Convert the action to a string.
+	 *
+	 * The string has the following form:
+	 *  [port=XXX queueId=XXX]
+	 *
+	 * @return the action as a string.
+	 */
+	@Override
+	public String toString() {
+	    String ret = "[";
+	    ret += "port=" + port.toString();
+	    ret += " queueId=" + queueId;
+	    ret += "]";
+
+	    return ret;
+	}
+
+	/**
+	 * Convert a string to an action.
+	 *
+	 * The string has the following form:
+	 *  [port=XXX queueId=XXX]
+	 *
+	 * @param actionStr the action as a string.
+	 */
+	public void fromString(String actionStr) {
+	    String[] parts = actionStr.split(" ");
+	    String decode = null;
+
+	    // Decode the "port=XXX" part
+	    if (parts.length > 0)
+		decode = parts[0];
+	    if (decode != null) {
+		String[] tokens = decode.split("port=");
+		if (tokens.length > 1 && tokens[1] != null) {
+		    try {
+			Short valueShort = Short.valueOf(tokens[1]);
+			port = new Port(valueShort);
+		    } catch (NumberFormatException e) {
+			throw new IllegalArgumentException("Invalid action string");
+		    }
+		}
+	    } else {
+		throw new IllegalArgumentException("Invalid action string");
+	    }
+
+	    // Decode the "queueId=XXX" part
+	    decode = null;
+	    if (parts.length > 1)
+		decode = parts[1];
+	    if (decode != null) {
+		decode = decode.replace("]", "");
+		String[] tokens = decode.split("queueId=");
+		if (tokens.length > 1 && tokens[1] != null) {
+		    try {
+			queueId = Short.valueOf(tokens[1]);
+		    } catch (NumberFormatException e) {
+			throw new IllegalArgumentException("Invalid action string");
+		    }
+		}
+	    } else {
+		throw new IllegalArgumentException("Invalid action string");
+	    }
+	}
+    }
+
+    private ActionValues actionType;	// The action type
+
+    //
+    // The actions.
+    // NOTE: Only one action should be set.
+    //
+    private ActionOutput actionOutput;
+    private ActionSetVlanId actionSetVlanId;
+    private ActionSetVlanPriority actionSetVlanPriority;
+    private ActionStripVlan actionStripVlan;
+    private ActionSetEthernetAddr actionSetEthernetSrcAddr;
+    private ActionSetEthernetAddr actionSetEthernetDstAddr;
+    private ActionSetIPv4Addr actionSetIPv4SrcAddr;
+    private ActionSetIPv4Addr actionSetIPv4DstAddr;
+    private ActionSetIpToS actionSetIpToS;
+    private ActionSetTcpUdpPort actionSetTcpUdpSrcPort;
+    private ActionSetTcpUdpPort actionSetTcpUdpDstPort;
+    private ActionEnqueue actionEnqueue;
+
+    /**
+     * Default constructor.
+     */
+    public FlowEntryAction() {
+	actionType = ActionValues.ACTION_VENDOR;	// XXX: Initial value
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param other the object to copy from.
+     */
+    public FlowEntryAction(FlowEntryAction other) {
+	this.actionType = other.actionType;
+
+	//
+	if (other.actionOutput != null)
+	    this.actionOutput = new ActionOutput(other.actionOutput);
+	else
+	    this.actionOutput = null;
+	//
+	if (other.actionSetVlanId != null)
+	    this.actionSetVlanId = new ActionSetVlanId(other.actionSetVlanId);
+	else
+	    this.actionSetVlanId = null;
+	//
+	if (other.actionSetVlanPriority != null)
+	    this.actionSetVlanPriority = new ActionSetVlanPriority(other.actionSetVlanPriority);
+	else
+	    this.actionSetVlanPriority = null;
+	//
+	if (other.actionStripVlan != null)
+	    this.actionStripVlan = new ActionStripVlan(other.actionStripVlan);
+	else
+	    this.actionStripVlan = null;
+	//
+	if (other.actionSetEthernetSrcAddr != null)
+	    this.actionSetEthernetSrcAddr = new ActionSetEthernetAddr(other.actionSetEthernetSrcAddr);
+	else
+	    this.actionSetEthernetSrcAddr = null;
+	//
+	if (other.actionSetEthernetDstAddr != null)
+	    this.actionSetEthernetDstAddr = new ActionSetEthernetAddr(other.actionSetEthernetDstAddr);
+	else
+	    this.actionSetEthernetDstAddr = null;
+	//
+	if (other.actionSetIPv4SrcAddr != null)
+	    this.actionSetIPv4SrcAddr = new ActionSetIPv4Addr(other.actionSetIPv4SrcAddr);
+	else
+	    this.actionSetIPv4SrcAddr = null;
+	//
+	if (other.actionSetIPv4DstAddr != null)
+	    this.actionSetIPv4DstAddr = new ActionSetIPv4Addr(other.actionSetIPv4DstAddr);
+	else
+	    this.actionSetIPv4DstAddr = null;
+	//
+	if (other.actionSetIpToS != null)
+	    this.actionSetIpToS = new ActionSetIpToS(other.actionSetIpToS);
+	else
+	    this.actionSetIpToS = null;
+	//
+	if (other.actionSetTcpUdpSrcPort != null)
+	    this.actionSetTcpUdpSrcPort = new ActionSetTcpUdpPort(other.actionSetTcpUdpSrcPort);
+	else
+	    this.actionSetTcpUdpSrcPort = null;
+	//
+	if (other.actionSetTcpUdpDstPort != null)
+	    this.actionSetTcpUdpDstPort = new ActionSetTcpUdpPort(other.actionSetTcpUdpDstPort);
+	else
+	    this.actionSetTcpUdpDstPort = null;
+	//
+	if (other.actionEnqueue != null)
+	    this.actionEnqueue = new ActionEnqueue(other.actionEnqueue);
+	else
+	    this.actionEnqueue = null;
+    }
+
+    /**
+     * Constructor from a string.
+     *
+     * The string has the following form:
+     *  [type=XXX action=XXX]
+     *
+     * @param actionStr the action as a string.
+     */
+    public FlowEntryAction(String actionStr) {
+	this.fromString(actionStr);
+    }
+
+    /**
+     * Get the action type.
+     *
+     * @return the action type.
+     */
+    @JsonProperty("actionType")
+    public ActionValues actionType() { return actionType; }
+
+    /**
+     * Get the output action.
+     *
+     * @return the output action.
+     */
+    @JsonProperty("actionOutput")
+    public ActionOutput actionOutput() { return actionOutput; }
+
+    /**
+     * Set the output action on a port.
+     *
+     * @param action the action to set.
+     */
+    @JsonProperty("actionOutput")
+    public void setActionOutput(ActionOutput action) {
+	actionOutput = action;
+	actionType = ActionValues.ACTION_OUTPUT;
+    }
+
+    /**
+     * Set the output action on a port.
+     *
+     * @param port the output port to set.
+     */
+    public void setActionOutput(Port port) {
+	actionOutput = new ActionOutput(port);
+	actionType = ActionValues.ACTION_OUTPUT;
+    }
+
+    /**
+     * Set the output action to controller.
+     *
+     * @param maxLen the maximum length (in bytes) to send to controller.
+     */
+    public void setActionOutputToController(short maxLen) {
+	Port port = new Port(Port.PortValues.PORT_CONTROLLER);
+	actionOutput = new ActionOutput(port, maxLen);
+	actionType = ActionValues.ACTION_OUTPUT;
+    }
+
+    /**
+     * Get the action to set the VLAN ID.
+     *
+     * @return the action to set the VLAN ID.
+     */
+    @JsonProperty("actionSetVlanId")
+    public ActionSetVlanId actionSetVlanId() { return actionSetVlanId; }
+
+    /**
+     * Set the action to set the VLAN ID.
+     *
+     * @param action the action to set.
+     */
+    @JsonProperty("actionSetVlanId")
+    public void setActionSetVlanId(ActionSetVlanId action) {
+	actionSetVlanId = action;
+	actionType = ActionValues.ACTION_SET_VLAN_VID;
+    }
+
+    /**
+     * Set the action to set the VLAN ID.
+     *
+     * @param vlanId the VLAN ID to set.
+     */
+    public void setActionSetVlanId(short vlanId) {
+	actionSetVlanId = new ActionSetVlanId(vlanId);
+	actionType = ActionValues.ACTION_SET_VLAN_VID;
+    }
+
+    /**
+     * Get the action to set the VLAN priority.
+     *
+     * @return the action to set the VLAN priority.
+     */
+    @JsonProperty("actionSetVlanPriority")
+    public ActionSetVlanPriority actionSetVlanPriority() {
+	return actionSetVlanPriority;
+    }
+
+    /**
+     * Set the action to set the VLAN priority.
+     *
+     * @param action the action to set.
+     */
+    @JsonProperty("actionSetVlanPriority")
+    public void setActionSetVlanPriority(ActionSetVlanPriority action) {
+	actionSetVlanPriority = action;
+	actionType = ActionValues.ACTION_SET_VLAN_PCP;
+    }
+
+    /**
+     * Set the action to set the VLAN priority.
+     *
+     * @param vlanPriority the VLAN priority to set.
+     */
+    public void setActionSetVlanPriority(byte vlanPriority) {
+	actionSetVlanPriority = new ActionSetVlanPriority(vlanPriority);
+	actionType = ActionValues.ACTION_SET_VLAN_PCP;
+    }
+
+    /**
+     * Get the action to strip the VLAN header.
+     *
+     * @return the action to strip the VLAN header.
+     */
+    @JsonProperty("actionStripVlan")
+    public ActionStripVlan actionStripVlan() {
+	return actionStripVlan;
+    }
+
+    /**
+     * Set the action to strip the VLAN header.
+     *
+     * @param action the action to set.
+     */
+    @JsonProperty("actionStripVlan")
+    public void setActionStripVlan(ActionStripVlan action) {
+	actionStripVlan = action;
+	actionType = ActionValues.ACTION_STRIP_VLAN;
+    }
+
+    /**
+     * Set the action to strip the VLAN header.
+     *
+     * @param stripVlan if true, strip the VLAN header.
+     */
+    public void setActionStripVlan(boolean stripVlan) {
+	actionStripVlan = new ActionStripVlan(stripVlan);
+	actionType = ActionValues.ACTION_STRIP_VLAN;
+    }
+
+    /**
+     * Get the action to set the Ethernet source address.
+     *
+     * @return the action to set the Ethernet source address.
+     */
+    @JsonProperty("actionSetEthernetSrcAddr")
+    public ActionSetEthernetAddr actionSetEthernetSrcAddr() {
+	return actionSetEthernetSrcAddr;
+    }
+
+    /**
+     * Set the action to set the Ethernet source address.
+     *
+     * @param action the action to set.
+     */
+    @JsonProperty("actionSetEthernetSrcAddr")
+    public void setActionSetEthernetSrcAddr(ActionSetEthernetAddr action) {
+	actionSetEthernetSrcAddr = action;
+	actionType = ActionValues.ACTION_SET_DL_SRC;
+    }
+
+    /**
+     * Set the action to set the Ethernet source address.
+     *
+     * @param addr the MAC address to set as the Ethernet source address.
+     */
+    public void setActionSetEthernetSrcAddr(MACAddress addr) {
+	actionSetEthernetSrcAddr = new ActionSetEthernetAddr(addr);
+	actionType = ActionValues.ACTION_SET_DL_SRC;
+    }
+
+    /**
+     * Get the action to set the Ethernet destination address.
+     *
+     * @return the action to set the Ethernet destination address.
+     */
+    @JsonProperty("actionSetEthernetDstAddr")
+    public ActionSetEthernetAddr actionSetEthernetDstAddr() {
+	return actionSetEthernetDstAddr;
+    }
+
+    /**
+     * Set the action to set the Ethernet destination address.
+     *
+     * @param action the action to set.
+     */
+    @JsonProperty("actionSetEthernetDstAddr")
+    public void setActionSetEthernetDstAddr(ActionSetEthernetAddr action) {
+	actionSetEthernetDstAddr = action;
+	actionType = ActionValues.ACTION_SET_DL_DST;
+    }
+
+    /**
+     * Set the action to set the Ethernet destination address.
+     *
+     * @param addr the MAC address to set as the Ethernet destination address.
+     */
+    public void setActionSetEthernetDstAddr(MACAddress addr) {
+	actionSetEthernetDstAddr = new ActionSetEthernetAddr(addr);
+	actionType = ActionValues.ACTION_SET_DL_DST;
+    }
+
+    /**
+     * Get the action to set the IPv4 source address.
+     *
+     * @return the action to set the IPv4 source address.
+     */
+    @JsonProperty("actionSetIPv4SrcAddr")
+    public ActionSetIPv4Addr actionSetIPv4SrcAddr() {
+	return actionSetIPv4SrcAddr;
+    }
+
+    /**
+     * Set the action to set the IPv4 source address.
+     *
+     * @param action the action to set.
+     */
+    @JsonProperty("actionSetIPv4SrcAddr")
+    public void setActionSetIPv4SrcAddr(ActionSetIPv4Addr action) {
+	actionSetIPv4SrcAddr = action;
+	actionType = ActionValues.ACTION_SET_NW_SRC;
+    }
+
+    /**
+     * Set the action to set the IPv4 source address.
+     *
+     * @param addr the IPv4 address to set as the IPv4 source address.
+     */
+    public void setActionSetIPv4SrcAddr(IPv4 addr) {
+	actionSetIPv4SrcAddr = new ActionSetIPv4Addr(addr);
+	actionType = ActionValues.ACTION_SET_NW_SRC;
+    }
+
+    /**
+     * Get the action to set the IPv4 destination address.
+     *
+     * @return the action to set the IPv4 destination address.
+     */
+    @JsonProperty("actionSetIPv4DstAddr")
+    public ActionSetIPv4Addr actionSetIPv4DstAddr() {
+	return actionSetIPv4DstAddr;
+    }
+
+    /**
+     * Set the action to set the IPv4 destination address.
+     *
+     * @param action the action to set.
+     */
+    @JsonProperty("actionSetIPv4DstAddr")
+    public void setActionSetIPv4DstAddr(ActionSetIPv4Addr action) {
+	actionSetIPv4DstAddr = action;
+	actionType = ActionValues.ACTION_SET_NW_DST;
+    }
+
+    /**
+     * Set the action to set the IPv4 destination address.
+     *
+     * @param addr the IPv4 address to set as the IPv4 destination address.
+     */
+    public void setActionSetIPv4DstAddr(IPv4 addr) {
+	actionSetIPv4DstAddr = new ActionSetIPv4Addr(addr);
+	actionType = ActionValues.ACTION_SET_NW_DST;
+    }
+
+    /**
+     * Get the action to set the IP ToS (DSCP field, 6 bits).
+     *
+     * @return the action to set the IP ToS (DSCP field, 6 bits).
+     */
+    @JsonProperty("actionSetIpToS")
+    public ActionSetIpToS actionSetIpToS() {
+	return actionSetIpToS;
+    }
+
+    /**
+     * Set the action to set the IP ToS (DSCP field, 6 bits).
+     *
+     * @param action the action to set.
+     */
+    @JsonProperty("actionSetIpToS")
+    public void setActionSetIpToS(ActionSetIpToS action) {
+	actionSetIpToS = action;
+	actionType = ActionValues.ACTION_SET_NW_TOS;
+    }
+
+    /**
+     * Set the action to set the IP ToS (DSCP field, 6 bits).
+     *
+     * @param ipToS the IP ToS (DSCP field, 6 bits) to set.
+     */
+    public void setActionSetIpToS(byte ipToS) {
+	actionSetIpToS = new ActionSetIpToS(ipToS);
+	actionType = ActionValues.ACTION_SET_NW_TOS;
+    }
+
+    /**
+     * Get the action to set the TCP/UDP source port.
+     *
+     * @return the action to set the TCP/UDP source port.
+     */
+    @JsonProperty("actionSetTcpUdpSrcPort")
+    public ActionSetTcpUdpPort actionSetTcpUdpSrcPort() {
+	return actionSetTcpUdpSrcPort;
+    }
+
+    /**
+     * Set the action to set the TCP/UDP source port.
+     *
+     * @param action the action to set.
+     */
+    @JsonProperty("actionSetTcpUdpSrcPort")
+    public void setActionSetTcpUdpSrcPort(ActionSetTcpUdpPort action) {
+	actionSetTcpUdpSrcPort = action;
+	actionType = ActionValues.ACTION_SET_TP_SRC;
+    }
+
+    /**
+     * Set the action to set the TCP/UDP source port.
+     *
+     * @param port the TCP/UDP port to set as the TCP/UDP source port.
+     */
+    public void setActionSetTcpUdpSrcPort(short port) {
+	actionSetTcpUdpSrcPort = new ActionSetTcpUdpPort(port);
+	actionType = ActionValues.ACTION_SET_TP_SRC;
+    }
+
+    /**
+     * Get the action to set the TCP/UDP destination port.
+     *
+     * @return the action to set the TCP/UDP destination port.
+     */
+    @JsonProperty("actionSetTcpUdpDstPort")
+    public ActionSetTcpUdpPort actionSetTcpUdpDstPort() {
+	return actionSetTcpUdpDstPort;
+    }
+
+    /**
+     * Set the action to set the TCP/UDP destination port.
+     *
+     * @param action the action to set.
+     */
+    @JsonProperty("actionSetTcpUdpDstPort")
+    public void setActionSetTcpUdpDstPort(ActionSetTcpUdpPort action) {
+	actionSetTcpUdpDstPort = action;
+	actionType = ActionValues.ACTION_SET_TP_DST;
+    }
+
+    /**
+     * Set the action to set the TCP/UDP destination port.
+     *
+     * @param port the TCP/UDP port to set as the TCP/UDP destination port.
+     */
+    public void setActionSetTcpUdpDstPort(short port) {
+	actionSetTcpUdpDstPort = new ActionSetTcpUdpPort(port);
+	actionType = ActionValues.ACTION_SET_TP_DST;
+    }
+
+    /**
+     * Get the action to output to queue on a port.
+     *
+     * @return the action to output to queue on a port.
+     */
+    @JsonProperty("actionEnqueue")
+    public ActionEnqueue actionEnqueue() { return actionEnqueue; }
+
+    /**
+     * Set the action to output to queue on a port.
+     *
+     * @param action the action to set.
+     */
+    @JsonProperty("actionEnqueue")
+    public void setActionEnqueue(ActionEnqueue action) {
+	actionEnqueue = action;
+	actionType = ActionValues.ACTION_ENQUEUE;
+    }
+
+    /**
+     * Set the action to output to queue on a port.
+     *
+     * @param port the port to set.
+     * @param queueId the queue ID to set.
+     */
+    public void setActionEnqueue(Port port, int queueId) {
+	actionEnqueue = new ActionEnqueue(port, queueId);
+	actionType = ActionValues.ACTION_ENQUEUE;
+    }
+
+    /**
+     * Convert the action to a string.
+     *
+     * The string has the following form:
+     *  [type=XXX action=XXX]
+     *
+     * @return the action as a string.
+     */
+    @Override
+    public String toString() {
+	String ret = "[";
+	ret += "type=" + actionType;
+	switch (actionType) {
+	case ACTION_OUTPUT:
+	    ret += " action=" + actionOutput.toString();
+	    break;
+	case ACTION_SET_VLAN_VID:
+	    ret += " action=" + actionSetVlanId.toString();
+	    break;
+	case ACTION_SET_VLAN_PCP:
+	    ret += " action=" + actionSetVlanPriority.toString();
+	    break;
+	case ACTION_STRIP_VLAN:
+	    ret += " action=" + actionStripVlan.toString();
+	    break;
+	case ACTION_SET_DL_SRC:
+	    ret += " action=" + actionSetEthernetSrcAddr.toString();
+	    break;
+	case ACTION_SET_DL_DST:
+	    ret += " action=" + actionSetEthernetDstAddr.toString();
+	    break;
+	case ACTION_SET_NW_SRC:
+	    ret += " action=" + actionSetIPv4SrcAddr.toString();
+	    break;
+	case ACTION_SET_NW_DST:
+	    ret += " action=" + actionSetIPv4DstAddr.toString();
+	    break;
+	case ACTION_SET_NW_TOS:
+	    ret += " action=" + actionSetIpToS.toString();
+	    break;
+	case ACTION_SET_TP_SRC:
+	    ret += " action=" + actionSetTcpUdpSrcPort.toString();
+	    break;
+	case ACTION_SET_TP_DST:
+	    ret += " action=" + actionSetTcpUdpDstPort.toString();
+	    break;
+	case ACTION_ENQUEUE:
+	    ret += " action=" + actionEnqueue.toString();
+	    break;
+	case ACTION_VENDOR:
+	    ret += " action=VENDOR";
+	    break;
+	}
+	ret += "]";
+
+	return ret;
+    }
+
+    /**
+     * Convert a string to an action.
+     *
+     * The string has the following form:
+     *  [type=XXX action=XXX]
+     *
+     * @param actionStr the action as a string.
+     */
+    public void fromString(String actionStr) {
+	String[] parts = actionStr.split("type=");
+	String decode = null;
+
+	// Extract the string after the "type="
+	if (parts.length > 1)
+	    decode = parts[1];
+	if (decode == null)
+	    throw new IllegalArgumentException("Invalid action string");
+
+	// Remove the trailing ']'
+	if ((decode.length() > 0) && (decode.charAt(decode.length() - 1) == ']')) {
+	    decode = decode.substring(0, decode.length() - 1);
+	} else {
+	    throw new IllegalArgumentException("Invalid action string");
+	}
+
+	// Extract the type value and the action value
+	parts = decode.split(" action=");
+
+	// Decode the "type=XXX" payload
+	if (parts.length > 0)
+	    decode = parts[0];
+	if (decode != null) {
+	    try {
+		actionType = Enum.valueOf(ActionValues.class, decode);
+	    } catch (IllegalArgumentException e) {
+		throw new IllegalArgumentException("Invalid action string");
+	    }
+	} else {
+	    throw new IllegalArgumentException("Invalid action string");
+	}
+
+	// Decode the "action=XXX" payload
+	decode = null;
+	if (parts.length > 1)
+	    decode = parts[1];
+	if (decode == null)
+	    throw new IllegalArgumentException("Invalid action string");
+	//
+	try {
+	    switch (actionType) {
+	    case ACTION_OUTPUT:
+		actionOutput = new ActionOutput(decode);
+		break;
+	    case ACTION_SET_VLAN_VID:
+		actionSetVlanId = new ActionSetVlanId(decode);
+		break;
+	    case ACTION_SET_VLAN_PCP:
+		actionSetVlanPriority = new ActionSetVlanPriority(decode);
+		break;
+	    case ACTION_STRIP_VLAN:
+		actionStripVlan = new ActionStripVlan(decode);
+		break;
+	    case ACTION_SET_DL_SRC:
+		actionSetEthernetSrcAddr = new ActionSetEthernetAddr(decode);
+		break;
+	    case ACTION_SET_DL_DST:
+		actionSetEthernetDstAddr = new ActionSetEthernetAddr(decode);
+		break;
+	    case ACTION_SET_NW_SRC:
+		actionSetIPv4SrcAddr = new ActionSetIPv4Addr(decode);
+		break;
+	    case ACTION_SET_NW_DST:
+		actionSetIPv4DstAddr = new ActionSetIPv4Addr(decode);
+		break;
+	    case ACTION_SET_NW_TOS:
+		actionSetIpToS = new ActionSetIpToS(decode);
+		break;
+	    case ACTION_SET_TP_SRC:
+		actionSetTcpUdpSrcPort = new ActionSetTcpUdpPort(decode);
+		break;
+	    case ACTION_SET_TP_DST:
+		actionSetTcpUdpDstPort = new ActionSetTcpUdpPort(decode);
+		break;
+	    case ACTION_ENQUEUE:
+		actionEnqueue = new ActionEnqueue(decode);
+		break;
+	    case ACTION_VENDOR:
+		// TODO: Handle it as appropriate
+		break;
+	    }
+	} catch (IllegalArgumentException e) {
+	    throw new IllegalArgumentException("Invalid action string");
+	}
+    }
+}