Merged in changes from master - bug fixes
diff --git a/build.xml b/build.xml
index a4202ad..1b36535 100644
--- a/build.xml
+++ b/build.xml
@@ -69,6 +69,7 @@
 	<include name="curator-client-1.3.4-SNAPSHOT.jar"/>
 	<include name="curator-framework-1.3.4-SNAPSHOT.jar"/>
 	<include name="curator-recipes-1.3.4-SNAPSHOT.jar"/>
+	<include name="zookeeper-3.4.5.jar"/>
     </patternset>
 
     <patternset id="titanlib">
diff --git a/ctrl-add-ext-template.sh b/ctrl-add-ext-template.sh
index c8e7d25..6cbf565 100755
--- a/ctrl-add-ext-template.sh
+++ b/ctrl-add-ext-template.sh
@@ -1,5 +1,5 @@
 #! /bin/bash
-controller="localhost onos9vpc onos10vpc onos11vpc"
+controller="onos9vpc onos10vpc onos11vpc"
 me=`hostname`
 controller=`echo $controller | sed "s/$me//g"`
 switches=`ifconfig -a | grep sw |grep -v eth | awk '{print $1}'`
diff --git a/ctrl-local.sh b/ctrl-local.sh
index 79b421b..023a9db 100755
--- a/ctrl-local.sh
+++ b/ctrl-local.sh
@@ -1,5 +1,5 @@
 #! /bin/bash
-controller="localhost"
+controller=`hostname`
 switches=`ifconfig -a | grep sw |grep -v eth | awk '{print $1}'`
 
 function host2ip (){
diff --git a/mastership-test.sh b/mastership-test.sh
index 2a83b71..209ffb7 100755
--- a/mastership-test.sh
+++ b/mastership-test.sh
@@ -1,2 +1,2 @@
 #java -Dlogback.configurationFile=logback.xml -cp target/floodlight-only.jar:lib/*:lib/titan/* net.onrc.onos.registry.controller.RegistryRunner $1
-java -Dlogback.configurationFile=logback.xml -cp target/floodlight-only.jar:lib/*:lib/titan/* net.floodlightcontroller.core.Main -cf onos3.properties
+java -Dlogback.configurationFile=logback.xml -cp target/floodlight-only.jar:lib/*:lib/titan/* net.floodlightcontroller.core.Main -cf onos.properties
diff --git a/showdpid.sh b/showdpid.sh
new file mode 100755
index 0000000..91281a1
--- /dev/null
+++ b/showdpid.sh
@@ -0,0 +1,17 @@
+#! /bin/bash
+controller=""
+switches=`ifconfig -a | grep sw |grep -v eth | awk '{print $1}'`
+
+function host2ip (){
+   ip=`grep $1 /etc/hosts |grep -v "ip6"|  awk '{print $1}'`
+   echo $ip
+}
+
+url=""
+for c in $controller; do
+  url="$url tcp:`host2ip $c`:6633"
+done
+echo $url
+for s in $switches; do
+    sudo ovs-ofctl  show  $s |grep dpid
+done
diff --git a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java b/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
index 8788aa7..c70ab16 100644
--- a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
+++ b/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
@@ -193,18 +193,6 @@
 		@Property("switch_dpid")
 		public void setSwitchDpid(String switchDpid);
 
-		@Property("in_port")
-		public Short getInPort();
-
-		@Property("in_port")
-		public void setInPort(Short inPort);
-
-		@Property("out_port")
-		public Short getOutPort();
-
-		@Property("out_port")
-		public void setOutPort(Short outPort);
-
 		@Property("user_state")
 		public String getUserState();
 
@@ -228,5 +216,47 @@
 
 		@Property("error_state_code")
 		public void setErrorStateCode(String errorStateCode);
+
+		@Property("matchInPort")
+		public Short getMatchInPort();
+
+		@Property("matchInPort")
+		public void setMatchInPort(Short matchInPort);
+
+		@Property("matchEthernetFrameType")
+		public Short getMatchEthernetFrameType();
+
+		@Property("matchEthernetFrameType")
+		public void setMatchEthernetFrameType(Short matchEthernetFrameType);
+
+		@Property("matchSrcMac")
+		public String getMatchSrcMac();
+
+		@Property("matchSrcMac")
+		public void setMatchSrcMac(String matchSrcMac);
+
+		@Property("matchDstMac")
+		public String getMatchDstMac();
+
+		@Property("matchDstMac")
+		public void setMatchDstMac(String matchDstMac);
+
+		@Property("matchSrcIPv4Net")
+		public String getMatchSrcIPv4Net();
+
+		@Property("matchSrcIPv4Net")
+		public void setMatchSrcIPv4Net(String matchSrcIPv4Net);
+
+		@Property("matchDstIPv4Net")
+		public String getMatchDstIPv4Net();
+
+		@Property("matchDstIPv4Net")
+		public void setMatchDstIPv4Net(String matchDstIPv4Net);
+
+		@Property("actionOutput")
+		public Short getActionOutput();
+
+		@Property("actionOutput")
+		public void setActionOutput(Short actionOutput);
 	}
 }
diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
index 8cf1982..a604969 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
@@ -29,11 +29,15 @@
 import net.floodlightcontroller.util.Dpid;
 import net.floodlightcontroller.util.DataPathEndpoints;
 import net.floodlightcontroller.util.FlowEntry;
+import net.floodlightcontroller.util.FlowEntryAction;
 import net.floodlightcontroller.util.FlowEntryId;
+import net.floodlightcontroller.util.FlowEntryMatch;
 import net.floodlightcontroller.util.FlowEntrySwitchState;
 import net.floodlightcontroller.util.FlowEntryUserState;
 import net.floodlightcontroller.util.FlowId;
 import net.floodlightcontroller.util.FlowPath;
+import net.floodlightcontroller.util.IPv4Net;
+import net.floodlightcontroller.util.MACAddress;
 import net.floodlightcontroller.util.OFMessageDamper;
 import net.floodlightcontroller.util.Port;
 import net.onrc.onos.util.GraphDBConnection;
@@ -42,6 +46,7 @@
 import org.openflow.protocol.OFFlowMod;
 import org.openflow.protocol.OFMatch;
 import org.openflow.protocol.OFPacketOut;
+import org.openflow.protocol.OFPort;
 import org.openflow.protocol.OFType;
 import org.openflow.protocol.action.OFAction;
 import org.openflow.protocol.action.OFActionOutput;
@@ -58,10 +63,15 @@
 
     protected OFMessageDamper messageDamper;
 
-    protected static int OFMESSAGE_DAMPER_CAPACITY = 50000; // TODO: find sweet spot
-    protected static int OFMESSAGE_DAMPER_TIMEOUT = 250;	// ms
-    public static short FLOWMOD_DEFAULT_IDLE_TIMEOUT = 0;	// infinity
-    public static short FLOWMOD_DEFAULT_HARD_TIMEOUT = 0;	// infinite
+    //
+    // TODO: Values copied from elsewhere (class LearningSwitch).
+    // The local copy should go away!
+    //
+    protected static final int OFMESSAGE_DAMPER_CAPACITY = 50000; // TODO: find sweet spot
+    protected static final int OFMESSAGE_DAMPER_TIMEOUT = 250;	// ms
+    public static final short FLOWMOD_DEFAULT_IDLE_TIMEOUT = 0;	// infinity
+    public static final short FLOWMOD_DEFAULT_HARD_TIMEOUT = 0;	// infinite
+    public static final short PRIORITY_DEFAULT = 100;
 
     /** The logger. */
     private static Logger log = LoggerFactory.getLogger(FlowManager.class);
@@ -123,23 +133,69 @@
 			continue;
 		    }
 
+		    //
+		    // Fetch the match conditions
+		    //
 		    OFMatch match = new OFMatch();
-		    match.setInputPort(flowEntryObj.getInPort());
+		    match.setWildcards(OFMatch.OFPFW_ALL);
+		    Short matchInPort = flowEntryObj.getMatchInPort();
+		    if (matchInPort != null) {
+			match.setInputPort(matchInPort);
+			match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_IN_PORT);
+		    }
+		    Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
+		    if (matchEthernetFrameType != null) {
+			match.setDataLayerType(matchEthernetFrameType);
+			match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
+		    }
+		    String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
+		    if (matchSrcIPv4Net != null) {
+			match.setFromCIDR(matchSrcIPv4Net, OFMatch.STR_NW_SRC);
+		    }
+		    String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
+		    if (matchDstIPv4Net != null) {
+			match.setFromCIDR(matchDstIPv4Net, OFMatch.STR_NW_DST);
+		    }
+		    String matchSrcMac = flowEntryObj.getMatchSrcMac();
+		    if (matchSrcMac != null) {
+			match.setDataLayerSource(matchSrcMac);
+			match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_SRC);
+		    }
+		    String matchDstMac = flowEntryObj.getMatchDstMac();
+		    if (matchDstMac != null) {
+			match.setDataLayerDestination(matchDstMac);
+			match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
+		    }
 
-		    OFActionOutput action = new OFActionOutput();
-		    action.setMaxLength((short)0xffff);
-		    action.setPort(flowEntryObj.getOutPort());
+		    //
+		    // Fetch the actions
+		    //
 		    List<OFAction> actions = new ArrayList<OFAction>();
-		    actions.add(action);
+		    Short actionOutputPort = flowEntryObj.getActionOutput();
+		    if (actionOutputPort != null) {
+			OFActionOutput action = new OFActionOutput();
+			// XXX: The max length is hard-coded for now
+			action.setMaxLength((short)0xffff);
+			action.setPort(actionOutputPort);
+			actions.add(action);
+		    }
 
 		    fm.setIdleTimeout(FLOWMOD_DEFAULT_IDLE_TIMEOUT)
 			.setHardTimeout(FLOWMOD_DEFAULT_HARD_TIMEOUT)
+			.setPriority(PRIORITY_DEFAULT)
 			.setBufferId(OFPacketOut.BUFFER_ID_NONE)
 			.setCookie(cookie)
 			.setCommand(flowModCommand)
 			.setMatch(match)
 			.setActions(actions)
 			.setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
+		    fm.setOutPort(OFPort.OFPP_NONE.getValue());
+		    if ((flowModCommand == OFFlowMod.OFPFC_DELETE) ||
+			(flowModCommand == OFFlowMod.OFPFC_DELETE_STRICT)) {
+			if (actionOutputPort != null)
+			    fm.setOutPort(actionOutputPort);
+		    }
+
 		    //
 		    // TODO: Set the following flag
 		    // fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
@@ -351,15 +407,35 @@
 	    // - flowEntry.flowEntryMatch()
 	    // - flowEntry.flowEntryActions()
 	    // - flowEntry.dpid()
-	    // - flowEntry.inPort()
-	    // - flowEntry.outPort()
 	    // - flowEntry.flowEntryUserState()
 	    // - flowEntry.flowEntrySwitchState()
 	    // - flowEntry.flowEntryErrorState()
+	    // - flowEntry.matchInPort()
+	    // - flowEntry.matchEthernetFrameType()
+	    // - flowEntry.matchSrcIPv4Net()
+	    // - flowEntry.matchDstIPv4Net()
+	    // - flowEntry.matchSrcMac()
+	    // - flowEntry.matchDstMac()
+	    // - flowEntry.actionOutput()
 	    //
 	    flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
-	    flowEntryObj.setInPort(flowEntry.inPort().value());
-	    flowEntryObj.setOutPort(flowEntry.outPort().value());
+	    if (flowEntry.flowEntryMatch().matchInPort())
+		flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
+	    if (flowEntry.flowEntryMatch().matchEthernetFrameType())
+		flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
+	    if (flowEntry.flowEntryMatch().matchSrcIPv4Net())
+		flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
+	    if (flowEntry.flowEntryMatch().matchDstIPv4Net())
+		flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
+	    if (flowEntry.flowEntryMatch().matchSrcMac())
+		flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
+	    if (flowEntry.flowEntryMatch().matchDstMac())
+		flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
+
+	    for (FlowEntryAction fa : flowEntry.flowEntryActions()) {
+		if (fa.actionOutput() != null)
+		    flowEntryObj.setActionOutput(fa.actionOutput().port().value());
+	    }
 	    // TODO: Hacks with hard-coded state names!
 	    if (found)
 		flowEntryObj.setUserState("FE_USER_MODIFY");
@@ -640,8 +716,43 @@
 	    FlowEntry flowEntry = new FlowEntry();
 	    flowEntry.setFlowEntryId(new FlowEntryId(flowEntryObj.getFlowEntryId()));
 	    flowEntry.setDpid(new Dpid(flowEntryObj.getSwitchDpid()));
-	    flowEntry.setInPort(new Port(flowEntryObj.getInPort()));
-	    flowEntry.setOutPort(new Port(flowEntryObj.getOutPort()));
+
+	    //
+	    // Extract the match conditions
+	    //
+	    FlowEntryMatch match = new FlowEntryMatch();
+	    Short matchInPort = flowEntryObj.getMatchInPort();
+	    if (matchInPort != null)
+		match.enableInPort(new Port(matchInPort));
+	    Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
+	    if (matchEthernetFrameType != null)
+		match.enableEthernetFrameType(matchEthernetFrameType);
+	    String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
+	    if (matchSrcIPv4Net != null)
+		match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
+	    String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
+	    if (matchDstIPv4Net != null)
+		match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
+	    String matchSrcMac = flowEntryObj.getMatchSrcMac();
+	    if (matchSrcMac != null)
+		match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
+	    String matchDstMac = flowEntryObj.getMatchDstMac();
+	    if (matchDstMac != null)
+		match.enableDstMac(MACAddress.valueOf(matchDstMac));
+	    flowEntry.setFlowEntryMatch(match);
+
+	    //
+	    // Extract the actions
+	    //
+	    ArrayList<FlowEntryAction> actions = new ArrayList<FlowEntryAction>();
+	    Short actionOutputPort = flowEntryObj.getActionOutput();
+	    if (actionOutputPort != null) {
+		FlowEntryAction action = new FlowEntryAction();
+		action.setActionOutput(new Port(actionOutputPort));
+		actions.add(action);
+	    }
+	    flowEntry.setFlowEntryActions(actions);
+
 	    String userState = flowEntryObj.getUserState();
 	    flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
 	    String switchState = flowEntryObj.getSwitchState();
diff --git a/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java b/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java
index 304bb5c..1fc1783 100644
--- a/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java
+++ b/src/main/java/net/floodlightcontroller/util/FlowEntryAction.java
@@ -54,6 +54,15 @@
 				// if the port is set to PORT_CONTROLLER
 
 	/**
+	 * Default constructor.
+	 */
+	public ActionOutput() {
+	    this.port = null;
+	    this.maxLen = 0;
+	}
+
+
+	/**
 	 * Constructor for a given output port and maximum length.
 	 *
 	 * @param port the output port to set.
@@ -66,6 +75,16 @@
 	}
 
 	/**
+	 * 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.
@@ -113,11 +132,18 @@
 	private short vlanId;		// The VLAN ID to set
 
 	/**
+	 * Default constructor.
+	 */
+	public ActionSetVlanId() {
+	    this.vlanId = 0;
+	}
+
+	/**
 	 * Constructor for a given VLAN ID.
 	 *
 	 * @param vlanId the VLAN ID to set.
 	 */
-	ActionSetVlanId(short vlanId) {
+	public ActionSetVlanId(short vlanId) {
 	    this.vlanId = vlanId;
 	}
 
@@ -156,11 +182,18 @@
 	private byte vlanPriority;	// The VLAN priority to set
 
 	/**
+	 * Default constructor.
+	 */
+	public ActionSetVlanPriority() {
+	    this.vlanPriority = 0;
+	}
+
+	/**
 	 * Constructor for a given VLAN priority.
 	 *
 	 * @param vlanPriority the VLAN priority to set.
 	 */
-	ActionSetVlanPriority(byte vlanPriority) {
+	public ActionSetVlanPriority(byte vlanPriority) {
 	    this.vlanPriority = vlanPriority;
 	}
 
@@ -199,11 +232,18 @@
 	private boolean stripVlan;	// If true, strip the VLAN header
 
 	/**
+	 * Default constructor.
+	 */
+	public ActionStripVlan() {
+	    this.stripVlan = false;
+	}
+
+	/**
 	 * Constructor for a given boolean flag.
 	 *
 	 * @param stripVlan if true, strip the VLAN header.
 	 */
-	ActionStripVlan(boolean stripVlan) {
+	public ActionStripVlan(boolean stripVlan) {
 	    this.stripVlan = stripVlan;
 	}
 
@@ -243,11 +283,18 @@
 	private MACAddress addr;	// The MAC address to set
 
 	/**
+	 * Default constructor.
+	 */
+	public ActionSetEthernetAddr() {
+	    this.addr = null;
+	}
+
+	/**
 	 * Constructor for a given MAC address.
 	 *
 	 * @param addr the MAC address to set.
 	 */
-	ActionSetEthernetAddr(MACAddress addr) {
+	public ActionSetEthernetAddr(MACAddress addr) {
 	    this.addr = addr;
 	}
 
@@ -287,11 +334,18 @@
 	private IPv4 addr;		// The IPv4 address to set
 
 	/**
+	 * Default constructor.
+	 */
+	public ActionSetIPv4Addr() {
+	    this.addr = null;
+	}
+
+	/**
 	 * Constructor for a given IPv4 address.
 	 *
 	 * @param addr the IPv4 address to set.
 	 */
-	ActionSetIPv4Addr(IPv4 addr) {
+	public ActionSetIPv4Addr(IPv4 addr) {
 	    this.addr = addr;
 	}
 
@@ -331,11 +385,18 @@
 	private byte ipToS;	// The IP ToS to set DSCP field, 6 bits)
 
 	/**
+	 * Default constructor.
+	 */
+	public ActionSetIpToS() {
+	    this.ipToS = 0;
+	}
+
+	/**
 	 * Constructor for a given IP ToS (DSCP field, 6 bits).
 	 *
 	 * @param ipToS the IP ToS (DSCP field, 6 bits) to set.
 	 */
-	ActionSetIpToS(byte ipToS) {
+	public ActionSetIpToS(byte ipToS) {
 	    this.ipToS = ipToS;
 	}
 
@@ -375,11 +436,18 @@
 	private short port;		// The TCP/UDP port to set
 
 	/**
+	 * Default constructor.
+	 */
+	public ActionSetTcpUdpPort() {
+	    this.port = 0;
+	}
+
+	/**
 	 * Constructor for a given TCP/UDP port.
 	 *
 	 * @param port the TCP/UDP port to set.
 	 */
-	ActionSetTcpUdpPort(short port) {
+	public ActionSetTcpUdpPort(short port) {
 	    this.port = port;
 	}
 
@@ -421,6 +489,14 @@
 	private int queueId;	// Where to enqueue the packets
 
 	/**
+	 * Default constructor.
+	 */
+	public ActionEnqueue() {
+	    this.port = null;
+	    this.queueId = 0;
+	}
+
+	/**
 	 * Constructor for a given port and queue ID.
 	 *
 	 * @param port the port to set.
@@ -515,11 +591,21 @@
     /**
      * Set the output action on a port.
      *
-     * @param port the output port to set.
+     * @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, (short)0);
+	actionOutput = new ActionOutput(port);
 	actionType = ActionValues.ACTION_OUTPUT;
     }
 
@@ -528,7 +614,6 @@
      *
      * @param maxLen the maximum length (in bytes) to send to controller.
      */
-    @JsonProperty("actionOutputToController")
     public void setActionOutputToController(short maxLen) {
 	Port port = new Port(Port.PortValues.PORT_CONTROLLER);
 	actionOutput = new ActionOutput(port, maxLen);
@@ -546,9 +631,19 @@
     /**
      * Set the action to set the VLAN ID.
      *
-     * @param vlanId the VLAN ID to set.
+     * @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;
@@ -567,9 +662,19 @@
     /**
      * Set the action to set the VLAN priority.
      *
-     * @param vlanPriority the VLAN priority to set.
+     * @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;
@@ -588,9 +693,19 @@
     /**
      * Set the action to strip the VLAN header.
      *
-     * @param stripVlan if true, 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;
@@ -609,9 +724,19 @@
     /**
      * Set the action to set the Ethernet source address.
      *
-     * @param addr the MAC address to set as 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;
@@ -630,9 +755,19 @@
     /**
      * Set the action to set the Ethernet destination address.
      *
-     * @param addr the MAC address to set as 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;
@@ -651,9 +786,19 @@
     /**
      * Set the action to set the IPv4 source address.
      *
-     * @param addr the IPv4 address to set as 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;
@@ -672,9 +817,19 @@
     /**
      * Set the action to set the IPv4 destination address.
      *
-     * @param addr the IPv4 address to set as 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;
@@ -693,9 +848,19 @@
     /**
      * Set the action to set the IP ToS (DSCP field, 6 bits).
      *
-     * @param ipToS the IP ToS (DSCP field, 6 bits) to set.
+     * @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;
@@ -714,9 +879,19 @@
     /**
      * Set the action to set the TCP/UDP source port.
      *
-     * @param port the TCP/UDP port to set as 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;
@@ -735,9 +910,19 @@
     /**
      * Set the action to set the TCP/UDP destination port.
      *
-     * @param port the TCP/UDP port to set as 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;
@@ -754,10 +939,20 @@
     /**
      * 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 int queueId the queue ID to set.
      */
-    @JsonProperty("actionEnqueue")
     public void setActionEnqueue(Port port, int queueId) {
 	actionEnqueue = new ActionEnqueue(port, queueId);
 	actionType = ActionValues.ACTION_ENQUEUE;
diff --git a/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java b/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
index af58eea..c9ed160 100644
--- a/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
+++ b/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
@@ -228,8 +228,10 @@
 		String latchPath = switchLatchesPath + "/" + dpidStr;
 		
 		if (switchLatches.get(dpidStr) != null){
-			throw new RuntimeException("Leader election for switch " + dpidStr +
-					"is already running");
+			//throw new RuntimeException("Leader election for switch " + dpidStr +
+			//		"is already running");
+			log.debug("Already contesting {}, returning", HexString.toHexString(dpid));
+			return;
 		}
 		
 		LeaderLatch latch = new LeaderLatch(client, latchPath, controllerId);
diff --git a/src/main/java/org/openflow/protocol/OFMatch.java b/src/main/java/org/openflow/protocol/OFMatch.java
index 0336d7d..397263d 100644
--- a/src/main/java/org/openflow/protocol/OFMatch.java
+++ b/src/main/java/org/openflow/protocol/OFMatch.java
@@ -911,7 +911,7 @@
      *            one of STR_NW_DST or STR_NW_SRC
      * @throws IllegalArgumentException
      */
-    private void setFromCIDR(String cidr, String which)
+    public void setFromCIDR(String cidr, String which)
             throws IllegalArgumentException {
         String values[] = cidr.split("/");
         String[] ip_str = values[0].split("\\.");
diff --git a/start-onos.sh b/start-onos.sh
index f8e9309..012a994 100755
--- a/start-onos.sh
+++ b/start-onos.sh
@@ -78,7 +78,7 @@
   # Run floodlight
   echo "Starting ONOS controller ..."
   echo 
-  java ${JVM_OPTS} -Dlogback.configurationFile=${FL_LOGBACK} -jar ${FL_JAR} -cf ./onos.properties > /dev/null 2>&1 &
+  java ${JVM_OPTS} -Dlogback.configurationFile=${FL_LOGBACK} -jar ${FL_JAR} -cf ${FL_HOME}/onos.properties > /dev/null 2>&1 &
 #  echo "java ${JVM_OPTS} -Dlogback.configurationFile=${FL_LOGBACK} -jar ${FL_JAR} -cf ./onos.properties > /dev/null 2>&1 &"
   sudo -b /usr/sbin/tcpdump -n -i eth0 -s0 -w ${PCAP_LOG} 'tcp port 6633' > /dev/null  2>&1
 }
diff --git a/test-network/mininet/net.sprint5-templete.py b/test-network/mininet/net.sprint5-templete.py
new file mode 100755
index 0000000..0fc96f1
--- /dev/null
+++ b/test-network/mininet/net.sprint5-templete.py
@@ -0,0 +1,153 @@
+#!/usr/bin/python
+
+NWID=1
+NR_NODES=20
+#Controllers=[{"ip":'127.0.0.1', "port":6633}, {"ip":'10.0.1.28', "port":6633}]
+Controllers=[{"ip":'10.0.1.28', "port":6633}]
+
+"""
+Start up a Simple topology
+"""
+from mininet.net import Mininet
+from mininet.node import Controller, RemoteController
+from mininet.log import setLogLevel, info, error, warn, debug
+from mininet.cli import CLI
+from mininet.topo import Topo
+from mininet.util import quietRun
+from mininet.moduledeps import pathCheck
+from mininet.link import Link, TCLink
+
+from sys import exit
+import os.path
+from subprocess import Popen, STDOUT, PIPE
+
+import sys
+
+#import argparse
+
+class MyController( Controller ):
+    def __init__( self, name, ip='127.0.0.1', port=6633, **kwargs):
+        """Init.
+           name: name to give controller
+           ip: the IP address where the remote controller is
+           listening
+           port: the port where the remote controller is listening"""
+        Controller.__init__( self, name, ip=ip, port=port, **kwargs )
+
+    def start( self ):
+        "Overridden to do nothing."
+        return
+
+    def stop( self ):
+        "Overridden to do nothing."
+        return
+
+    def checkListening( self ):
+        "Warn if remote controller is not accessible"
+        listening = self.cmd( "echo A | telnet -e A %s %d" %
+                              ( self.ip, self.port ) )
+        if 'Unable' in listening:
+            warn( "Unable to contact the remote controller"
+                  " at %s:%d\n" % ( self.ip, self.port ) )
+
+class SDNTopo( Topo ):
+    "SDN Topology"
+
+    def __init__( self, *args, **kwargs ):
+        Topo.__init__( self, *args, **kwargs )
+
+        switch = []
+        host = []
+        root = []
+
+        for i in range (NR_NODES):
+            name_suffix = '%02d' % NWID + "." + '%02d' % i
+            dpid_suffix = '%02x' % NWID + '%02x' % i
+            dpid = '0000' + '0000' + '0000' + dpid_suffix
+            sw = self.addSwitch('sw'+name_suffix, dpid=dpid)
+            switch.append(sw)
+
+        for i in range (NR_NODES):
+            host.append(self.addHost( 'host%d' % i ))
+
+        for i in range (NR_NODES):
+            root.append(self.addHost( 'root%d' % i, inNamespace=False ))
+
+        for i in range (NR_NODES):
+            self.addLink(host[i], switch[i])
+
+        for i in range (1, NR_NODES):
+            self.addLink(switch[0], switch[i])
+
+        for i in range (NR_NODES):
+            self.addLink(root[i], host[i])
+
+def startsshd( host ):
+    "Start sshd on host"
+    info( '*** Starting sshd\n' )
+    name, intf, ip = host.name, host.defaultIntf(), host.IP()
+    banner = '/tmp/%s.banner' % name
+    host.cmd( 'echo "Welcome to %s at %s" >  %s' % ( name, ip, banner ) )
+    host.cmd( '/usr/sbin/sshd -o "Banner %s"' % banner, '-o "UseDNS no"' )
+    info( '***', host.name, 'is running sshd on', intf, 'at', ip, '\n' )
+
+def startsshds ( hosts ):
+    for h in hosts:
+        startsshd( h )
+
+def stopsshd( ):
+    "Stop *all* sshd processes with a custom banner"
+    info( '*** Shutting down stale sshd/Banner processes ',
+          quietRun( "pkill -9 -f Banner" ), '\n' )
+
+def sdnnet(opt):
+    topo = SDNTopo()
+    info( '*** Creating network\n' )
+    #net = Mininet( topo=topo, controller=MyController, link=TCLink)
+    net = Mininet( topo=topo, link=TCLink, build=False)
+    controllers=[]
+    for c in Controllers:
+      rc = RemoteController('c%d' % Controllers.index(c), ip=c['ip'],port=c['port'])
+      print "controller ip %s port %s" % (c['ip'], c['port'])
+      controllers.append(rc)
+  
+    net.controllers=controllers
+    net.build()
+
+    host = []
+    for i in range (NR_NODES):
+      host.append(net.get( 'host%d' % i ))
+
+    net.start()
+
+    sw=net.get('sw01.00')
+    print "center sw", sw
+    sw.attach('tapa0')
+
+    for i in range (NR_NODES):
+        host[i].defaultIntf().setIP('192.168.%d.%d/16' % (NWID,i)) 
+
+    root = []
+    for i in range (NR_NODES):
+        root.append(net.get( 'root%d' % i ))
+
+    for i in range (NR_NODES):
+        host[i].intf('host%d-eth1' % i).setIP('1.1.%d.1/24' % i)
+        root[i].intf('root%d-eth0' % i).setIP('1.1.%d.2/24' % i)
+
+    stopsshd ()
+    startsshds ( host )
+
+    if opt=="cli":
+        CLI(net)
+        stopsshd()
+        net.stop()
+
+if __name__ == '__main__':
+    setLogLevel( 'info' )
+    if len(sys.argv) == 1:
+      sdnnet("cli")
+    elif len(sys.argv) == 2 and sys.argv[1] == "-n":
+      sdnnet("nocli")
+    else:
+      print "%s [-n]" % sys.argv[0]
diff --git a/web/add_flow.py b/web/add_flow.py
index 18846b7..7adaf98 100755
--- a/web/add_flow.py
+++ b/web/add_flow.py
@@ -1,6 +1,7 @@
 #! /usr/bin/env python
 # -*- Mode: python; py-indent-offset: 4; tab-width: 8; indent-tabs-mode: t; -*-
 
+import copy
 import pprint
 import os
 import sys
@@ -84,7 +85,36 @@
     exit(1)
 
 if __name__ == "__main__":
-  usage_msg = "Usage: %s <flow-id> <installer-id> <src-dpid> <src-port> <dest-dpid> <dest-port>" % (sys.argv[0])
+  usage_msg = "Usage: %s <flow-id> <installer-id> <src-dpid> <src-port> <dest-dpid> <dest-port> [Match Conditions] [Actions]\n" % (sys.argv[0])
+  usage_msg = usage_msg + "    Match Conditions:\n"
+  usage_msg = usage_msg + "        matchInPort <True|False> (default to True)\n"
+  usage_msg = usage_msg + "        matchSrcMac <source MAC address>\n"
+  usage_msg = usage_msg + "        matchDstMac <destination MAC address>\n"
+  usage_msg = usage_msg + "        matchSrcIPv4Net <source IPv4 network address>\n"
+  usage_msg = usage_msg + "        matchDstIPv4Net <destination IPv4 network address>\n"
+  usage_msg = usage_msg + "        matchEthernetFrameType <Ethernet frame type>\n"
+
+  usage_msg = usage_msg + "    Match Conditions (not implemented yet):\n"
+  usage_msg = usage_msg + "        matchVlanId <VLAN ID>\n"
+  usage_msg = usage_msg + "        matchVlanPriority <VLAN priority>\n"
+  usage_msg = usage_msg + "        matchIpToS <IP ToS (DSCP field, 6 bits)>\n"
+  usage_msg = usage_msg + "        matchIpProto <IP protocol>\n"
+  usage_msg = usage_msg + "        matchSrcTcpUdpPort <source TCP/UDP port>\n"
+  usage_msg = usage_msg + "        matchDstTcpUdpPort <destination TCP/UDP port>\n"
+  usage_msg = usage_msg + "    Actions:\n"
+  usage_msg = usage_msg + "        actionOutput <True|False> (default to True)\n"
+  usage_msg = usage_msg + "        actionSetEthernetSrcAddr <source MAC address>\n"
+  usage_msg = usage_msg + "        actionSetEthernetDstAddr <destination MAC address>\n"
+  usage_msg = usage_msg + "        actionSetIPv4SrcAddr <source IPv4 address>\n"
+  usage_msg = usage_msg + "        actionSetIPv4DstAddr <destination IPv4 address>\n"
+  usage_msg = usage_msg + "    Actions (not implemented yet):\n"
+  usage_msg = usage_msg + "        actionSetVlanId <VLAN ID>\n"
+  usage_msg = usage_msg + "        actionSetVlanPriority <VLAN priority>\n"
+  usage_msg = usage_msg + "        actionSetIpToS <IP ToS (DSCP field, 6 bits)>\n"
+  usage_msg = usage_msg + "        actionSetTcpUdpSrcPort <source TCP/UDP port>\n"
+  usage_msg = usage_msg + "        actionSetTcpUdpDstPort <destination TCP/UDP port>\n"
+  usage_msg = usage_msg + "        actionStripVlan <True|False>\n"
+  usage_msg = usage_msg + "        actionEnqueue <dummy argument>\n"
 
   # app.debug = False;
 
@@ -98,10 +128,16 @@
     log_error(usage_msg)
     exit(1)
 
-  # Do the work
+  # Extract the mandatory arguments
   my_flow_id = sys.argv[1]
-  my_installer_id = sys.argv[2];	# 'ONOS-Path-Computation-Python'
-  data_path = shortest_path(sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6])
+  my_installer_id = sys.argv[2]
+  my_src_dpid = sys.argv[3]
+  my_src_port = sys.argv[4]
+  my_dst_dpid = sys.argv[5]
+  my_dst_port = sys.argv[6]
+
+  # Compute the shortest path
+  data_path = shortest_path(my_src_dpid, my_src_port, my_dst_dpid, my_dst_port)
 
   debug("Data Path: %s" % data_path)
 
@@ -113,6 +149,214 @@
   flow_path = {}
   flow_path['flowId'] = flow_id
   flow_path['installerId'] = installer_id
+
+  #
+  # Extract the "match" and "action" arguments
+  #
+  idx = 7
+  match = {}
+  matchInPortEnabled = True		# NOTE: Enabled by default
+  actions = []
+  actionOutputEnabled = True		# NOTE: Enabled by default
+  while idx < len(sys.argv):
+    action = {}
+    arg1 = sys.argv[idx]
+    idx = idx + 1
+    # Extract the second argument
+    if idx >= len(sys.argv):
+      error_arg = "ERROR: Missing or invalid '" + arg1 + "' argument"
+      log_error(error_arg)
+      log_error(usage_msg)
+      exit(1)
+    arg2 = sys.argv[idx]
+    idx = idx + 1
+
+    if arg1 == "matchInPort":
+      # Just mark whether inPort matching is enabled
+      matchInPortEnabled = arg2 in ['True', 'true']
+      # inPort = {}
+      # inPort['value'] = int(arg2, 0)
+      # match['inPort'] = inPort
+      ## match['matchInPort'] = True
+    elif arg1 == "matchSrcMac":
+      srcMac = {}
+      srcMac['value'] = arg2
+      match['srcMac'] = srcMac
+      # match['matchSrcMac'] = True
+    elif arg1 == "matchDstMac":
+      dstMac = {}
+      dstMac['value'] = arg2
+      match['dstMac'] = dstMac
+      # match['matchDstMac'] = True
+    elif arg1 == "matchVlanId":
+      match['vlanId'] = int(arg2, 0)
+      # match['matchVlanId'] = True
+    elif arg1 == "matchVlanPriority":
+      match['vlanPriority'] = int(arg2, 0)
+      # match['matchVlanPriority'] = True
+    elif arg1 == "matchEthernetFrameType":
+      match['ethernetFrameType'] = int(arg2, 0)
+      # match['matchEthernetFrameType'] = True
+    elif arg1 == "matchIpToS":
+      match['ipToS'] = int(arg2, 0)
+      # match['matchIpToS'] = True
+    elif arg1 == "matchIpProto":
+      match['ipProto'] = int(arg2, 0)
+      # match['matchIpProto'] = True
+    elif arg1 == "matchSrcIPv4Net":
+      srcIPv4Net = {}
+      srcIPv4Net['value'] = arg2
+      match['srcIPv4Net'] = srcIPv4Net
+      # match['matchSrcIPv4Net'] = True
+    elif arg1 == "matchDstIPv4Net":
+      dstIPv4Net = {}
+      dstIPv4Net['value'] = arg2
+      match['dstIPv4Net'] = dstIPv4Net
+      # match['matchDstIPv4Net'] = True
+    elif arg1 == "matchSrcTcpUdpPort":
+      match['srcTcpUdpPort'] = int(arg2, 0)
+      # match['matchSrcTcpUdpPort'] = True
+    elif arg1 == "matchDstTcpUdpPort":
+      match['dstTcpUdpPort'] = int(arg2, 0)
+      # match['matchDstTcpUdpPort'] = True
+    elif arg1 == "actionOutput":
+      # Just mark whether ACTION_OUTPUT action is enabled
+      actionOutputEnabled = arg2 in ['True', 'true']
+      #
+      # TODO: Complete the implementation for ACTION_OUTPUT
+      #   actionOutput = {}
+      #   outPort = {}
+      #   outPort['value'] = int(arg2, 0)
+      #   actionOutput['port'] = outPort
+      #   actionOutput['maxLen'] = int(arg3, 0)
+      #   action['actionOutput'] = actionOutput
+      #   # action['actionType'] = 'ACTION_OUTPUT'
+      #   actions.append(action)
+      #
+    elif arg1 == "actionSetVlanId":
+      vlanId = {}
+      vlanId['vlanId'] = int(arg2, 0)
+      action['actionSetVlanId'] = vlanId
+      # action['actionType'] = 'ACTION_SET_VLAN_VID'
+      actions.append(copy.deepcopy(action))
+    elif arg1 == "actionSetVlanPriority":
+      vlanPriority = {}
+      vlanPriority['vlanPriority'] = int(arg2, 0)
+      action['actionSetVlanPriority'] = vlanPriority
+      # action['actionType'] = 'ACTION_SET_VLAN_PCP'
+      actions.append(copy.deepcopy(action))
+    elif arg1 == "actionSetIpToS":
+      ipToS = {}
+      ipToS['ipToS'] = int(arg2, 0)
+      action['actionSetIpToS'] = ipToS
+      # action['actionType'] = 'ACTION_SET_NW_TOS'
+      actions.append(copy.deepcopy(action))
+    elif arg1 == "actionSetTcpUdpSrcPort":
+      tcpUdpSrcPort = {}
+      tcpUdpSrcPort['port'] = int(arg2, 0)
+      action['actionSetTcpUdpSrcPort'] = tcpUdpSrcPort
+      # action['actionType'] = 'ACTION_SET_TP_SRC'
+      actions.append(copy.deepcopy(action))
+    elif arg1 == "actionSetTcpUdpDstPort":
+      tcpUdpDstPort = {}
+      tcpUdpDstPort['port'] = int(arg2, 0)
+      action['actionSetTcpUdpDstPort'] = tcpUdpDstPort
+      # action['actionType'] = 'ACTION_SET_TP_DST'
+      actions.append(copy.deepcopy(action))
+    elif arg1 == "actionStripVlan":
+      stripVlan = {}
+      stripVlan['stripVlan'] = arg2 in ['True', 'true']
+      action['actionStripVlan'] = stripVlan
+      # action['actionType'] = 'ACTION_STRIP_VLAN'
+      actions.append(copy.deepcopy(action))
+    elif arg1 == "actionSetEthernetSrcAddr":
+      ethernetSrcAddr = {}
+      ethernetSrcAddr['value'] = arg2
+      setEthernetSrcAddr = {}
+      setEthernetSrcAddr['addr'] = ethernetSrcAddr
+      action['actionSetEthernetSrcAddr'] = setEthernetSrcAddr
+      # action['actionType'] = 'ACTION_SET_DL_SRC'
+      actions.append(copy.deepcopy(action))
+    elif arg1 == "actionSetEthernetDstAddr":
+      ethernetDstAddr = {}
+      ethernetDstAddr['value'] = arg2
+      setEthernetDstAddr = {}
+      setEthernetDstAddr['addr'] = ethernetDstAddr
+      action['actionSetEthernetDstAddr'] = setEthernetDstAddr
+      # action['actionType'] = 'ACTION_SET_DL_DST'
+      actions.append(copy.deepcopy(action))
+    elif arg1 == "actionSetIPv4SrcAddr":
+      IPv4SrcAddr = {}
+      IPv4SrcAddr['value'] = arg2
+      setIPv4SrcAddr = {}
+      setIPv4SrcAddr['addr'] = IPv4SrcAddr
+      action['actionSetIPv4SrcAddr'] = setIPv4SrcAddr
+      # action['actionType'] = 'ACTION_SET_NW_SRC'
+      actions.append(copy.deepcopy(action))
+    elif arg1 == "actionSetIPv4DstAddr":
+      IPv4DstAddr = {}
+      IPv4DstAddr['value'] = arg2
+      setIPv4DstAddr = {}
+      setIPv4DstAddr['addr'] = IPv4DstAddr
+      action['actionSetIPv4DstAddr'] = setIPv4DstAddr
+      # action['actionType'] = 'ACTION_SET_NW_DST'
+      actions.append(copy.deepcopy(action))
+    elif arg1 == "actionEnqueue":
+      # TODO: Implement ACTION_ENQUEUE
+      actionEnqueue = {}
+      #   actionEnqueue['queueId'] = int(arg2, 0)
+      #   enqueuePort = {}
+      #   enqueuePort['value'] = int(arg3, 0)
+      #   actionEnqueue['port'] = enqueuePort
+      #   action['actionEnqueue'] = actionEnqueue
+      #   # action['actionType'] = 'ACTION_ENQUEUE'
+      #   actions.append(copy.deepcopy(action))
+      #
+    else:
+      log_error("ERROR: Unknown argument '%s'" % (arg1))
+      log_error(usage_msg)
+      exit(1)
+
+
+  #
+  # Add the match conditions to each flow entry
+  #
+  if (len(match) > 0) or matchInPortEnabled:
+    idx = 0
+    while idx < len(data_path['flowEntries']):
+      if matchInPortEnabled:
+	inPort = data_path['flowEntries'][idx]['inPort']
+	match['inPort'] = copy.deepcopy(inPort)
+	# match['matchInPort'] = True
+      data_path['flowEntries'][idx]['flowEntryMatch'] = copy.deepcopy(match)
+      idx = idx + 1
+
+  #
+  # Set the actions for each flow entry
+  # NOTE: The actions from the command line are aplied
+  # ONLY to the first flow entry.
+  #
+  # If ACTION_OUTPUT action is enabled, then apply it
+  # to each flow entry.
+  #
+  if (len(actions) > 0) or actionOutputEnabled:
+    idx = 0
+    while idx < len(data_path['flowEntries']):
+      if idx > 0:
+	actions = []	# Reset the actions for all but first entry
+      action = {}
+      outPort = data_path['flowEntries'][idx]['outPort']
+      actionOutput = {}
+      actionOutput['port'] = copy.deepcopy(outPort)
+      # actionOutput['maxLen'] = 0	# TODO: not used for now
+      action['actionOutput'] = copy.deepcopy(actionOutput)
+      # action['actionType'] = 'ACTION_OUTPUT'
+      actions.append(copy.deepcopy(action))
+
+      data_path['flowEntries'][idx]['flowEntryActions'] = copy.deepcopy(actions)
+      idx = idx + 1
+
+
   flow_path['dataPath'] = data_path
 
   flow_path_json = json.dumps(flow_path)
diff --git a/web/delete_flow.py b/web/delete_flow.py
index f6f3d39..412d02f 100755
--- a/web/delete_flow.py
+++ b/web/delete_flow.py
@@ -59,4 +59,5 @@
     exit(1)
 
   # Do the work
-  delete_flow_path(sys.argv[1]);
+  flow_id_arg = int(sys.argv[1], 0)
+  delete_flow_path(flow_id_arg);
diff --git a/web/get_flow.py b/web/get_flow.py
index dd6a8b6..fdaa10b 100755
--- a/web/get_flow.py
+++ b/web/get_flow.py
@@ -44,104 +44,114 @@
   print "FlowPath: (flowId = %s installerId = %s src = %s/%s dst = %s/%s)" % (flowId, installerId, srcSwitch, srcPort, dstSwitch, dstPort)
 
   for f in parsedResult['dataPath']['flowEntries']:
-    inPort = f['inPort']['value']
-    outPort = f['outPort']['value']
     dpid = f['dpid']['value']
     userState = f['flowEntryUserState']
     switchState = f['flowEntrySwitchState']
     match = f['flowEntryMatch'];
     actions = f['flowEntryActions']
-    print "  FlowEntry: (%s, %s, %s, %s, %s)" % (inPort, dpid, outPort, userState, switchState)
+    print "  FlowEntry: (%s, %s, %s)" % (dpid, userState, switchState)
 
-    inPort = match['inPort']
-    matchInPort = match['matchInPort']
-    srcMac = match['srcMac']
-    matchSrcMac = match['matchSrcMac']
-    dstMac = match['dstMac']
-    matchDstMac = match['matchDstMac']
-    vlanId = match['vlanId']
-    matchVlanId = match['matchVlanId']
-    vlanPriority = match['vlanPriority']
-    matchVlanPriority = match['matchVlanPriority']
-    ethernetFrameType = match['ethernetFrameType']
-    matchEthernetFrameType = match['matchEthernetFrameType']
-    ipToS = match['ipToS']
-    matchIpToS = match['matchIpToS']
-    ipProto = match['ipProto']
-    matchIpProto = match['matchIpProto']
-    srcIPv4Net = match['srcIPv4Net']
-    matchSrcIPv4Net = match['matchSrcIPv4Net']
-    dstIPv4Net = match['dstIPv4Net']
-    matchDstIPv4Net = match['matchDstIPv4Net']
-    srcTcpUdpPort = match['srcTcpUdpPort']
-    matchSrcTcpUdpPort = match['matchSrcTcpUdpPort']
-    dstTcpUdpPort = match['dstTcpUdpPort']
-    matchDstTcpUdpPort = match['matchDstTcpUdpPort']
-    if matchInPort == True:
-      print "    inPort: %s" % inPort['value']
-    if matchSrcMac == True:
-      print "    srcMac: %s" % srcMac['value']
-    if matchDstMac == True:
-      print "    dstMac: %s" % dstMac['value']
-    if matchVlanId == True:
-      print "    vlanId: %s" % vlanId
-    if matchVlanPriority == True:
-      print "    vlanPriority: %s" % vlanPriority
-    if matchEthernetFrameType == True:
-      print "    ethernetFrameType: %s" % ethernetFrameType
-    if matchIpToS == True:
-      print "    ipToS: %s" % ipToS
-    if matchIpProto == True:
-      print "    ipProto: %s" % ipProto
-    if matchSrcIPv4Net == True:
-      print "    srcIPv4Net: %s" % srcIPv4Net['value']
-    if matchDstIPv4Net == True:
-      print "    dstIPv4Net: %s" % dstIPv4Net['value']
-    if matchSrcTcpUdpPort == True:
-      print "    srcTcpUdpPort: %s" % srcTcpUdpPort
-    if matchDstTcpUdpPort == True:
-      print "    dstTcpUdpPort: %s" % dstTcpUdpPort
+    #
+    # Print the match conditions
+    #
+    if match == None:
+      print "   Match: %s" % (match)
+    else:
+      inPort = match['inPort']
+      matchInPort = match['matchInPort']
+      srcMac = match['srcMac']
+      matchSrcMac = match['matchSrcMac']
+      dstMac = match['dstMac']
+      matchDstMac = match['matchDstMac']
+      vlanId = match['vlanId']
+      matchVlanId = match['matchVlanId']
+      vlanPriority = match['vlanPriority']
+      matchVlanPriority = match['matchVlanPriority']
+      ethernetFrameType = match['ethernetFrameType']
+      matchEthernetFrameType = match['matchEthernetFrameType']
+      ipToS = match['ipToS']
+      matchIpToS = match['matchIpToS']
+      ipProto = match['ipProto']
+      matchIpProto = match['matchIpProto']
+      srcIPv4Net = match['srcIPv4Net']
+      matchSrcIPv4Net = match['matchSrcIPv4Net']
+      dstIPv4Net = match['dstIPv4Net']
+      matchDstIPv4Net = match['matchDstIPv4Net']
+      srcTcpUdpPort = match['srcTcpUdpPort']
+      matchSrcTcpUdpPort = match['matchSrcTcpUdpPort']
+      dstTcpUdpPort = match['dstTcpUdpPort']
+      matchDstTcpUdpPort = match['matchDstTcpUdpPort']
+      if matchInPort == True:
+	print "    inPort: %s" % inPort['value']
+      if matchSrcMac == True:
+	print "    srcMac: %s" % srcMac['value']
+      if matchDstMac == True:
+	print "    dstMac: %s" % dstMac['value']
+      if matchVlanId == True:
+	print "    vlanId: %s" % vlanId
+      if matchVlanPriority == True:
+	print "    vlanPriority: %s" % vlanPriority
+      if matchEthernetFrameType == True:
+	print "    ethernetFrameType: %s" % hex(ethernetFrameType)
+      if matchIpToS == True:
+	print "    ipToS: %s" % ipToS
+      if matchIpProto == True:
+	print "    ipProto: %s" % ipProto
+      if matchSrcIPv4Net == True:
+	print "    srcIPv4Net: %s" % srcIPv4Net['value']
+      if matchDstIPv4Net == True:
+	print "    dstIPv4Net: %s" % dstIPv4Net['value']
+      if matchSrcTcpUdpPort == True:
+	print "    srcTcpUdpPort: %s" % srcTcpUdpPort
+      if matchDstTcpUdpPort == True:
+	print "    dstTcpUdpPort: %s" % dstTcpUdpPort
 
-    for a in actions:
-      actionType = a['actionType']
-      if actionType == "ACTION_OUTPUT":
-	port = a['actionOutput']['port']
-	maxLen = a['actionOutput']['maxLen']
-	print "    actionType: %s port: %s maxLen: %s" % (actionType, port, maxLen)
-      if actionType == "ACTION_SET_VLAN_VID":
-	vlanId = a['actionSetVlanId']['vlanId']
-	print "    actionType: %s vlanId: %s" % (actionType, vlanId)
-      if actionType == "ACTION_SET_VLAN_PCP":
-	vlanPriority = a['actionSetVlanPriority']['vlanPriority']
-	print "    actionType: %s vlanPriority: %s" % (actionType, vlanPriority)
-      if actionType == "ACTION_STRIP_VLAN":
-	stripVlan = a['actionStripVlan']['stripVlan']
-	print "    actionType: %s stripVlan: %s" % (actionType, stripVlan)
-      if actionType == "ACTION_SET_DL_SRC":
-	setEthernetSrcAddr = a['actionSetEthernetSrcAddr']['addr']['value']
-	print "    actionType: %s setEthernetSrcAddr: %s" % (actionType, setEthernetSrcAddr)
-      if actionType == "ACTION_SET_DL_DST":
-	setEthernetDstAddr = a['actionSetEthernetDstAddr']['addr']['value']
-	print "    actionType: %s setEthernetDstAddr: %s" % (actionType, setEthernetDstAddr)
-      if actionType == "ACTION_SET_NW_SRC":
-	setIPv4SrcAddr = a['actionSetIPv4SrcAddr']['addr']['value']
-	print "    actionType: %s setIPv4SrcAddr: %s" % (actionType, setIPv4SrcAddr)
-      if actionType == "ACTION_SET_NW_DST":
-	setIPv4DstAddr = a['actionSetIPv4DstAddr']['addr']['value']
-	print "    actionType: %s setIPv4DstAddr: %s" % (actionType, setIPv4DstAddr)
-      if actionType == "ACTION_SET_NW_TOS":
-	setIpToS = a['actionSetIpToS']['ipToS']
-	print "    actionType: %s setIpToS: %s" % (actionType, setIpToS)
-      if actionType == "ACTION_SET_TP_SRC":
-	setTcpUdpSrcPort = a['actionSetTcpUdpSrcPort']['port']
-	print "    actionType: %s setTcpUdpSrcPort: %s" % (actionType, setTcpUdpSrcPort)
-      if actionType == "ACTION_SET_TP_DST":
-	setTcpUdpDstPort = a['actionSetTcpUdpDstPort']['port']
-	print "    actionType: %s setTcpUdpDstPort: %s" % (actionType, setTcpUdpDstPort)
-      if actionType == "ACTION_ENQUEUE":
-	port = a['actionEnqueue']['port']['value']
-	queueId = a['actionEnqueue']['queueId']
-	print "    actionType: %s port: %s queueId: %s" % (actionType, port, queueId)
+    #
+    # Print the actions
+    #
+    if actions == None:
+      print "   Actions: %s" % (actions)
+    else:
+      for a in actions:
+	actionType = a['actionType']
+	if actionType == "ACTION_OUTPUT":
+	  port = a['actionOutput']['port']['value']
+	  maxLen = a['actionOutput']['maxLen']
+	  print "    actionType: %s port: %s maxLen: %s" % (actionType, port, maxLen)
+	if actionType == "ACTION_SET_VLAN_VID":
+	  vlanId = a['actionSetVlanId']['vlanId']
+	  print "    actionType: %s vlanId: %s" % (actionType, vlanId)
+	if actionType == "ACTION_SET_VLAN_PCP":
+	  vlanPriority = a['actionSetVlanPriority']['vlanPriority']
+	  print "    actionType: %s vlanPriority: %s" % (actionType, vlanPriority)
+	if actionType == "ACTION_STRIP_VLAN":
+	  stripVlan = a['actionStripVlan']['stripVlan']
+	  print "    actionType: %s stripVlan: %s" % (actionType, stripVlan)
+	if actionType == "ACTION_SET_DL_SRC":
+	  setEthernetSrcAddr = a['actionSetEthernetSrcAddr']['addr']['value']
+	  print "    actionType: %s setEthernetSrcAddr: %s" % (actionType, setEthernetSrcAddr)
+	if actionType == "ACTION_SET_DL_DST":
+	  setEthernetDstAddr = a['actionSetEthernetDstAddr']['addr']['value']
+	  print "    actionType: %s setEthernetDstAddr: %s" % (actionType, setEthernetDstAddr)
+	if actionType == "ACTION_SET_NW_SRC":
+	  setIPv4SrcAddr = a['actionSetIPv4SrcAddr']['addr']['value']
+	  print "    actionType: %s setIPv4SrcAddr: %s" % (actionType, setIPv4SrcAddr)
+	if actionType == "ACTION_SET_NW_DST":
+	  setIPv4DstAddr = a['actionSetIPv4DstAddr']['addr']['value']
+	  print "    actionType: %s setIPv4DstAddr: %s" % (actionType, setIPv4DstAddr)
+	if actionType == "ACTION_SET_NW_TOS":
+	  setIpToS = a['actionSetIpToS']['ipToS']
+	  print "    actionType: %s setIpToS: %s" % (actionType, setIpToS)
+	if actionType == "ACTION_SET_TP_SRC":
+	  setTcpUdpSrcPort = a['actionSetTcpUdpSrcPort']['port']
+	  print "    actionType: %s setTcpUdpSrcPort: %s" % (actionType, setTcpUdpSrcPort)
+	if actionType == "ACTION_SET_TP_DST":
+	  setTcpUdpDstPort = a['actionSetTcpUdpDstPort']['port']
+	  print "    actionType: %s setTcpUdpDstPort: %s" % (actionType, setTcpUdpDstPort)
+	if actionType == "ACTION_ENQUEUE":
+	  port = a['actionEnqueue']['port']['value']
+	  queueId = a['actionEnqueue']['queueId']
+	  print "    actionType: %s port: %s queueId: %s" % (actionType, port, queueId)
 
 def get_flow_path(flow_id):
   try:
diff --git a/web/rest-test.sh b/web/rest-test.sh
new file mode 100755
index 0000000..a54e1e2
--- /dev/null
+++ b/web/rest-test.sh
@@ -0,0 +1,7 @@
+#! /bin/sh
+rm -f rest.json
+touch rest.json
+curl -s 'http://localhost:8080/wm/core/topology/switches/all/json' | python -m json.tool >> rest.json
+curl -s 'http://localhost:8080/wm/core/topology/links/json' | python -m json.tool >> rest.json
+curl -s 'http://localhost:8080/wm/registry/controllers/json' | python -m json.tool >> rest.json
+curl -s 'http://localhost:8080/wm/registry/switches/json' | python -m json.tool >> rest.json