* Update the Topology class implementation:
  - The port IDs are type "integer" instead of "short" so it will be easier
    to use it for more general purpose (e.g., topologies with lots of tunnels).
  - Implemented methods to get/add/remove various topology elements:
    switch, port, link
  - Added state to keep track of the reversed unidirectional links, so they
    can be properly removed if a switch or a port is removed.
* Add a Topology instance inside the PathComputation class, and
  populate it as appropriate with ENTRY_ADD/ENTRY_REMOVE topology events
  from the datagrid.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java b/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
index a2f2c21..612b72a 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
@@ -24,18 +24,18 @@
     class Link {
 	public Node me;			// The node this link originates from
 	public Node neighbor;		// The neighbor node on the other side
-	public short myPort;		// Local port number for the link
-	public short neighborPort;	// Neighbor port number for the link
+	public int myPort;		// Local port ID for the link
+	public int neighborPort;	// Neighbor port ID for the link
 
 	/**
 	 * Link constructor.
 	 *
 	 * @param me the node this link originates from.
 	 * @param the neighbor node on the other side of the link.
-	 * @param myPort local port number for the link.
-	 * @param neighborPort neighrobr port number for the link.
+	 * @param myPort local port ID for the link.
+	 * @param neighborPort neighbor port ID for the link.
 	 */
-	public Link(Node me, Node neighbor, short myPort, short neighborPort) {
+	public Link(Node me, Node neighbor, int myPort, int neighborPort) {
 	    this.me = me;
 	    this.neighbor = neighbor;
 	    this.myPort = myPort;
@@ -43,8 +43,10 @@
 	}
     };
 
-    public long nodeId;			// The node ID
-    public HashMap<Short, Link> links;	// The links originating from this node
+    public long nodeId;				// The node ID
+    public HashMap<Integer, Link> links;	// The links from this node
+    private HashMap<Integer, Link> reverseLinksMap; // The links to this node
+    private HashMap<Integer, Integer> portsMap;	// The ports for this node
 
     /**
      * Node constructor.
@@ -53,21 +55,124 @@
      */
     public Node(long nodeId) {
 	this.nodeId = nodeId;
-	links = new HashMap<Short, Link>();
+	links = new HashMap<Integer, Link>();
+	reverseLinksMap = new HashMap<Integer, Link>();
+	portsMap = new HashMap<Integer, Integer>();
     }
 
     /**
-     * Add a neighbor.
+     * Get all ports.
      *
-     * A new link to the neighbor will be created. 
-     *
-     * @param neighbor the neighbor to add.
-     * @param myPort the local port number for the link to the neighbor.
-     * @param neighborPort the neighbor port number for the link.
+     * @return all ports.
      */
-    public void addNeighbor(Node neighbor, short myPort, short neighborPort) {
-	Link link = new Link(this, neighbor, myPort, neighborPort);
-	links.put(myPort, link);
+    public Map<Integer, Integer> ports() {
+	return portsMap;
+    }
+
+    /**
+     * Get the port for a given Port ID.
+     *
+     * Note: For now the port itself is just the Port ID. In the future
+     * it might contain more information.
+     *
+     * @return the port if found, otherwise null.
+     */
+    public Integer getPort(int portId) {
+	return portsMap.get(nodeId);
+    }
+
+    /**
+     * Add a port for a given Port ID.
+     *
+     * Note: For now the port itself is just the Port ID. In the future
+     * it might contain more information.
+     *
+     * @param portId the Port ID of the port to add.
+     * @return the added Port.
+     */
+    Integer addPort(int portId) {
+	Integer port = new Integer(portId);
+	portsMap.put(portId, port);
+	return port;
+    }
+
+    /**
+     * Remove a port for a given Port ID.
+     *
+     * NOTE: The outgoing and incoming links using this port are removed as
+     * well.
+     */
+    void removePort(int portId) {
+	// Remove the outgoing link
+	Link link = getLink(portId);
+	if (link != null) {
+	    link.neighbor.removeReverseLink(link);
+	    removeLink(portId);
+	}
+
+	// Remove the incoming link
+	Link reverseLink = reverseLinksMap.get(portId);
+	if (reverseLink != null) {
+	    // NOTE: reverseLink.myPort is the neighbor's outgoing port
+	    reverseLink.neighbor.removeLink(reverseLink.myPort);
+	    removeReverseLink(reverseLink);
+	}
+
+	portsMap.remove(portId);
+    }
+    
+    /**
+     * Get a link on a port to a neighbor.
+     *
+     * @param myPortId the local port ID for the link to the neighbor.
+     * @return the link if found, otherwise null.
+     */
+    public Link getLink(int myPortId) {
+	return links.get(myPortId);
+    }
+
+    /**
+     * Add a link to a neighbor.
+     *
+     * @param myPortId the local port ID for the link to the neighbor.
+     * @param neighbor the neighbor for the link.
+     * @param neighborPortId the neighbor port ID for the link.
+     * @return the added Link.
+     */
+    public Link addLink(int myPortId, Node neighbor, int neighborPortId) {
+	Link link = new Link(this, neighbor, myPortId, neighborPortId);
+	links.put(myPortId, link);
+	neighbor.addReverseLink(link);
+	return link;
+    }
+
+    /**
+     * Add a reverse link from a neighbor.
+     *
+     * @param link the reverse link from a neighbor to add.
+     */
+    private void addReverseLink(Link link) {
+	// NOTE: link.neghborPort is my port
+	reverseLinksMap.put(link.neighborPort, link);
+    }
+
+    /**
+     * Remove a link to a neighbor.
+     *
+     * @param myPortId the local port ID for the link to the neighbor.
+     */
+    public void removeLink(int myPortId) {
+	links.remove(myPortId);
+    }
+
+    /**
+     * Remove a reverse link from a neighbor.
+     *
+     * @param link the reverse link from a neighbor to remove.
+     */
+    private void removeReverseLink(Link link) {
+	// NOTE: link.neghborPort is my port
+	reverseLinksMap.remove(link.neighborPort);
     }
 };
 
@@ -77,12 +182,147 @@
 public class Topology {
     private Map<Long, Node> nodesMap;	// The dpid->Node mapping
 
+    /**
+     * Default constructor.
+     */
     public Topology() {
 	nodesMap = new HashMap<Long, Node>();
     }
 
     /**
-     * Get a node for a give Node ID.
+     * Add a topology element to the topology.
+     *
+     * @param topologyElement the topology element to add.
+     * @return true if the topology was modified, otherwise false.
+     */
+    public boolean addTopologyElement(TopologyElement topologyElement) {
+	boolean isModified = false;
+
+	switch (topologyElement.getType()) {
+	case ELEMENT_SWITCH: {
+	    // Add the switch
+	    Node node = getNode(topologyElement.getSwitch());
+	    if (node == null) {
+		node = addNode(topologyElement.getSwitch());
+		isModified = true;
+	    }
+	    // Add the ports for the switch
+	    for (Integer portId : topologyElement.getSwitchPorts().values()) {
+		Integer port = node.getPort(portId);
+		if (port == null) {
+		    node.addPort(portId);
+		    isModified = true;
+		}
+	    }
+	    break;
+	}
+	case ELEMENT_PORT: {
+	    // Add the switch
+	    Node node = getNode(topologyElement.getSwitch());
+	    if (node == null) {
+		node = addNode(topologyElement.getSwitch());
+		isModified = true;
+	    }
+	    // Add the port for the switch
+	    Integer port = node.getPort(topologyElement.getSwitchPort());
+	    if (port == null) {
+		node.addPort(topologyElement.getSwitchPort());
+		isModified = true;
+	    }
+	    break;
+	}
+	case ELEMENT_LINK: {
+	    // Add the "from" switch
+	    Node fromNode = getNode(topologyElement.getFromSwitch());
+	    if (fromNode == null) {
+		fromNode = addNode(topologyElement.getFromSwitch());
+		isModified = true;
+	    }
+	    // Add the "to" switch
+	    Node toNode = getNode(topologyElement.getToSwitch());
+	    if (toNode == null) {
+		toNode = addNode(topologyElement.getToSwitch());
+		isModified = true;
+	    }
+	    // Add the "from" port
+	    Integer fromPort = fromNode.getPort(topologyElement.getFromPort());
+	    if (fromPort == null) {
+		fromNode.addPort(topologyElement.getFromPort());
+		isModified = true;
+	    }
+	    // Add the "to" port
+	    Integer toPort = fromNode.getPort(topologyElement.getToPort());
+	    if (toPort == null) {
+		toNode.addPort(topologyElement.getToPort());
+		isModified = true;
+	    }
+	    Node.Link link = fromNode.getLink(topologyElement.getFromPort());
+	    if (link == null) {
+		fromNode.addLink(topologyElement.getFromPort(),
+				 toNode,
+				 topologyElement.getToPort());
+		isModified = true;
+	    }
+
+	    break;
+	}
+	}
+
+	return isModified;
+    }
+
+    /**
+     * Remove a topology element from the topology.
+     *
+     * @param topologyElement the topology element to remove.
+     * @return true if the topology was modified, otherwise false.
+     */
+    public boolean removeTopologyElement(TopologyElement topologyElement) {
+	boolean isModified = false;
+
+	switch (topologyElement.getType()) {
+	case ELEMENT_SWITCH: {
+	    // Remove the switch
+	    Node node = getNode(topologyElement.getSwitch());
+	    if (node != null) {
+		removeNode(node);
+		isModified = true;
+	    }
+	    break;
+	}
+	case ELEMENT_PORT: {
+	    // Find the switch
+	    Node node = getNode(topologyElement.getSwitch());
+	    if (node == null)
+		break;
+	    // Remove the port for the switch
+	    Integer port = node.getPort(topologyElement.getSwitchPort());
+	    if (port != null) {
+		node.removePort(topologyElement.getSwitchPort());
+		isModified = true;
+	    }
+	    break;
+	}
+	case ELEMENT_LINK: {
+	    // Find the "from" switch
+	    Node fromNode = getNode(topologyElement.getFromSwitch());
+	    if (fromNode == null)
+		break;
+	    // Remove the link originating from the "from" port
+	    Node.Link link = fromNode.getLink(topologyElement.getFromPort());
+	    if (link != null) {
+		fromNode.removeLink(topologyElement.getFromPort());
+		isModified = true;
+	    }
+	    break;
+	}
+	}
+
+	return isModified;
+    }
+
+    /**
+     * Get a node for a given Node ID.
      *
      * @param nodeId the Node ID to use.
      * @return the corresponding Node if found, otherwise null.
@@ -92,6 +332,34 @@
     }
 
     /**
+     * Add a node for a given Node ID.
+     *
+     * @param nodeId the Node ID to use.
+     * @return the added Node.
+     */
+    Node addNode(long nodeId) {
+	Node node = new Node(nodeId);
+	nodesMap.put(nodeId, node);
+	return node;
+    }
+
+    /**
+     * Remove an existing node.
+     *
+     * @param node the Node to remove.
+     */
+    void removeNode(Node node) {
+	//
+	// Remove all ports one-by-one. This operation will also remove the
+	// incoming links originating from the neighbors.
+	//
+	for (Integer portId : node.ports().keySet())
+	    node.removePort(portId);
+
+	nodesMap.remove(node.nodeId);
+    }
+
+    /**
      * Read topology state from the database.
      *
      * @param dbHandler the Graph Database handler to use.
@@ -110,10 +378,8 @@
 	    String nodeDpid = nodeVertex.getProperty("dpid").toString();
 	    long nodeId = HexString.toLong(nodeDpid);
 	    Node me = nodesMap.get(nodeId);
-	    if (me == null) {
-		me = new Node(nodeId);
-		nodesMap.put(nodeId, me);
-	    }
+	    if (me == null)
+		me = addNode(nodeId);
 
 	    //
 	    // The local Port info
@@ -123,13 +389,12 @@
 		if (! myPortVertex.getProperty("state").toString().equals("ACTIVE"))
 		    continue;
 
-		short myPort = 0;
+		int myPort = 0;
 		Object obj = myPortVertex.getProperty("number");
 		if (obj instanceof Short) {
 		    myPort = (Short)obj;
 		} else if (obj instanceof Integer) {
-		    Integer int_nodeId = (Integer)obj;
-		    myPort = int_nodeId.shortValue();
+		    myPort = (Integer)obj;
 		}
 
 		//
@@ -140,13 +405,12 @@
 		    if (! neighborPortVertex.getProperty("state").toString().equals("ACTIVE"))
 			continue;
 
-		    short neighborPort = 0;
+		    int neighborPort = 0;
 		    obj = neighborPortVertex.getProperty("number");
 		    if (obj instanceof Short) {
 			neighborPort = (Short)obj;
 		    } else if (obj instanceof Integer) {
-			Integer int_nodeId = (Integer)obj;
-			neighborPort = int_nodeId.shortValue();
+			neighborPort = (Integer)obj;
 		    }
 		    //
 		    // The neighbor Switch info
@@ -160,11 +424,9 @@
 			String neighborDpid = neighborVertex.getProperty("dpid").toString();
 			long neighborId = HexString.toLong(neighborDpid);
 			Node neighbor = nodesMap.get(neighborId);
-			if (neighbor == null) {
-			    neighbor = new Node(neighborId);
-			    nodesMap.put(neighborId, neighbor);
-			}
-			me.addNeighbor(neighbor, myPort, neighborPort);
+			if (neighbor == null)
+			    neighbor = addNode(neighborId);
+			me.addLink(myPort, neighbor, neighborPort);
 		    }
 		}
 	    }