Cleanup in the FlowPusher and the FlowSynchronizer:
 * Don't use FlowPath and IFlowPath when pushing flows through the
   FlowPusher, because it is not needed anymore: now the FlowEntry object
   is self-contained.
 * Removed the alternative FlowPusher add(IFlowEntry) method that takes
   IFlowEntry argument from Titan; instead, extract the IFlowEntry
   into a FlowEntry object, and then use the remaining add(FlowEntry)
   method.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
index a1216f4..58a590f 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
@@ -25,7 +25,7 @@
 /**
  * Class for performing Flow-related operations on the Database.
  */
-class FlowDatabaseOperation {
+public class FlowDatabaseOperation {
     private final static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
 
     /**
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
index 186d4ff..bdd0355 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -417,7 +417,6 @@
 	Map<Long, IOFSwitch> mySwitches = getMySwitches();
 
 	for (FlowPathEntryPair flowPair : modifiedFlowEntries) {
-	    FlowPath flowPath = flowPair.flowPath;
 	    FlowEntry flowEntry = flowPair.flowEntry;
 
 	    IOFSwitch mySwitch = mySwitches.get(flowEntry.dpid().value());
@@ -429,10 +428,10 @@
 	    //
 	    // Push the Flow Entry into the switch
 	    //
-	    if (! pusher.add(mySwitch, flowPath, flowEntry)) {
+	    if (! pusher.add(mySwitch, flowEntry)) {
 		String logMsg = "Cannot install Flow Entry " +
 		    flowEntry.flowEntryId() +
-		    " from Flow Path " + flowPath.flowId() +
+		    " from Flow Path " + flowEntry.flowId() +
 		    " on switch " + flowEntry.dpid();
 		log.error(logMsg);
 		continue;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowPusher.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowPusher.java
index 8f2469b..a1c67fe 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowPusher.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowPusher.java
@@ -27,8 +27,6 @@
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 import net.floodlightcontroller.util.MACAddress;
 import net.floodlightcontroller.util.OFMessageDamper;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
 import net.onrc.onos.ofcontroller.util.FlowEntryAction;
 import net.onrc.onos.ofcontroller.util.FlowEntryAction.*;
 import net.onrc.onos.ofcontroller.util.FlowEntry;
@@ -36,7 +34,6 @@
 import net.onrc.onos.ofcontroller.util.FlowEntryId;
 import net.onrc.onos.ofcontroller.util.FlowEntryMatch;
 import net.onrc.onos.ofcontroller.util.FlowEntryUserState;
-import net.onrc.onos.ofcontroller.util.FlowPath;
 import net.onrc.onos.ofcontroller.util.IPv4Net;
 import net.onrc.onos.ofcontroller.util.Port;
 
@@ -441,312 +438,7 @@
 	}
 	
 	@Override
-	public boolean add(IOFSwitch sw, IFlowPath flowObj, IFlowEntry flowEntryObj) {
-		log.debug("sending : {}, {}", sw, flowObj);
-		String flowEntryIdStr = flowEntryObj.getFlowEntryId();
-		if (flowEntryIdStr == null)
-		    return false;
-		FlowEntryId flowEntryId = new FlowEntryId(flowEntryIdStr);
-		String userState = flowEntryObj.getUserState();
-		if (userState == null)
-		    return false;
-
-		//
-		// Create the Open Flow Flow Modification Entry to push
-		//
-		OFFlowMod fm = (OFFlowMod)factory.getMessage(OFType.FLOW_MOD);
-		long cookie = flowEntryId.value();
-
-		short flowModCommand = OFFlowMod.OFPFC_ADD;
-		if (userState.equals("FE_USER_ADD")) {
-		    flowModCommand = OFFlowMod.OFPFC_ADD;
-		} else if (userState.equals("FE_USER_MODIFY")) {
-		    flowModCommand = OFFlowMod.OFPFC_MODIFY_STRICT;
-		} else if (userState.equals("FE_USER_DELETE")) {
-		    flowModCommand = OFFlowMod.OFPFC_DELETE_STRICT;
-		} else {
-		    // Unknown user state. Ignore the entry
-		    log.debug("Flow Entry ignored (FlowEntryId = {}): unknown user state {}",
-			      flowEntryId.toString(), userState);
-		    return false;
-		}
-
-		//
-		// Fetch the match conditions.
-		//
-		// NOTE: The Flow matching conditions common for all Flow Entries are
-		// used ONLY if a Flow Entry does NOT have the corresponding matching
-		// condition set.
-		//
-		OFMatch match = new OFMatch();
-		match.setWildcards(OFMatch.OFPFW_ALL);
-
-		// Match the Incoming Port
-		Short matchInPort = flowEntryObj.getMatchInPort();
-		if (matchInPort != null) {
-		    match.setInputPort(matchInPort);
-		    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_IN_PORT);
-		}
-
-		// Match the Source MAC address
-		String matchSrcMac = flowEntryObj.getMatchSrcMac();
-		if (matchSrcMac == null)
-		    matchSrcMac = flowObj.getMatchSrcMac();
-		if (matchSrcMac != null) {
-		    match.setDataLayerSource(matchSrcMac);
-		    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_SRC);
-		}
-
-		// Match the Destination MAC address
-		String matchDstMac = flowEntryObj.getMatchDstMac();
-		if (matchDstMac == null)
-		    matchDstMac = flowObj.getMatchDstMac();
-		if (matchDstMac != null) {
-		    match.setDataLayerDestination(matchDstMac);
-		    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
-		}
-
-		// Match the Ethernet Frame Type
-		Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
-		if (matchEthernetFrameType == null)
-		    matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
-		if (matchEthernetFrameType != null) {
-		    match.setDataLayerType(matchEthernetFrameType);
-		    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
-		}
-
-		// Match the VLAN ID
-		Short matchVlanId = flowEntryObj.getMatchVlanId();
-		if (matchVlanId == null)
-		    matchVlanId = flowObj.getMatchVlanId();
-		if (matchVlanId != null) {
-		    match.setDataLayerVirtualLan(matchVlanId);
-		    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_VLAN);
-		}
-
-		// Match the VLAN priority
-		Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
-		if (matchVlanPriority == null)
-		    matchVlanPriority = flowObj.getMatchVlanPriority();
-		if (matchVlanPriority != null) {
-		    match.setDataLayerVirtualLanPriorityCodePoint(matchVlanPriority);
-		    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_VLAN_PCP);
-		}
-
-		// Match the Source IPv4 Network prefix
-		String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
-		if (matchSrcIPv4Net == null)
-		    matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
-		if (matchSrcIPv4Net != null) {
-		    match.setFromCIDR(matchSrcIPv4Net, OFMatch.STR_NW_SRC);
-		}
-
-		// Match the Destination IPv4 Network prefix
-		String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
-		if (matchDstIPv4Net == null)
-		    matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
-		if (matchDstIPv4Net != null) {
-		    match.setFromCIDR(matchDstIPv4Net, OFMatch.STR_NW_DST);
-		}
-
-		// Match the IP protocol
-		Byte matchIpProto = flowEntryObj.getMatchIpProto();
-		if (matchIpProto == null)
-		    matchIpProto = flowObj.getMatchIpProto();
-		if (matchIpProto != null) {
-		    match.setNetworkProtocol(matchIpProto);
-		    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_NW_PROTO);
-		}
-
-		// Match the IP ToS (DSCP field, 6 bits)
-		Byte matchIpToS = flowEntryObj.getMatchIpToS();
-		if (matchIpToS == null)
-		    matchIpToS = flowObj.getMatchIpToS();
-		if (matchIpToS != null) {
-		    match.setNetworkTypeOfService(matchIpToS);
-		    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_NW_TOS);
-		}
-
-		// Match the Source TCP/UDP port
-		Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
-		if (matchSrcTcpUdpPort == null)
-		    matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
-		if (matchSrcTcpUdpPort != null) {
-		    match.setTransportSource(matchSrcTcpUdpPort);
-		    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_TP_SRC);
-		}
-
-		// Match the Destination TCP/UDP port
-		Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
-		if (matchDstTcpUdpPort == null)
-		    matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
-		if (matchDstTcpUdpPort != null) {
-		    match.setTransportDestination(matchDstTcpUdpPort);
-		    match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_TP_DST);
-		}
-
-		//
-		// Fetch the actions
-		//
-		Short actionOutputPort = null;
-		List<OFAction> openFlowActions = new ArrayList<OFAction>();
-		int actionsLen = 0;
-		FlowEntryActions flowEntryActions = null;
-		String actionsStr = flowEntryObj.getActions();
-		if (actionsStr != null)
-		    flowEntryActions = new FlowEntryActions(actionsStr);
-		else
-		    flowEntryActions = new FlowEntryActions();
-		for (FlowEntryAction action : flowEntryActions.actions()) {
-		    ActionOutput actionOutput = action.actionOutput();
-		    ActionSetVlanId actionSetVlanId = action.actionSetVlanId();
-		    ActionSetVlanPriority actionSetVlanPriority = action.actionSetVlanPriority();
-		    ActionStripVlan actionStripVlan = action.actionStripVlan();
-		    ActionSetEthernetAddr actionSetEthernetSrcAddr = action.actionSetEthernetSrcAddr();
-		    ActionSetEthernetAddr actionSetEthernetDstAddr = action.actionSetEthernetDstAddr();
-		    ActionSetIPv4Addr actionSetIPv4SrcAddr = action.actionSetIPv4SrcAddr();
-		    ActionSetIPv4Addr actionSetIPv4DstAddr = action.actionSetIPv4DstAddr();
-		    ActionSetIpToS actionSetIpToS = action.actionSetIpToS();
-		    ActionSetTcpUdpPort actionSetTcpUdpSrcPort = action.actionSetTcpUdpSrcPort();
-		    ActionSetTcpUdpPort actionSetTcpUdpDstPort = action.actionSetTcpUdpDstPort();
-		    ActionEnqueue actionEnqueue = action.actionEnqueue();
-
-		    if (actionOutput != null) {
-				actionOutputPort = actionOutput.port().value();
-				// XXX: The max length is hard-coded for now
-				OFActionOutput ofa =
-				    new OFActionOutput(actionOutput.port().value(),
-						       (short)0xffff);
-				openFlowActions.add(ofa);
-				actionsLen += ofa.getLength();
-		    }
-
-		    if (actionSetVlanId != null) {
-				OFActionVirtualLanIdentifier ofa =
-				    new OFActionVirtualLanIdentifier(actionSetVlanId.vlanId());
-				openFlowActions.add(ofa);
-				actionsLen += ofa.getLength();
-		    }
-
-		    if (actionSetVlanPriority != null) {
-				OFActionVirtualLanPriorityCodePoint ofa =
-				    new OFActionVirtualLanPriorityCodePoint(actionSetVlanPriority.vlanPriority());
-				openFlowActions.add(ofa);
-				actionsLen += ofa.getLength();
-		    }
-
-		    if (actionStripVlan != null) {
-				if (actionStripVlan.stripVlan() == true) {
-				    OFActionStripVirtualLan ofa = new OFActionStripVirtualLan();
-				    openFlowActions.add(ofa);
-				    actionsLen += ofa.getLength();
-				}
-		    }
-
-		    if (actionSetEthernetSrcAddr != null) {
-				OFActionDataLayerSource ofa = 
-				    new OFActionDataLayerSource(actionSetEthernetSrcAddr.addr().toBytes());
-				openFlowActions.add(ofa);
-				actionsLen += ofa.getLength();
-		    }
-
-		    if (actionSetEthernetDstAddr != null) {
-				OFActionDataLayerDestination ofa =
-				    new OFActionDataLayerDestination(actionSetEthernetDstAddr.addr().toBytes());
-				openFlowActions.add(ofa);
-				actionsLen += ofa.getLength();
-		    }
-
-		    if (actionSetIPv4SrcAddr != null) {
-				OFActionNetworkLayerSource ofa =
-				    new OFActionNetworkLayerSource(actionSetIPv4SrcAddr.addr().value());
-				openFlowActions.add(ofa);
-				actionsLen += ofa.getLength();
-		    }
-
-		    if (actionSetIPv4DstAddr != null) {
-				OFActionNetworkLayerDestination ofa =
-				    new OFActionNetworkLayerDestination(actionSetIPv4DstAddr.addr().value());
-				openFlowActions.add(ofa);
-				actionsLen += ofa.getLength();
-		    }
-
-		    if (actionSetIpToS != null) {
-				OFActionNetworkTypeOfService ofa =
-				    new OFActionNetworkTypeOfService(actionSetIpToS.ipToS());
-				openFlowActions.add(ofa);
-				actionsLen += ofa.getLength();
-		    }
-
-		    if (actionSetTcpUdpSrcPort != null) {
-				OFActionTransportLayerSource ofa =
-				    new OFActionTransportLayerSource(actionSetTcpUdpSrcPort.port());
-				openFlowActions.add(ofa);
-				actionsLen += ofa.getLength();
-		    }
-
-		    if (actionSetTcpUdpDstPort != null) {
-				OFActionTransportLayerDestination ofa =
-				    new OFActionTransportLayerDestination(actionSetTcpUdpDstPort.port());
-				openFlowActions.add(ofa);
-				actionsLen += ofa.getLength();
-		    }
-
-		    if (actionEnqueue != null) {
-				OFActionEnqueue ofa =
-				    new OFActionEnqueue(actionEnqueue.port().value(),
-							actionEnqueue.queueId());
-				openFlowActions.add(ofa);
-				actionsLen += ofa.getLength();
-		    }
-		}
-
-		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(openFlowActions)
-		    .setLengthU(OFFlowMod.MINIMUM_LENGTH + actionsLen);
-		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);
-		// See method ForwardingBase::pushRoute()
-		//
-
-		//
-		// Write the message to the switch
-		//
-		log.debug("MEASUREMENT: Installing flow entry " + userState +
-			  " into switch DPID: " +
-			  sw.getStringId() +
-			  " flowEntryId: " + flowEntryId.toString() +
-			  " srcMac: " + matchSrcMac + " dstMac: " + matchDstMac +
-			  " inPort: " + matchInPort + " outPort: " + actionOutputPort
-			  );
-		add(sw,fm);
-	    //
-	    // TODO: We should use the OpenFlow Barrier mechanism
-	    // to check for errors, and update the SwitchState
-	    // for a flow entry after the Barrier message is
-	    // is received.
-	    //
-	    flowEntryObj.setSwitchState("FE_SWITCH_UPDATED");
-
-		return true;
-	}
-	
-	@Override
-	public boolean add(IOFSwitch sw, FlowPath flowPath, FlowEntry flowEntry) {
+	public boolean add(IOFSwitch sw, FlowEntry flowEntry) {
 		//
 		// Create the OpenFlow Flow Modification Entry to push
 		//
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
index b3c8e84..c357e7c 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
@@ -25,7 +25,9 @@
 import net.onrc.onos.graph.GraphDBOperation;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.flowmanager.FlowDatabaseOperation;
 import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.FlowEntry;
 import net.onrc.onos.ofcontroller.util.FlowEntryId;
 
 /**
@@ -236,7 +238,15 @@
 		return;
 	    }
 
-	    pusher.add(sw, iFlowEntry.getFlow(), iFlowEntry);
+	    FlowEntry flowEntry =
+		FlowDatabaseOperation.extractFlowEntry(iFlowEntry);
+	    if (flowEntry == null) {
+		log.error("Cannot add flow entry {} to sw {} : flow entry cannot be extracted",
+			  flowEntryId, sw.getId());
+		return;
+	    }
+
+	    pusher.add(sw, flowEntry);
 	}
 	
 	/**
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/IFlowPusherService.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/IFlowPusherService.java
index 20a6249..2f550a7 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/IFlowPusherService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/IFlowPusherService.java
@@ -6,10 +6,7 @@
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.internal.OFMessageFuture;
 import net.floodlightcontroller.core.module.IFloodlightService;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
 import net.onrc.onos.ofcontroller.util.FlowEntry;
-import net.onrc.onos.ofcontroller.util.FlowPath;
 
 /**
  * FlowPusherService is a service to send message to switches in proper rate.
@@ -59,20 +56,10 @@
 	/**
 	 * Create a message from FlowEntry and add it to the queue of the switch.
 	 * @param sw Switch to which message is pushed.
-	 * @param flowPath FlowPath object used for creating message.
 	 * @param flowEntry FlowEntry object used for creating message.
 	 * @return true if message is successfully added to a queue.
 	 */
-	boolean add(IOFSwitch sw, FlowPath flowPath, FlowEntry flowEntry);
-
-	/**
-	 * Create a message from IFlowEntry and add it to the queue of the switch.
-	 * @param sw Switch to which message is pushed.
-	 * @param flowObj IFlowPath object used for creating message.
-	 * @param flowEntryObj IFlowEntry object used for creating message.
-	 * @return true if message is successfully added to a queue.
-	 */
-	boolean add(IOFSwitch sw, IFlowPath flowObj, IFlowEntry flowEntryObj);
+	boolean add(IOFSwitch sw, FlowEntry flowEntry);
 
 	/**
 	 * Set sending rate to a switch.