Generate a notification from the FlowManager to the ForwardingService
when a collection of flows has been installed into all switches.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
index f49b10a..3538eb4 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
@@ -75,11 +75,14 @@
     // Transient state for processing the Flow Paths:
     //  - The Flow Paths that should be recomputed
     //  - The Flow Paths with modified Flow Entries
+    //  - The Flow Paths that we should check if installed in all switches
     //
     private Map<Long, FlowPath> shouldRecomputeFlowPaths =
 	new HashMap<Long, FlowPath>();
     private Map<Long, FlowPath> modifiedFlowPaths =
 	new HashMap<Long, FlowPath>();
+    private Map<Long, FlowPath> checkIfInstalledFlowPaths =
+	new HashMap<Long, FlowPath>();
 
     /**
      * Constructor for a given Flow Manager and Datagrid Service.
@@ -239,6 +242,12 @@
 	for (FlowPath flowPath : modifiedFlowPaths.values())
 	    flowPath.dataPath().removeDeletedFlowEntries();
 
+	//
+	// Check if Flow Paths have been installed into all switches,
+	// and generate the appropriate events.
+	//
+	checkInstalledFlowPaths(checkIfInstalledFlowPaths.values());
+
 	// Cleanup
 	topologyEvents.clear();
 	flowPathEvents.clear();
@@ -246,6 +255,44 @@
 	//
 	shouldRecomputeFlowPaths.clear();
 	modifiedFlowPaths.clear();
+	checkIfInstalledFlowPaths.clear();
+    }
+
+    /**
+     * Check if Flow Paths have been installed into all switches,
+     * and generate the appropriate events.
+     *
+     * @param flowPaths the flowPaths to process.
+     */
+    private void checkInstalledFlowPaths(Collection<FlowPath> flowPaths) {
+	List<FlowPath> installedFlowPaths = new LinkedList<FlowPath>();
+
+	Kryo kryo = kryoFactory.newKryo();
+
+	for (FlowPath flowPath : flowPaths) {
+	    boolean isInstalled = true;
+
+	    //
+	    // Check whether all Flow Entries have been installed
+	    //
+	    for (FlowEntry flowEntry : flowPath.flowEntries()) {
+		if (flowEntry.flowEntrySwitchState() !=
+		    FlowEntrySwitchState.FE_SWITCH_UPDATED) {
+		    isInstalled = false;
+		    break;
+		}
+	    }
+
+	    if (isInstalled) {
+		// Create a copy and add it to the list
+		FlowPath copyFlowPath = kryo.copy(flowPath);
+		installedFlowPaths.add(copyFlowPath);
+	    }
+	}
+	kryoFactory.deleteKryo(kryo);
+
+	// Generate an event for the installed Flow Path.
+	flowManager.notificationFlowPathsInstalled(installedFlowPaths);
     }
 
     /**
@@ -529,10 +576,12 @@
 	    }
 
 	    //
-	    // Update the local Flow Entry.
+	    // Update the local Flow Entry, and keep state to check
+	    // if the Flow Path has been installed.
 	    //
 	    localFlowEntry.setFlowEntryUserState(flowEntry.flowEntryUserState());
 	    localFlowEntry.setFlowEntrySwitchState(flowEntry.flowEntrySwitchState());
+	    checkIfInstalledFlowPaths.put(flowPath.flowId().value(), flowPath);
 	    return localFlowEntry;
 	}