* Implement method FlowManager::reconcileFlows()
  Note: for simplicity, we don't compare the old and the new paths,
  because it is error-prone.
  Instead, we delete all old flow entries, and add the new flow entries,
  even if some of those entries haven't changed.
  In the future we should perform the appropriate comparison.

* Change addAndMaintainShortestPathFlow() to return the computed
  (shortest) flow path.
diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
index 1b45423..2b23e18 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
@@ -5,6 +5,7 @@
 import java.util.Collection;
 import java.util.EnumSet;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -695,7 +696,11 @@
 	    flowEntryObj.setType("flow_entry");
 
 	    // 
-	    // Set the Flow Entry attributes:
+	    // Set the Flow Entry Edges and attributes:
+	    // - Switch edge
+	    // - InPort edge
+	    // - OutPort edge
+	    //
 	    // - flowEntry.flowEntryMatch()
 	    // - flowEntry.flowEntryActions()
 	    // - flowEntry.dpid()
@@ -754,18 +759,16 @@
 		flowEntryObj.setUserState("FE_USER_ADD");
 	    flowEntryObj.setSwitchState("FE_SWITCH_NOT_UPDATED");
 	    //
-	    // TODO: Take care of the FlowEntryMatch, FlowEntryAction set,
-	    // and FlowEntryErrorState.
+	    // TODO: Take care of the FlowEntryErrorState.
 	    //
 
 	    // Flow Entries edges:
 	    //   Flow
-	    //   NextFE
-	    //   InPort
-	    //   OutPort
-	    //   Switch
-	    if (! found)
+	    //   NextFE (TODO)
+	    if (! found) {
 		flowObj.addFlowEntry(flowEntryObj);
+		flowEntryObj.setFlow(flowObj);
+	    }
 	}
 	conn.endTx(Transaction.COMMIT);
 
@@ -1214,7 +1217,7 @@
     /**
      * Add and maintain a shortest-path flow.
      *
-     * NOTE: The Flow Path does NOT contain all flow entries.
+     * NOTE: The Flow Path argument does NOT contain all flow entries.
      * Instead, it contains a single dummy flow entry that is used to
      * store the matching condition(s).
      * That entry is replaced by the appropriate entries from the
@@ -1222,12 +1225,10 @@
      *
      * @param flowPath the Flow Path with the endpoints and the match
      * conditions to install.
-     * @param flowId the return-by-reference Flow ID as assigned internally.
-     * @return true on success, otherwise false.
+     * @return the added shortest-path flow on success, otherwise null.
      */
     @Override
-    public boolean addAndMaintainShortestPathFlow(FlowPath flowPath,
-						  FlowId flowId) {
+    public FlowPath addAndMaintainShortestPathFlow(FlowPath flowPath) {
 	//
 	// Do the shortest path computation
 	//
@@ -1235,7 +1236,7 @@
 	    topoRouteService.getShortestPath(flowPath.dataPath().srcPort(),
 					     flowPath.dataPath().dstPort());
 	if (dataPath == null)
-	    return false;
+	    return null;
 
 	FlowEntryMatch userFlowEntryMatch = null;
 	if (! flowPath.dataPath().flowEntries().isEmpty()) {
@@ -1270,16 +1271,18 @@
 	//
 	// Prepare the computed Flow Path
 	//
-	FlowPath resultFlowPath = new FlowPath();
-	resultFlowPath.setFlowId(new FlowId(flowPath.flowId().value()));
-	resultFlowPath.setInstallerId(new CallerId(flowPath.installerId().value()));
-	resultFlowPath.setDataPath(dataPath);
+	FlowPath computedFlowPath = new FlowPath();
+	computedFlowPath.setFlowId(new FlowId(flowPath.flowId().value()));
+	computedFlowPath.setInstallerId(new CallerId(flowPath.installerId().value()));
+	computedFlowPath.setDataPath(dataPath);
 
-	boolean returnValue = addFlow(resultFlowPath, flowId);
+	FlowId flowId = new FlowId();
+	if (! addFlow(computedFlowPath, flowId))
+	    return null;
 
 	// TODO: Mark the flow for maintenance purpose
 
-	return (returnValue);
+	return (computedFlowPath);
     }
 
     /**
@@ -1326,18 +1329,84 @@
     }
 
     /**
-     * Reconcile all flows on inactive port (src port of link which might be
-     * broken).
+     * Reconcile all flows on inactive switch port.
      *
-     * TODO: We need it now: Pavlin
-     *
-     * @param src_port the port that has become inactive.
+     * @param portObject the port that has become inactive.
      */
     @Override
-    public void reconcileFlows(IPortObject src_port) {
-	// TODO: We need it now: Pavlin
+    public void reconcileFlows(IPortObject portObject) {
+	Iterable<IFlowEntry> inFlowEntries = portObject.getInFlowEntries();
+	Iterable<IFlowEntry> outFlowEntries = portObject.getOutFlowEntries();
 
-	// TODO: It should call installFlowEntry() as appropriate.
+	//
+	// Collect all affected Flow IDs from the affected flow entries
+	//
+	HashSet<IFlowPath> flowObjSet = new HashSet<IFlowPath>();
+	for (IFlowEntry flowEntryObj: inFlowEntries) {
+	    IFlowPath flowObj = flowEntryObj.getFlow();
+	    if (flowObj != null)
+		flowObjSet.add(flowObj);
+	}
+	for (IFlowEntry flowEntryObj: outFlowEntries) {
+	    IFlowPath flowObj = flowEntryObj.getFlow();
+	    if (flowObj != null)
+		flowObjSet.add(flowObj);
+	}
+	// conn.endTx(Transaction.COMMIT);
+
+	//
+	// Remove the old Flow Entries, and add the new Flow Entries
+	//
+	Map<Long, IOFSwitch> mySwitches = floodlightProvider.getSwitches();
+	for (IFlowPath flowObj : flowObjSet) {
+	    FlowPath flowPath = extractFlowPath(flowObj);
+	    if (flowPath == null)
+		continue;
+
+	    //
+	    // Remove my Flow Entries from the Network MAP
+	    //
+	    Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
+	    for (IFlowEntry flowEntryObj : flowEntries) {
+		String dpidStr = flowEntryObj.getSwitchDpid();
+		if (dpidStr == null)
+		    continue;
+		Dpid dpid = new Dpid(dpidStr);
+		IOFSwitch mySwitch = mySwitches.get(dpid.value());
+		if (mySwitch == null)
+		    continue;		// Ignore the entry: not my switch
+		flowObj.removeFlowEntry(flowEntryObj);
+		conn.utils().removeFlowEntry(conn, flowEntryObj);
+	    }
+
+	    //
+	    // Delete the flow entries from the switches
+	    //
+	    for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
+		flowEntry.setFlowEntryUserState(FlowEntryUserState.FE_USER_DELETE);
+		installFlowEntry(mySwitches, flowEntry);
+	    }
+
+	    //
+	    // Calculate the new shortest path and install it in the
+	    // Network MAP.
+	    //
+	    FlowPath addedFlowPath = addAndMaintainShortestPathFlow(flowPath);
+	    if (addedFlowPath == null) {
+		log.error("Cannot add Shortest Path Flow from {} to {}",
+			  flowPath.dataPath().srcPort().toString(),
+			  flowPath.dataPath().dstPort().toString());
+		continue;
+	    }
+
+	    //
+	    // Add the flow entries to the switches
+	    //
+	    for (FlowEntry flowEntry : addedFlowPath.dataPath().flowEntries()) {
+		flowEntry.setFlowEntryUserState(FlowEntryUserState.FE_USER_ADD);
+		installFlowEntry(mySwitches, flowEntry);
+	    }
+	}
     }
 
     /**
diff --git a/src/main/java/net/floodlightcontroller/flowcache/IFlowService.java b/src/main/java/net/floodlightcontroller/flowcache/IFlowService.java
index 45cdde0..b6df1e2 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/IFlowService.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/IFlowService.java
@@ -86,7 +86,7 @@
     /**
      * Add and maintain a shortest-path flow.
      *
-     * NOTE: The Flow Path does NOT contain all flow entries.
+     * NOTE: The Flow Path argument does NOT contain all flow entries.
      * Instead, it contains a single dummy flow entry that is used to
      * store the matching condition(s).
      * That entry is replaced by the appropriate entries from the
@@ -94,9 +94,7 @@
      *
      * @param flowPath the Flow Path with the endpoints and the match
      * conditions to install.
-     * @param flowId the return-by-reference Flow ID as assigned internally.
-     * @return true on success, otherwise false.
+     * @return the added shortest-path flow on success, otherwise null.
      */
-    public boolean addAndMaintainShortestPathFlow(FlowPath flowPath,
-						  FlowId flowId);
+    public FlowPath addAndMaintainShortestPathFlow(FlowPath flowPath);
 }
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/AddShortestPathFlowResource.java b/src/main/java/net/floodlightcontroller/flowcache/web/AddShortestPathFlowResource.java
index e00a4b5..3c5bcd8 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/AddShortestPathFlowResource.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/AddShortestPathFlowResource.java
@@ -52,10 +52,12 @@
 
 	// Process the request
 	if (flowPath != null) {
-	    if (flowService.addAndMaintainShortestPathFlow(flowPath, result)
-		!= true) {
+	    FlowPath addedFlowPath =
+		flowService.addAndMaintainShortestPathFlow(flowPath);
+	    if (addedFlowPath == null)
 		result = new FlowId();		// Error: Return empty Flow Id
-	    }
+	    else
+		result = addedFlowPath.flowId();
 	}
 
         return result;
diff --git a/src/main/java/net/onrc/onos/flow/IFlowManager.java b/src/main/java/net/onrc/onos/flow/IFlowManager.java
index d7ac371..8394046 100644
--- a/src/main/java/net/onrc/onos/flow/IFlowManager.java
+++ b/src/main/java/net/onrc/onos/flow/IFlowManager.java
@@ -41,14 +41,11 @@
     public Iterable<FlowPath> getFlows(IPortObject port);
 
     /**
-     * Reconcile all flows on inactive port (src port of link which might be
-     * broken).
+     * Reconcile all flows on inactive switch port.
      *
-     * TODO: We need it now: Pavlin
-     *
-     * @param src_port the port that has become inactive.
+     * @param portObject the port that has become inactive.
      */
-    public void reconcileFlows(IPortObject src_port);
+    public void reconcileFlows(IPortObject portObject);
 
     /**
      * Reconcile all flows between a source and a destination port.