* Added the skeleton for the Path Computation implementation.
* Refactor the interaction between the Datagrid Service and the Flow Manager:
  Now the Path Computation service itself receives the notifications
  from the Datagrid Service without using the Flow Manager as a middle-man.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/PathComputation.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/PathComputation.java
new file mode 100644
index 0000000..d4950d2
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/PathComputation.java
@@ -0,0 +1,196 @@
+package net.onrc.onos.ofcontroller.flowmanager;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import net.onrc.onos.datagrid.IDatagridService;
+import net.onrc.onos.ofcontroller.topology.TopologyElement;
+import net.onrc.onos.ofcontroller.util.EventEntry;
+import net.onrc.onos.ofcontroller.util.FlowPath;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class for implementing the Path Computation and Path Maintenance.
+ */
+class PathComputation extends Thread implements IPathComputationService {
+    /** The logger. */
+    private final static Logger log = LoggerFactory.getLogger(PathComputation.class);
+
+    private FlowManager flowManager;		// The Flow Manager to use
+    private IDatagridService datagridService;	// The Datagrid Service to use
+
+    // The queue with Flow Path and Topology Element updates
+    private BlockingQueue<EventEntry<?>> networkEvents =
+	new LinkedBlockingQueue<EventEntry<?>>();
+
+    // The pending Topology and Flow Path events
+    private List<EventEntry<TopologyElement>> topologyEvents =
+	new LinkedList<EventEntry<TopologyElement>>();
+    private List<EventEntry<FlowPath>> flowPathEvents =
+	new LinkedList<EventEntry<FlowPath>>();
+
+    /**
+     * Constructor for a given Flow Manager and Datagrid Service.
+     *
+     * @param flowManager the Flow Manager to use.
+     * @param datagridService the Datagrid Service to use.
+     */
+    PathComputation(FlowManager flowManager,
+		    IDatagridService datagridService) {
+	this.flowManager = flowManager;
+	this.datagridService = datagridService;
+    }
+
+    /**
+     * Run the thread.
+     */
+    @Override
+    public void run() {
+	//
+	// Obtain the initial Topology state
+	//
+	Collection<TopologyElement> topologyElements =
+	    datagridService.getAllTopologyElements();
+	for (TopologyElement topologyElement : topologyElements) {
+	    EventEntry<TopologyElement> eventEntry =
+		new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
+	    topologyEvents.add(eventEntry);
+	}
+	//
+	// Obtain the initial Flow Path state
+	//
+	Collection<FlowPath> flowPaths = datagridService.getAllFlows();
+	for (FlowPath flowPath : flowPaths) {
+	    EventEntry<FlowPath> eventEntry =
+		new EventEntry<FlowPath>(EventEntry.Type.ENTRY_ADD, flowPath);
+	    flowPathEvents.add(eventEntry);
+	}
+	// Process the events (if any)
+	processEvents();
+
+	//
+	// The main loop
+	//
+	Collection<EventEntry<?>> collection = new LinkedList<EventEntry<?>>();
+	try {
+	    while (true) {
+		EventEntry<?> eventEntry = networkEvents.take();
+		collection.add(eventEntry);
+		networkEvents.drainTo(collection);
+
+		// Demultiplex all events
+		for (EventEntry<?> event : collection) {
+		    if (event.eventData() instanceof TopologyElement) {
+			EventEntry<TopologyElement> topologyEventEntry =
+			    (EventEntry<TopologyElement>)event;
+			topologyEvents.add(topologyEventEntry);
+		    } else if (event.eventData() instanceof FlowPath) {
+			EventEntry<FlowPath> flowPathEventEntry =
+			    (EventEntry<FlowPath>)event;
+			flowPathEvents.add(flowPathEventEntry);
+		    }
+		}
+		collection.clear();
+		// Process the events (if any)
+		processEvents();
+	    }
+	} catch (Exception exception) {
+	    log.debug("Exception processing Network Events: ", exception);
+	}
+    }
+
+    /**
+     * Process the events (if any)
+     */
+    private void processEvents() {
+	if (topologyEvents.isEmpty() && flowPathEvents.isEmpty())
+	    return;		// Nothing to do
+
+	// TODO: Implement it!
+
+	System.out.println("PAVPAV: Topology Events = " + topologyEvents.size() + " Flow Path Events = " + flowPathEvents.size());
+
+	topologyEvents.clear();
+	flowPathEvents.clear();
+    }
+
+    /**
+     * Receive a notification that a Flow is added.
+     *
+     * @param flowPath the flow that is added.
+     */
+    @Override
+    public void notificationRecvFlowAdded(FlowPath flowPath) {
+	EventEntry<FlowPath> eventEntry =
+	    new EventEntry<FlowPath>(EventEntry.Type.ENTRY_ADD, flowPath);
+	networkEvents.add(eventEntry);
+    }
+
+    /**
+     * Receive a notification that a Flow is removed.
+     *
+     * @param flowPath the flow that is removed.
+     */
+    @Override
+    public void notificationRecvFlowRemoved(FlowPath flowPath) {
+	EventEntry<FlowPath> eventEntry =
+	    new EventEntry<FlowPath>(EventEntry.Type.ENTRY_REMOVE, flowPath);
+	networkEvents.add(eventEntry);
+    }
+
+    /**
+     * Receive a notification that a Flow is updated.
+     *
+     * @param flowPath the flow that is updated.
+     */
+    @Override
+    public void notificationRecvFlowUpdated(FlowPath flowPath) {
+	// NOTE: The ADD and UPDATE events are processed in same way
+	EventEntry<FlowPath> eventEntry =
+	    new EventEntry<FlowPath>(EventEntry.Type.ENTRY_ADD, flowPath);
+	networkEvents.add(eventEntry);
+    }
+
+    /**
+     * Receive a notification that a Topology Element is added.
+     *
+     * @param topologyElement the Topology Element that is added.
+     */
+    @Override
+    public void notificationRecvTopologyElementAdded(TopologyElement topologyElement) {
+	EventEntry<TopologyElement> eventEntry =
+	    new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
+	networkEvents.add(eventEntry);
+    }
+
+    /**
+     * Receive a notification that a Topology Element is removed.
+     *
+     * @param topologyElement the Topology Element that is removed.
+     */
+    @Override
+    public void notificationRecvTopologyElementRemoved(TopologyElement topologyElement) {
+	EventEntry<TopologyElement> eventEntry =
+	    new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_REMOVE, topologyElement);
+	networkEvents.add(eventEntry);
+    }
+
+    /**
+     * Receive a notification that a Topology Element is updated.
+     *
+     * @param topologyElement the Topology Element that is updated.
+     */
+    @Override
+    public void notificationRecvTopologyElementUpdated(TopologyElement topologyElement) {
+	// NOTE: The ADD and UPDATE events are processed in same way
+	EventEntry<TopologyElement> eventEntry =
+	    new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
+	networkEvents.add(eventEntry);
+    }
+}