Topology interface to use Dpid, PortNumber

- Modified Switch interface to use Dpid, PortNumber instead of Long
- Modified Port interface to use Dpid, PortNumber instead of Long
- Modified Topology interface which uses Dpid, PortNumber, SwitchPort

- PortImpl#toString() format has changed: "%d:%d" -> "Dpid#toString():PortNumber#toString"

- Part of ONOS-1564

Change-Id: I8decdbb2fb0cce9e087ad49af3a087b65b8511d7
diff --git a/src/main/java/net/onrc/onos/apps/forwarding/Forwarding.java b/src/main/java/net/onrc/onos/apps/forwarding/Forwarding.java
index 830998c..0a2ed39 100644
--- a/src/main/java/net/onrc/onos/apps/forwarding/Forwarding.java
+++ b/src/main/java/net/onrc/onos/apps/forwarding/Forwarding.java
@@ -262,7 +262,7 @@
         }
 
         packetService.broadcastPacketOutEdge(eth,
-                new SwitchPort(sw.getDpid(), inPort.getNumber().shortValue()));
+                new SwitchPort(sw.getDpid(), inPort.getNumber()));
     }
 
     private void handlePacketIn(Switch sw, Port inPort, Ethernet eth) {
@@ -333,18 +333,17 @@
         }
 
         //This code assumes the device has only one port. It should be problem.
-        net.onrc.onos.core.topology.Port portObject = ports.next();
-        short destinationPort = portObject.getNumber().shortValue();
-        Switch switchObject = portObject.getSwitch();
-        long destinationDpid = switchObject.getDpid();
+        Port destinationPort = ports.next();
+        short destinationPortNum = destinationPort.getNumber().value();
+        Switch destinationSw = destinationPort.getSwitch();
+        long destinationDpid = destinationSw.getDpid().value();
 
-        // TODO eliminate cast
         SwitchPort srcSwitchPort = new SwitchPort(
-                new Dpid(sw.getDpid()),
-                new PortNumber((short) inPort.getNumber().longValue()));
+                sw.getDpid(),
+                inPort.getNumber());
         SwitchPort dstSwitchPort = new SwitchPort(
-                new Dpid(destinationDpid),
-                new PortNumber(destinationPort));
+                destinationSw.getDpid(),
+                destinationPort.getNumber());
 
         MACAddress srcMacAddress = MACAddress.valueOf(eth.getSourceMACAddress());
         MACAddress dstMacAddress = MACAddress.valueOf(eth.getDestinationMACAddress());
@@ -412,7 +411,7 @@
                     net.onrc.onos.core.intent.Path path = pathIntent.getPath();
                     long outPort = -1;
 
-                    if (spfIntent.getDstSwitchDpid() == sw.getDpid()) {
+                    if (spfIntent.getDstSwitchDpid() == sw.getDpid().value()) {
                         log.trace("The packet-in sw dpid {} is on the path.", sw.getDpid());
                         isflowEntryForThisSwitch = true;
                         outPort = spfIntent.getDstPortNumber();
@@ -421,10 +420,10 @@
                     for (Iterator<LinkEvent> i = path.iterator(); i.hasNext();) {
                         LinkEvent le = i.next();
 
-                        if (le.getSrc().dpid.equals(sw.getDpid())) {
+                        if (new Dpid(le.getSrc().dpid).equals(sw.getDpid())) {
                             log.trace("The packet-in sw dpid {} is on the path.", sw.getDpid());
                             isflowEntryForThisSwitch = true;
-                            outPort = le.getSrc().getNumber();
+                            outPort = le.getSrc().getNumber().value();
                             break;
                         }
                     }
@@ -443,21 +442,21 @@
 
                         log.debug("Sending packet out from sw {}, outport{}", sw.getDpid(), outPort);
                         packetService.sendPacket(eth, new SwitchPort(
-                                sw.getDpid(), (short) outPort));
+                                sw.getDpid(), new PortNumber((short) outPort)));
                     }
                 } else {
                     // Flow path has not yet been installed to switches so save the
                     // packet out for later
                     log.trace("Put a packet into the waiting list. flowId {}", existingFlow.intentId);
-                    waitingPackets.put(existingFlow.intentId, new PacketToPush(eth, sw.getDpid()));
+                    waitingPackets.put(existingFlow.intentId, new PacketToPush(eth, sw.getDpid().value()));
                 }
                 return;
             }
 
             String intentId = Long.toString(controllerRegistryService.getNextUniqueId());
             ShortestPathIntent intent = new ShortestPathIntent(intentId,
-                    sw.getDpid(), inPort.getNumber(), srcMacAddress.toLong(),
-                    destinationDpid, destinationPort, dstMacAddress.toLong());
+                    sw.getDpid().value(), inPort.getNumber().value(), srcMacAddress.toLong(),
+                    destinationDpid, destinationPortNum, dstMacAddress.toLong());
 
             intent.setIdleTimeout(idleTimeout + SRC_SWITCH_TIMEOUT_ADJUST_SECOND);
             intent.setFirstSwitchIdleTimeout(idleTimeout);
@@ -467,7 +466,7 @@
                     new Object[]{srcMacAddress, srcSwitchPort, dstMacAddress, dstSwitchPort});
 
              // Add to waiting lists
-            waitingPackets.put(intentId, new PacketToPush(eth, sw.getDpid()));
+            waitingPackets.put(intentId, new PacketToPush(eth, sw.getDpid().value()));
             log.trace("Put a Packet in the wating list. intent ID {}, related pathspec {}", intentId, pathspec);
             pendingFlows.put(pathspec, new PushedFlow(intentId));
             log.trace("Put a Path {} in the pending flow, intent ID {}", pathspec, intentId);
@@ -529,7 +528,7 @@
             outPort = (short) spfIntent.getDstPortNumber();
             log.debug("Path is empty. Maybe devices on the same switch. outPort {}", outPort);
         } else {
-            outPort = graphPath.get(0).getSrc().getNumber().shortValue();
+            outPort = graphPath.get(0).getSrc().getNumber().value();
             log.debug("path{}, outPort {}", graphPath, outPort);
         }
 
diff --git a/src/main/java/net/onrc/onos/apps/proxyarp/ProxyArpManager.java b/src/main/java/net/onrc/onos/apps/proxyarp/ProxyArpManager.java
index 1b3167d..183703c 100644
--- a/src/main/java/net/onrc/onos/apps/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/apps/proxyarp/ProxyArpManager.java
@@ -33,6 +33,8 @@
 import net.onrc.onos.core.topology.Port;
 import net.onrc.onos.core.topology.Switch;
 import net.onrc.onos.core.topology.Topology;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.PortNumber;
 import net.onrc.onos.core.util.SwitchPort;
 
 import org.openflow.util.HexString;
@@ -372,7 +374,7 @@
             ARP arp = (ARP) eth.getPayload();
             learnArp(arp);
             if (arp.getOpCode() == ARP.OP_REQUEST) {
-                handleArpRequest(sw.getDpid(), inPort.getNumber().shortValue(),
+                handleArpRequest(sw.getDpid().value(), inPort.getNumber().value(),
                         arp, eth);
             } else if (arp.getOpCode() == ARP.OP_REPLY) {
                 // For replies we simply send a notification via Hazelcast
@@ -476,14 +478,14 @@
                         continue;
                     }
 
-                    short outPort = portObject.getNumber().shortValue();
+                    PortNumber outPort = portObject.getNumber();
                     Switch outSwitchObject = portObject.getSwitch();
-                    long outSwitch = outSwitchObject.getDpid();
+                    Dpid outSwitch = outSwitchObject.getDpid();
 
                     if (log.isTraceEnabled()) {
                         log.trace("Probing device {} on port {}/{}",
                                 new Object[]{macAddress,
-                                        HexString.toHexString(outSwitch), outPort});
+                                        outSwitch, outPort});
                     }
 
                     packetService.sendPacket(
diff --git a/src/main/java/net/onrc/onos/core/datagrid/web/GetNGFlowsSummaryResource.java b/src/main/java/net/onrc/onos/core/datagrid/web/GetNGFlowsSummaryResource.java
index 1f143cb..da30293 100644
--- a/src/main/java/net/onrc/onos/core/datagrid/web/GetNGFlowsSummaryResource.java
+++ b/src/main/java/net/onrc/onos/core/datagrid/web/GetNGFlowsSummaryResource.java
@@ -97,7 +97,7 @@
             FlowEntry flowEntry;
             ArrayList<FlowEntry> flowEntries = new ArrayList<>();
             for (LinkEvent linkEvent : path) {
-                Dpid dpid = new Dpid(linkEvent.getSrc().getDpid());
+                Dpid dpid = linkEvent.getSrc().getDpid();
                 flowEntry = new FlowEntry();
                 flowEntry.setDpid(dpid);
                 flowEntries.add(flowEntry);
diff --git a/src/main/java/net/onrc/onos/core/datastore/topology/KVLink.java b/src/main/java/net/onrc/onos/core/datastore/topology/KVLink.java
index 0945071..982bcb4 100644
--- a/src/main/java/net/onrc/onos/core/datastore/topology/KVLink.java
+++ b/src/main/java/net/onrc/onos/core/datastore/topology/KVLink.java
@@ -11,6 +11,8 @@
 import net.onrc.onos.core.datastore.utils.KVObject;
 import net.onrc.onos.core.topology.LinkEvent;
 import net.onrc.onos.core.topology.PortEvent;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.PortNumber;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -40,6 +42,7 @@
         }
     };
 
+    // TODO eliminate this class and util SwitchPort.
     /**
      * Internal data structure to represent a port on a switch.
      */
@@ -59,6 +62,17 @@
         }
 
         /**
+         * Constructor.
+         *
+         * @param dpid datapath ID of this switch port
+         * @param number port number of this port on switch({@code dpid})
+         */
+        public SwitchPort(final Dpid srcDpid, final PortNumber srcPortNo) {
+            this.dpid = srcDpid.value();
+            this.number = (long) srcPortNo.value();
+        }
+
+        /**
          * Gets the PortID of a port this object represent.
          *
          * @return PortID
@@ -106,6 +120,21 @@
      * @param dstPortNo destination port number
      * @return LinkID
      */
+    public static byte[] getLinkID(final Dpid srcDpid, final PortNumber srcPortNo,
+                                   final Dpid dstDpid, final PortNumber dstPortNo) {
+        return LinkEvent.getLinkID(srcDpid, srcPortNo,
+                                   dstDpid, dstPortNo).array();
+    }
+
+    /**
+     * Generate a LinkID from Link 4-tuples.
+     *
+     * @param srcDpid source DPID
+     * @param srcPortNo source port number
+     * @param dstDpid destination DPID
+     * @param dstPortNo destination port number
+     * @return LinkID
+     */
     public static byte[] getLinkID(final Long srcDpid, final Long srcPortNo,
                                    final Long dstDpid, final Long dstPortNo) {
         return LinkEvent.getLinkID(srcDpid, srcPortNo, dstDpid,
@@ -182,6 +211,41 @@
     }
 
     /**
+     * KVLink constructor for default namespace.
+     *
+     * @param srcDpid source DPID
+     * @param srcPortNo source port number
+     * @param dstDpid destination DPID
+     * @param dstPortNo destination port number
+     */
+    public KVLink(final Dpid srcDpid, final PortNumber srcPortNo,
+            final Dpid dstDpid, final PortNumber dstPortNo) {
+        this(srcDpid, srcPortNo, dstDpid, dstPortNo, DEFAULT_NAMESPACE);
+    }
+
+    /**
+     * KVLink constructor for specified namespace.
+     *
+     * @param srcDpid source DPID
+     * @param srcPortNo source port number
+     * @param dstDpid destination DPID
+     * @param dstPortNo destination port number
+     * @param namespace namespace to create this object
+     */
+    public KVLink(final Dpid srcDpid, final PortNumber srcPortNo,
+                  final Dpid dstDpid, final PortNumber dstPortNo,
+                  final String namespace) {
+        super(DataStoreClient.getClient()
+                .getTable(namespace + LINK_TABLE_SUFFIX),
+                getLinkID(srcDpid, srcPortNo, dstDpid, dstPortNo),
+                namespace);
+
+        src = new SwitchPort(srcDpid, srcPortNo);
+        dst = new SwitchPort(dstDpid, dstPortNo);
+        status = STATUS.INACTIVE;
+    }
+
+    /**
      * Gets an instance from LinkID in default namespace.
      * <p/>
      * Note: You need to call `read()` to get the DB content.
diff --git a/src/main/java/net/onrc/onos/core/datastore/topology/KVPort.java b/src/main/java/net/onrc/onos/core/datastore/topology/KVPort.java
index 72fa348..9a3014e 100644
--- a/src/main/java/net/onrc/onos/core/datastore/topology/KVPort.java
+++ b/src/main/java/net/onrc/onos/core/datastore/topology/KVPort.java
@@ -11,6 +11,8 @@
 import net.onrc.onos.core.datastore.utils.ByteArrayUtil;
 import net.onrc.onos.core.datastore.utils.KVObject;
 import net.onrc.onos.core.topology.PortEvent;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.PortNumber;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -66,6 +68,17 @@
      * @param number port number of this
      * @return PortID
      */
+    public static byte[] getPortID(final Dpid dpid, final PortNumber number) {
+        return PortEvent.getPortID(dpid, number).array();
+    }
+
+    /**
+     * Generate a PortID from port pair (dpid, number).
+     *
+     * @param dpid DPID of a switch it reside on.
+     * @param number port number of this
+     * @return PortID
+     */
     public static byte[] getPortID(final Long dpid, final Long number) {
         return PortEvent.getPortID(dpid, number).array();
     }
@@ -152,6 +165,27 @@
     }
 
     /**
+     * KVPort constructor for default namespace.
+     *
+     * @param dpid DPID of the switch this port is on
+     * @param number port number of this port
+     */
+    public KVPort(final Dpid dpid, final PortNumber number) {
+        this(dpid, number, DEFAULT_NAMESPACE);
+    }
+
+    /**
+     * KVPort constructor for specified namespace.
+     *
+     * @param dpid DPID of the switch this port is on
+     * @param number port number of this port
+     * @param namespace namespace to create this object
+     */
+    public KVPort(final Dpid dpid, final PortNumber number, final String namespace) {
+        this(dpid.value(), (long) number.value(), namespace);
+    }
+
+    /**
      * Gets an instance from PortID in default namespace.
      * <p/>
      * Note: You need to call `read()` to get the DB content.
diff --git a/src/main/java/net/onrc/onos/core/datastore/topology/KVSwitch.java b/src/main/java/net/onrc/onos/core/datastore/topology/KVSwitch.java
index c9151de..1d9b58e 100644
--- a/src/main/java/net/onrc/onos/core/datastore/topology/KVSwitch.java
+++ b/src/main/java/net/onrc/onos/core/datastore/topology/KVSwitch.java
@@ -10,6 +10,7 @@
 import net.onrc.onos.core.datastore.serializers.Topology.SwitchProperty;
 import net.onrc.onos.core.datastore.utils.KVObject;
 import net.onrc.onos.core.topology.SwitchEvent;
+import net.onrc.onos.core.util.Dpid;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -117,6 +118,25 @@
     }
 
     /**
+     * KVSwitch constructor for default namespace.
+     *
+     * @param dpid dpid of this switch
+     */
+    public KVSwitch(final Dpid dpid) {
+        this(dpid, KVObject.DEFAULT_NAMESPACE);
+    }
+
+    /**
+     * KVSwitch constructor for specified namespace.
+     *
+     * @param dpid dpid of this switch
+     * @param namespace namespace to create this object
+     */
+    public KVSwitch(final Dpid dpid, final String namespace) {
+        this(dpid.value(), namespace);
+    }
+
+    /**
      * Gets an instance from SwitchID in default namespace.
      * <p/>
      * Note: You need to call `read()` to get the DB content.
diff --git a/src/main/java/net/onrc/onos/core/devicemanager/OnosDeviceManager.java b/src/main/java/net/onrc/onos/core/devicemanager/OnosDeviceManager.java
index 0c7a75e..30ffb19 100644
--- a/src/main/java/net/onrc/onos/core/devicemanager/OnosDeviceManager.java
+++ b/src/main/java/net/onrc/onos/core/devicemanager/OnosDeviceManager.java
@@ -28,6 +28,8 @@
 import net.onrc.onos.core.topology.ITopologyService;
 import net.onrc.onos.core.topology.Port;
 import net.onrc.onos.core.topology.Topology;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.PortNumber;
 
 import org.openflow.protocol.OFMessage;
 import org.openflow.protocol.OFPacketIn;
@@ -120,12 +122,12 @@
             log.trace("Receive PACKET_IN swId {}, portId {}", sw.getId(), pi.getInPort());
         }
 
-        long dpid = sw.getId();
-        short portId = pi.getInPort();
+        final Dpid dpid = new Dpid(sw.getId());
+        final PortNumber portNum = new PortNumber(pi.getInPort());
         Long mac = eth.getSourceMAC().toLong();
 
         OnosDevice srcDevice =
-                getSourceDeviceFromPacket(eth, dpid, portId);
+                getSourceDeviceFromPacket(eth, dpid.value(), portNum.value());
 
         if (srcDevice == null) {
             return Command.STOP;
@@ -137,11 +139,11 @@
         // the Topology module.
         topology.acquireReadLock();
         try {
-            if (topology.getOutgoingLink(dpid, (long) portId) != null ||
-                    topology.getIncomingLink(dpid, (long) portId) != null) {
+            if (topology.getOutgoingLink(dpid, portNum) != null ||
+                    topology.getIncomingLink(dpid, portNum) != null) {
                 log.debug("Stop adding OnosDevice {} as " +
                     "there is a link on the port: dpid {} port {}",
-                    srcDevice.getMacAddress(), dpid, portId);
+                    srcDevice.getMacAddress(), dpid, portNum);
                 return Command.CONTINUE;
             }
         } finally {
@@ -282,8 +284,8 @@
                 // We don't handle vlan now and multiple attachment points.
                 deleteDevice = new OnosDevice(dev.getMacAddress(),
                         null,
-                        switchPort.getDpid(),
-                        switchPort.getNumber(),
+                        switchPort.getDpid().value(),
+                        (long) switchPort.getNumber().value(),
                         new Date(dev.getLastSeenTime()));
                 break;
             }
diff --git a/src/main/java/net/onrc/onos/core/intent/ConstrainedBFSTree.java b/src/main/java/net/onrc/onos/core/intent/ConstrainedBFSTree.java
index 3f92a29..fac7af9 100644
--- a/src/main/java/net/onrc/onos/core/intent/ConstrainedBFSTree.java
+++ b/src/main/java/net/onrc/onos/core/intent/ConstrainedBFSTree.java
@@ -7,6 +7,7 @@
 import net.onrc.onos.core.topology.Link;
 import net.onrc.onos.core.topology.LinkEvent;
 import net.onrc.onos.core.topology.Switch;
+import net.onrc.onos.core.util.Dpid;
 
 /**
  * This class creates bandwidth constrained breadth first tree and returns paths
@@ -18,7 +19,7 @@
 public class ConstrainedBFSTree {
     LinkedList<Switch> switchQueue = new LinkedList<>();
     HashSet<Switch> switchSearched = new HashSet<>();
-    HashMap<Long, LinkEvent> upstreamLinks = new HashMap<>();
+    HashMap<Dpid, LinkEvent> upstreamLinks = new HashMap<>();
     HashMap<Switch, Path> paths = new HashMap<>();
     Switch rootSwitch;
     PathIntentMap intents = null;
@@ -80,10 +81,10 @@
      */
     public Path getPath(Switch leafSwitch) {
         Path path = paths.get(leafSwitch);
-        Long rootSwitchDpid = rootSwitch.getDpid();
+        Dpid rootSwitchDpid = rootSwitch.getDpid();
         if (path == null && switchSearched.contains(leafSwitch)) {
             path = new Path();
-            Long sw = leafSwitch.getDpid();
+            Dpid sw = leafSwitch.getDpid();
             while (!sw.equals(rootSwitchDpid)) {
                 LinkEvent upstreamLink = upstreamLinks.get(sw);
                 path.add(0, upstreamLink);
diff --git a/src/main/java/net/onrc/onos/core/intent/PathIntentMap.java b/src/main/java/net/onrc/onos/core/intent/PathIntentMap.java
index 12c81c5..dae154e 100644
--- a/src/main/java/net/onrc/onos/core/intent/PathIntentMap.java
+++ b/src/main/java/net/onrc/onos/core/intent/PathIntentMap.java
@@ -32,8 +32,8 @@
      * @return a set of all intents that contain swPort
      */
     private HashSet<PathIntent> get(SwitchPort swPort) {
-        Long dpid = swPort.getDpid();
-        Long port = swPort.getNumber();
+        Long dpid = swPort.getDpid().value();
+        Long port = (long) swPort.getNumber().value();
         HashMap<Long, HashSet<PathIntent>> portToIntents = intents.get(dpid);
         if (portToIntents == null) {
             portToIntents = new HashMap<>();
@@ -100,8 +100,8 @@
      */
     public Collection<PathIntent> getIntentsByLink(LinkEvent linkEvent) {
         return getIntentsByPort(
-                linkEvent.getSrc().getDpid(),
-                linkEvent.getSrc().getNumber());
+                linkEvent.getSrc().getDpid().value(),
+                (long) linkEvent.getSrc().getNumber().value());
     }
 
     /**
diff --git a/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntime.java b/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntime.java
index 3dc5252..d4452e1 100644
--- a/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntime.java
+++ b/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntime.java
@@ -19,6 +19,7 @@
 import net.onrc.onos.core.intent.ShortestPathIntent;
 import net.onrc.onos.core.topology.Switch;
 import net.onrc.onos.core.topology.Topology;
+import net.onrc.onos.core.util.Dpid;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -69,8 +70,8 @@
                     }
 
                     ShortestPathIntent spIntent = (ShortestPathIntent) intentOp.intent;
-                    Switch srcSwitch = topology.getSwitch(spIntent.getSrcSwitchDpid());
-                    Switch dstSwitch = topology.getSwitch(spIntent.getDstSwitchDpid());
+                    Switch srcSwitch = topology.getSwitch(new Dpid(spIntent.getSrcSwitchDpid()));
+                    Switch dstSwitch = topology.getSwitch(new Dpid(spIntent.getDstSwitchDpid()));
                     if (srcSwitch == null || dstSwitch == null) {
                         log.debug("Switch not found. src:{}, dst:{}",
                                 spIntent.getSrcSwitchDpid(),
diff --git a/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModule.java b/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModule.java
index f850c58..b41b68a 100644
--- a/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModule.java
+++ b/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModule.java
@@ -272,7 +272,7 @@
         ShortestPathIntent spfIntent = (ShortestPathIntent) pathIntent.getParentIntent();
 
         for (LinkEvent linkEvent : pathIntent.getPath()) {
-            long sw = linkEvent.getSrc().getDpid();
+            long sw = linkEvent.getSrc().getDpid().value();
             allSwitchesForPath.add(sw);
         }
         allSwitchesForPath.add(spfIntent.getDstSwitchDpid());
@@ -304,7 +304,7 @@
         ShortestPathIntent spfIntent = (ShortestPathIntent) pathIntent.getParentIntent();
 
         for (LinkEvent linkEvent : pathIntent.getPath()) {
-            long sw = linkEvent.getSrc().getDpid();
+            long sw = linkEvent.getSrc().getDpid().value();
 
             if (domainSwitchDpids.contains(sw)) {
                 allSwitchesForPath.add(sw);
@@ -702,13 +702,15 @@
 
             p.log("begin_getIntentsByPort");
             for (PortEvent portEvent : removedPortEvents) {
-                affectedPaths.addAll(pathIntents.getIntentsByPort(portEvent.getDpid(), portEvent.getNumber()));
+                affectedPaths.addAll(pathIntents.getIntentsByPort(
+                        portEvent.getDpid().value(),
+                        (long) portEvent.getNumber().value()));
             }
             p.log("end_getIntentsByPort");
 
             p.log("begin_getIntentsByDpid");
             for (SwitchEvent switchEvent : removedSwitchEvents) {
-                affectedPaths.addAll(pathIntents.getIntentsByDpid(switchEvent.getDpid()));
+                affectedPaths.addAll(pathIntents.getIntentsByDpid(switchEvent.getDpid().value()));
             }
             p.log("end_getIntentsByDpid");
         }
diff --git a/src/main/java/net/onrc/onos/core/intent/runtime/PlanCalcRuntime.java b/src/main/java/net/onrc/onos/core/intent/runtime/PlanCalcRuntime.java
index bec9dd0..c47c832 100644
--- a/src/main/java/net/onrc/onos/core/intent/runtime/PlanCalcRuntime.java
+++ b/src/main/java/net/onrc/onos/core/intent/runtime/PlanCalcRuntime.java
@@ -118,8 +118,8 @@
             }
             List<FlowEntry> entries = new ArrayList<>();
             for (LinkEvent linkEvent : intent.getPath()) {
-                long sw = linkEvent.getSrc().getDpid();
-                dstPort = linkEvent.getSrc().getNumber();
+                long sw = linkEvent.getSrc().getDpid().value();
+                dstPort = linkEvent.getSrc().getNumber().value();
                 FlowEntry fe = new FlowEntry(sw, srcPort, dstPort, srcMac, dstMac,
                                              srcIP, dstIP, i.operator);
                 if (sw != firstSrcSw) {
@@ -134,7 +134,7 @@
                     fe.setFlowEntryId(cookieId);
                 }
                 entries.add(fe);
-                srcPort = linkEvent.getDst().getNumber();
+                srcPort = linkEvent.getDst().getNumber().value();
             }
             if (lastDstSw >= 0 && lastDstPort >= 0) {
                 long sw = lastDstSw;
diff --git a/src/main/java/net/onrc/onos/core/intent/runtime/web/ShortestPathResource.java b/src/main/java/net/onrc/onos/core/intent/runtime/web/ShortestPathResource.java
index 9f0019c..58f9b2d 100644
--- a/src/main/java/net/onrc/onos/core/intent/runtime/web/ShortestPathResource.java
+++ b/src/main/java/net/onrc/onos/core/intent/runtime/web/ShortestPathResource.java
@@ -11,7 +11,6 @@
 import net.onrc.onos.core.topology.Switch;
 import net.onrc.onos.core.topology.Topology;
 import net.onrc.onos.core.util.Dpid;
-
 import org.restlet.representation.Representation;
 import org.restlet.resource.Get;
 import org.restlet.resource.ServerResource;
@@ -53,8 +52,8 @@
         Topology topology = topologyService.getTopology();
         topology.acquireReadLock();
         try {
-            Switch srcSwitch = topology.getSwitch(srcDpid.value());
-            Switch dstSwitch = topology.getSwitch(dstDpid.value());
+            Switch srcSwitch = topology.getSwitch(srcDpid);
+            Switch dstSwitch = topology.getSwitch(dstDpid);
             if ((srcSwitch == null) || (dstSwitch == null)) {
                 return null;
             }
@@ -65,7 +64,8 @@
             }
             List<Link> links = new LinkedList<>();
             for (LinkEvent linkEvent : path) {
-                Link link = topology.getLink(linkEvent.getSrc().getDpid(),
+                Link link = topology.getLink(
+                        linkEvent.getSrc().getDpid(),
                         linkEvent.getSrc().getNumber(),
                         linkEvent.getDst().getDpid(),
                         linkEvent.getDst().getNumber());
diff --git a/src/main/java/net/onrc/onos/core/packetservice/BroadcastPacketOutNotification.java b/src/main/java/net/onrc/onos/core/packetservice/BroadcastPacketOutNotification.java
index c1c631c..8a9c065 100644
--- a/src/main/java/net/onrc/onos/core/packetservice/BroadcastPacketOutNotification.java
+++ b/src/main/java/net/onrc/onos/core/packetservice/BroadcastPacketOutNotification.java
@@ -4,6 +4,8 @@
 
 import net.onrc.onos.core.topology.Topology;
 import net.onrc.onos.core.topology.Port;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.PortNumber;
 
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
@@ -89,8 +91,8 @@
             Port globalPort;
             topology.acquireReadLock();
             try {
-                globalPort = topology.getPort(entry.getKey(),
-                    entry.getValue().longValue());
+                globalPort = topology.getPort(new Dpid(entry.getKey()),
+                    new PortNumber(entry.getValue()));
             } finally {
                 topology.releaseReadLock();
             }
diff --git a/src/main/java/net/onrc/onos/core/packetservice/PacketModule.java b/src/main/java/net/onrc/onos/core/packetservice/PacketModule.java
index 2bed639..9a03fed 100644
--- a/src/main/java/net/onrc/onos/core/packetservice/PacketModule.java
+++ b/src/main/java/net/onrc/onos/core/packetservice/PacketModule.java
@@ -26,6 +26,8 @@
 import net.onrc.onos.core.topology.Port;
 import net.onrc.onos.core.topology.Switch;
 import net.onrc.onos.core.topology.Topology;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.PortNumber;
 import net.onrc.onos.core.util.SwitchPort;
 
 import org.openflow.protocol.OFMessage;
@@ -161,10 +163,11 @@
 
         Switch topologySwitch;
         Port inPort;
+        final Dpid dpid = new Dpid(sw.getId());
+        topology.acquireReadLock();
         try {
-            topology.acquireReadLock();
-            topologySwitch = topology.getSwitch(sw.getId());
-            inPort = topology.getPort(sw.getId(), (long) pi.getInPort());
+            topologySwitch = topology.getSwitch(dpid);
+            inPort = topology.getPort(dpid, new PortNumber(pi.getInPort()));
         } finally {
             topology.releaseReadLock();
         }
diff --git a/src/main/java/net/onrc/onos/core/topology/LinkEvent.java b/src/main/java/net/onrc/onos/core/topology/LinkEvent.java
index 9b6630f..c54140d 100644
--- a/src/main/java/net/onrc/onos/core/topology/LinkEvent.java
+++ b/src/main/java/net/onrc/onos/core/topology/LinkEvent.java
@@ -4,6 +4,9 @@
 
 import net.onrc.onos.core.topology.PortEvent.SwitchPort;
 import net.onrc.onos.core.topology.web.serializers.LinkEventSerializer;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.PortNumber;
+
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
@@ -39,6 +42,12 @@
                 link.getDstPort().getNumber());
     }
 
+    public LinkEvent(Dpid srcDpid, PortNumber srcPortNo,
+                     Dpid dstDpid, PortNumber dstPortNo) {
+        src = new SwitchPort(srcDpid, srcPortNo);
+        dst = new SwitchPort(dstDpid, dstPortNo);
+    }
+
     public SwitchPort getSrc() {
         return src;
     }
@@ -54,6 +63,12 @@
 
     public static final int LINKID_BYTES = 2 + PortEvent.PORTID_BYTES * 2;
 
+    public static ByteBuffer getLinkID(Dpid srcDpid, PortNumber srcPortNo,
+                                       Dpid dstDpid, PortNumber dstPortNo) {
+            return getLinkID(srcDpid.value(), (long) srcPortNo.value(),
+                             dstDpid.value(), (long) dstPortNo.value());
+    }
+
     public static ByteBuffer getLinkID(Long srcDpid, Long srcPortNo,
                                        Long dstDpid, Long dstPortNo) {
         return (ByteBuffer) ByteBuffer.allocate(LinkEvent.LINKID_BYTES).putChar('L')
diff --git a/src/main/java/net/onrc/onos/core/topology/LinkImpl.java b/src/main/java/net/onrc/onos/core/topology/LinkImpl.java
index 95eddab..4c7e1c5 100644
--- a/src/main/java/net/onrc/onos/core/topology/LinkImpl.java
+++ b/src/main/java/net/onrc/onos/core/topology/LinkImpl.java
@@ -34,22 +34,22 @@
 
     @Override
     public Switch getSrcSwitch() {
-        return topology.getSwitch(srcPort.dpid().value());
+        return topology.getSwitch(srcPort.dpid());
     }
 
     @Override
     public Port getSrcPort() {
-        return topology.getPort(srcPort.dpid().value(), (long) srcPort.port().value());
+        return topology.getPort(srcPort.dpid(), srcPort.port());
     }
 
     @Override
     public Switch getDstSwitch() {
-        return topology.getSwitch(dstPort.dpid().value());
+        return topology.getSwitch(dstPort.dpid());
     }
 
     @Override
     public Port getDstPort() {
-        return topology.getPort(dstPort.dpid().value(), (long) dstPort.port().value());
+        return topology.getPort(dstPort.dpid(), dstPort.port());
     }
 
     @Override
diff --git a/src/main/java/net/onrc/onos/core/topology/Port.java b/src/main/java/net/onrc/onos/core/topology/Port.java
index af503bc..a8df75f 100644
--- a/src/main/java/net/onrc/onos/core/topology/Port.java
+++ b/src/main/java/net/onrc/onos/core/topology/Port.java
@@ -1,6 +1,8 @@
 package net.onrc.onos.core.topology;
 
 import net.onrc.onos.core.topology.web.serializers.PortSerializer;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.PortNumber;
 import net.onrc.onos.core.util.SwitchPort;
 
 import org.codehaus.jackson.map.annotate.JsonSerialize;
@@ -19,14 +21,14 @@
      *
      * @return data path ID (dpid)
      */
-    public Long getDpid();
+    public Dpid getDpid();
 
     /**
      * Gets the port number of this port.
      *
      * @return port number
      */
-    public Long getNumber();
+    public PortNumber getNumber();
 
     /**
      * Gets a {@link SwitchPort} that represents this Port's dpid and port
diff --git a/src/main/java/net/onrc/onos/core/topology/PortEvent.java b/src/main/java/net/onrc/onos/core/topology/PortEvent.java
index 57c648c..5c63de7 100644
--- a/src/main/java/net/onrc/onos/core/topology/PortEvent.java
+++ b/src/main/java/net/onrc/onos/core/topology/PortEvent.java
@@ -1,6 +1,10 @@
 package net.onrc.onos.core.topology;
 
 import net.onrc.onos.core.topology.web.serializers.SwitchPortSerializer;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.PortNumber;
+
+import org.apache.commons.lang.Validate;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 import java.nio.ByteBuffer;
@@ -12,6 +16,8 @@
  * TODO: We probably want common base class/interface for Self-Contained Event Object.
  */
 public class PortEvent {
+
+    // TODO eliminate this class and use util.SwitchPort if possible
     @JsonSerialize(using = SwitchPortSerializer.class)
     public static class SwitchPort {
         public final Long dpid;
@@ -31,12 +37,16 @@
             this.number = number;
         }
 
-        public Long getDpid() {
-            return dpid;
+        public SwitchPort(Dpid dpid, PortNumber number) {
+            this(dpid.value(), (long) number.value());
         }
 
-        public Long getNumber() {
-            return number;
+        public Dpid getDpid() {
+            return new Dpid(dpid);
+        }
+
+        public PortNumber getNumber() {
+            return new PortNumber(number.shortValue());
         }
 
         @Override
@@ -100,12 +110,16 @@
         this.id = new SwitchPort(dpid, number);
     }
 
-    public Long getDpid() {
-        return id.dpid;
+    public PortEvent(Dpid dpid, PortNumber number) {
+        this.id = new SwitchPort(dpid, number);
     }
 
-    public Long getNumber() {
-        return id.number;
+    public Dpid getDpid() {
+        return id.getDpid();
+    }
+
+    public PortNumber getNumber() {
+        return id.getNumber();
     }
 
     @Override
@@ -134,6 +148,12 @@
 
     public static final int PORTID_BYTES = SwitchEvent.SWITCHID_BYTES + 2 + 8;
 
+    public static ByteBuffer getPortID(Dpid dpid, PortNumber number) {
+        Validate.notNull(dpid);
+        Validate.notNull(number);
+        return getPortID(dpid.value(), (long) number.value());
+    }
+
     public static ByteBuffer getPortID(Long dpid, Long number) {
         if (dpid == null) {
             throw new IllegalArgumentException("dpid cannot be null");
diff --git a/src/main/java/net/onrc/onos/core/topology/PortImpl.java b/src/main/java/net/onrc/onos/core/topology/PortImpl.java
index 5d46005..77bc942 100644
--- a/src/main/java/net/onrc/onos/core/topology/PortImpl.java
+++ b/src/main/java/net/onrc/onos/core/topology/PortImpl.java
@@ -6,6 +6,8 @@
 import java.util.Set;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.PortNumber;
 import net.onrc.onos.core.util.SwitchPort;
 
 /**
@@ -18,7 +20,7 @@
 
     private Switch sw;
 
-    private Long number;
+    private PortNumber number;
     private String description;
 
     private final SwitchPort switchPort;
@@ -27,22 +29,27 @@
     // accessed concurrently
     protected Set<Device> devices;
 
-    public PortImpl(Topology topology, Switch parentSwitch, Long number) {
+    public PortImpl(Topology topology, Switch parentSwitch, PortNumber number) {
         super(topology);
         this.sw = parentSwitch;
         this.number = number;
         this.devices = new HashSet<>();
 
-        switchPort = new SwitchPort(parentSwitch.getDpid(), number.shortValue());
+        switchPort = new SwitchPort(parentSwitch.getDpid(),
+                                    number);
+    }
+
+    public PortImpl(Topology topology, Switch parentSwitch, Long number) {
+        this(topology, parentSwitch, new PortNumber(number.shortValue()));
     }
 
     @Override
-    public Long getDpid() {
+    public Dpid getDpid() {
         return sw.getDpid();
     }
 
     @Override
-    public Long getNumber() {
+    public PortNumber getNumber() {
         return number;
     }
 
@@ -73,14 +80,14 @@
 
     @Override
     public Link getOutgoingLink() {
-        return topology.getOutgoingLink(switchPort.dpid().value(),
-                (long) switchPort.port().value());
+        return topology.getOutgoingLink(switchPort.dpid(),
+                                        switchPort.port());
     }
 
     @Override
     public Link getIncomingLink() {
-        return topology.getIncomingLink(switchPort.dpid().value(),
-                (long) switchPort.port().value());
+        return topology.getIncomingLink(switchPort.dpid(),
+                                        switchPort.port());
     }
 
     @Override
@@ -132,7 +139,7 @@
 
     @Override
     public String toString() {
-        return String.format("%d:%d",
+        return String.format("%s:%s",
                 getSwitch().getDpid(),
                 getNumber());
     }
diff --git a/src/main/java/net/onrc/onos/core/topology/Switch.java b/src/main/java/net/onrc/onos/core/topology/Switch.java
index 9a4bf8c..f57de38 100644
--- a/src/main/java/net/onrc/onos/core/topology/Switch.java
+++ b/src/main/java/net/onrc/onos/core/topology/Switch.java
@@ -3,6 +3,8 @@
 import java.util.Collection;
 
 import net.onrc.onos.core.topology.web.serializers.SwitchSerializer;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.PortNumber;
 
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
@@ -19,7 +21,7 @@
      *
      * @return data path ID (dpid)
      */
-    public Long getDpid();
+    public Dpid getDpid();
 
     /**
      * Gets all the ports on this switch.
@@ -35,7 +37,7 @@
      * @return {@link Port} with {@code number} on this switch, or {@code null}
      *         if this switch did not have a port for specified port number
      */
-    public Port getPort(Long number);
+    public Port getPort(PortNumber number);
 
     // Graph traversal API
 
@@ -69,7 +71,7 @@
      * @return {@link Link} to neighbor switch {@code dpid} or {@code null} if
      *         link does not exist.
      */
-    public Link getLinkToNeighbor(Long dpid);
+    public Link getLinkToNeighbor(Dpid dpid);
 
     // XXX Iterable or Collection?
     /**
diff --git a/src/main/java/net/onrc/onos/core/topology/SwitchEvent.java b/src/main/java/net/onrc/onos/core/topology/SwitchEvent.java
index 554651e..4e9418a 100644
--- a/src/main/java/net/onrc/onos/core/topology/SwitchEvent.java
+++ b/src/main/java/net/onrc/onos/core/topology/SwitchEvent.java
@@ -25,8 +25,8 @@
         this.dpid = new Dpid(dpid);
     }
 
-    public Long getDpid() {
-        return dpid.value();
+    public Dpid getDpid() {
+        return dpid;
     }
 
     @Override
diff --git a/src/main/java/net/onrc/onos/core/topology/SwitchImpl.java b/src/main/java/net/onrc/onos/core/topology/SwitchImpl.java
index 415b924..4952c6f 100644
--- a/src/main/java/net/onrc/onos/core/topology/SwitchImpl.java
+++ b/src/main/java/net/onrc/onos/core/topology/SwitchImpl.java
@@ -1,6 +1,7 @@
 package net.onrc.onos.core.topology;
 
 import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.PortNumber;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -25,7 +26,7 @@
     private Dpid dpid;
     // These needs to be ConcurrentCollecton if allowing the topology to be
     // accessed concurrently
-    private final Map<Long, Port> ports;
+    private final Map<PortNumber, Port> ports;
 
     public SwitchImpl(Topology topology, Long dpid) {
         this(topology, new Dpid(dpid));
@@ -34,12 +35,12 @@
     public SwitchImpl(Topology topology, Dpid dpid) {
         super(topology);
         this.dpid = dpid;
-        ports = new HashMap<Long, Port>();
+        ports = new HashMap<>();
     }
 
     @Override
-    public Long getDpid() {
-        return dpid.value();
+    public Dpid getDpid() {
+        return dpid;
     }
 
     @Override
@@ -48,7 +49,7 @@
     }
 
     @Override
-    public Port getPort(Long number) {
+    public Port getPort(PortNumber number) {
         return ports.get(number);
     }
 
@@ -66,7 +67,7 @@
     }
 
     @Override
-    public Link getLinkToNeighbor(Long neighborDpid) {
+    public Link getLinkToNeighbor(Dpid neighborDpid) {
         for (Link link : getOutgoingLinks()) {
             if (link.getDstSwitch().getDpid().equals(neighborDpid)) {
                 return link;
diff --git a/src/main/java/net/onrc/onos/core/topology/Topology.java b/src/main/java/net/onrc/onos/core/topology/Topology.java
index eee37cc..3bef1e2 100644
--- a/src/main/java/net/onrc/onos/core/topology/Topology.java
+++ b/src/main/java/net/onrc/onos/core/topology/Topology.java
@@ -2,6 +2,9 @@
 
 import net.floodlightcontroller.util.MACAddress;
 import net.onrc.onos.core.topology.web.serializers.TopologySerializer;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.PortNumber;
+import net.onrc.onos.core.util.SwitchPort;
 
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
@@ -12,51 +15,75 @@
  */
 @JsonSerialize(using = TopologySerializer.class)
 public interface Topology {
+
     /**
-     * Get the switch for a given switch DPID.
+     * Gets the switch for a given switch DPID.
      *
      * @param dpid the switch dpid.
      * @return the switch if found, otherwise null.
      */
-    public Switch getSwitch(Long dpid);
+    public Switch getSwitch(Dpid dpid);
 
     /**
-     * Get all switches in the network.
+     * Gets all switches in the network.
      *
      * @return all switches in the network.
      */
     public Iterable<Switch> getSwitches();
 
     /**
-     * Get the port on a switch.
+     * Gets the port on a switch.
      *
      * @param dpid   the switch DPID.
      * @param number the switch port number.
      * @return the switch port if found, otherwise null.
      */
-    public Port getPort(Long dpid, Long number);
+    public Port getPort(Dpid dpid, PortNumber number);
 
     /**
-     * Get the outgoing link from a switch port.
+     * Gets the port on a switch.
+     *
+     * @param port port identifier
+     * @return the switch port if found, otherwise null.
+     */
+    public Port getPort(SwitchPort port);
+
+    /**
+     * Gets the outgoing link from a switch port.
      *
      * @param dpid   the switch DPID.
      * @param number the switch port number.
      * @return the outgoing link if found, otherwise null.
      */
-    public Link getOutgoingLink(Long dpid, Long number);
-    // TODO See if we should change <dpid, port_num> pairs to SwitchPort
+    public Link getOutgoingLink(Dpid dpid, PortNumber number);
 
     /**
-     * Get the incoming link to a switch port.
+     * Gets the outgoing link from a switch port.
+     *
+     * @param port port identifier
+     * @return the switch port if found, otherwise null.
+     */
+    public Link getOutgoingLink(SwitchPort port);
+
+    /**
+     * Gets the incoming link to a switch port.
      *
      * @param dpid   the switch DPID.
      * @param number the switch port number.
      * @return the incoming link if found, otherwise null.
      */
-    public Link getIncomingLink(Long dpid, Long number);
+    public Link getIncomingLink(Dpid dpid, PortNumber number);
 
     /**
-     * Get the outgoing link from a switch and a port to another switch and
+     * Gets the incoming link to a switch port.
+     *
+     * @param port port identifier
+     * @return the switch port if found, otherwise null.
+     */
+    public Link getIncomingLink(SwitchPort port);
+
+    /**
+     * Gets the outgoing link from a switch and a port to another switch and
      * a port.
      *
      * @param srcDpid   the source switch DPID.
@@ -65,11 +92,11 @@
      * @param dstNumber the destination switch port number.
      * @return the outgoing link if found, otherwise null.
      */
-    public Link getLink(Long srcDpid, Long srcNumber, Long dstDpid,
-                        Long dstNumber);
+    public Link getLink(Dpid srcDpid, PortNumber srcNumber,
+                        Dpid dstDpid, PortNumber dstNumber);
 
     /**
-     * Get all links in the network.
+     * Gets all links in the network.
      * <p/>
      * TODO: Not clear if this method is needed. Remove if not used.
      *
@@ -78,7 +105,7 @@
     public Iterable<Link> getLinks();
 
     /**
-     * Get the network device for a given MAC address.
+     * Gets the network device for a given MAC address.
      *
      * @param address the MAC address to use.
      * @return the network device for the MAC address if found, otherwise null.
diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java b/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java
index d48e222..2bba015 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java
@@ -8,6 +8,8 @@
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.PortNumber;
 import net.onrc.onos.core.util.SwitchPort;
 
 import org.slf4j.Logger;
@@ -18,7 +20,7 @@
     private static final Logger log = LoggerFactory.getLogger(TopologyImpl.class);
 
     // DPID -> Switch
-    private final ConcurrentMap<Long, Switch> switches;
+    private final ConcurrentMap<Dpid, Switch> switches;
     private final ConcurrentMap<MACAddress, Device> mac2Device;
 
     private final ConcurrentMap<SwitchPort, Link> outgoingLinks;
@@ -38,7 +40,7 @@
     }
 
     @Override
-    public Switch getSwitch(Long dpid) {
+    public Switch getSwitch(Dpid dpid) {
         // TODO Check if it is safe to directly return this Object.
         return switches.get(dpid);
     }
@@ -48,6 +50,10 @@
     }
 
     protected void removeSwitch(Long dpid) {
+        switches.remove(new Dpid(dpid));
+    }
+
+    protected void removeSwitch(Dpid dpid) {
         switches.remove(dpid);
     }
 
@@ -58,7 +64,7 @@
     }
 
     @Override
-    public Port getPort(Long dpid, Long number) {
+    public Port getPort(Dpid dpid, PortNumber number) {
         Switch sw = getSwitch(dpid);
         if (sw != null) {
             return sw.getPort(number);
@@ -67,18 +73,34 @@
     }
 
     @Override
-    public Link getOutgoingLink(Long dpid, Long number) {
-        return outgoingLinks.get(new SwitchPort(dpid, number.shortValue()));
+    public Port getPort(SwitchPort port) {
+        return getPort(port.dpid(), port.port());
     }
 
     @Override
-    public Link getIncomingLink(Long dpid, Long number) {
-        return incomingLinks.get(new SwitchPort(dpid, number.shortValue()));
+    public Link getOutgoingLink(Dpid dpid, PortNumber number) {
+        return outgoingLinks.get(new SwitchPort(dpid, number));
     }
 
     @Override
-    public Link getLink(Long srcDpid, Long srcNumber, Long dstDpid,
-                        Long dstNumber) {
+    public Link getOutgoingLink(SwitchPort port) {
+        return outgoingLinks.get(port);
+    }
+
+    @Override
+    public Link getIncomingLink(Dpid dpid, PortNumber number) {
+        return incomingLinks.get(new SwitchPort(dpid, number));
+    }
+
+    @Override
+    public Link getIncomingLink(SwitchPort port) {
+        return incomingLinks.get(port);
+    }
+
+    @Override
+    public Link getLink(Dpid srcDpid, PortNumber srcNumber,
+                        Dpid dstDpid, PortNumber dstNumber) {
+
         Link link = getOutgoingLink(srcDpid, srcNumber);
         if (link == null) {
             return null;
diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyManager.java b/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
index a24cfd0..b800d84 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
@@ -25,8 +25,8 @@
 import net.onrc.onos.core.datastore.topology.KVSwitch;
 import net.onrc.onos.core.registry.IControllerRegistryService;
 import net.onrc.onos.core.topology.PortEvent.SwitchPort;
+import net.onrc.onos.core.util.Dpid;
 import net.onrc.onos.core.util.EventEntry;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -100,11 +100,11 @@
     // FIXME Replace with concurrent variant.
     //   #removeSwitchDiscoveryEvent(SwitchEvent) runs in different thread.
     //
-    private Map<Long, Map<ByteBuffer, PortEvent>> discoveredAddedPortEvents =
+    private Map<Dpid, Map<ByteBuffer, PortEvent>> discoveredAddedPortEvents =
             new HashMap<>();
-    private Map<Long, Map<ByteBuffer, LinkEvent>> discoveredAddedLinkEvents =
+    private Map<Dpid, Map<ByteBuffer, LinkEvent>> discoveredAddedLinkEvents =
             new HashMap<>();
-    private Map<Long, Map<ByteBuffer, DeviceEvent>> discoveredAddedDeviceEvents =
+    private Map<Dpid, Map<ByteBuffer, DeviceEvent>> discoveredAddedDeviceEvents =
             new HashMap<>();
 
     //
@@ -978,10 +978,10 @@
      */
     @GuardedBy("topology.writeLock")
     private void addLink(LinkEvent linkEvent) {
-        Port srcPort = topology.getPort(linkEvent.getSrc().dpid,
-                linkEvent.getSrc().number);
-        Port dstPort = topology.getPort(linkEvent.getDst().dpid,
-                linkEvent.getDst().number);
+        Port srcPort = topology.getPort(linkEvent.getSrc().getDpid(),
+                linkEvent.getSrc().getNumber());
+        Port dstPort = topology.getPort(linkEvent.getDst().getDpid(),
+                linkEvent.getDst().getNumber());
         if ((srcPort == null) || (dstPort == null)) {
             log.debug("{} reordered because {} port is null", linkEvent,
                     (srcPort == null) ? "src" : "dst");
@@ -1035,16 +1035,16 @@
      */
     @GuardedBy("topology.writeLock")
     private void removeLink(LinkEvent linkEvent) {
-        Port srcPort = topology.getPort(linkEvent.getSrc().dpid,
-                linkEvent.getSrc().number);
+        Port srcPort = topology.getPort(linkEvent.getSrc().getDpid(),
+                linkEvent.getSrc().getNumber());
         if (srcPort == null) {
             log.warn("Src Port for Link {} already removed, ignoring",
                     linkEvent);
             return;
         }
 
-        Port dstPort = topology.getPort(linkEvent.getDst().dpid,
-                linkEvent.getDst().number);
+        Port dstPort = topology.getPort(linkEvent.getDst().getDpid(),
+                linkEvent.getDst().getNumber());
         if (dstPort == null) {
             log.warn("Dst Port for Link {} already removed, ignoring",
                     linkEvent);
@@ -1097,7 +1097,7 @@
         boolean attachmentFound = false;
         for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
             // Attached Ports must exist
-            Port port = topology.getPort(swp.dpid, swp.number);
+            Port port = topology.getPort(swp.getDpid(), swp.getNumber());
             if (port == null) {
                 // Reordered event: delay the event in local cache
                 ByteBuffer id = deviceEvent.getIDasByteBuffer();
@@ -1150,7 +1150,7 @@
         // Process each attachment point
         for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
             // Attached Ports must exist
-            Port port = topology.getPort(swp.dpid, swp.number);
+            Port port = topology.getPort(swp.getDpid(), swp.getNumber());
             if (port == null) {
                 log.warn("Port for the attachment point {} did not exist. skipping attachment point mutation", swp);
                 continue;
diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyPublisher.java b/src/main/java/net/onrc/onos/core/topology/TopologyPublisher.java
index eb76c1e..1c251c5 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyPublisher.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyPublisher.java
@@ -96,11 +96,11 @@
             for (Switch sw : switches) {
                 try {
                     String controller =
-                            registryService.getControllerForSwitch(sw.getDpid());
+                            registryService.getControllerForSwitch(sw.getDpid().value());
                     if (controller == null) {
                         log.debug("Requesting control to set switch {} INACTIVE",
-                                HexString.toHexString(sw.getDpid()));
-                        registryService.requestControl(sw.getDpid(), this);
+                                sw.getDpid());
+                        registryService.requestControl(sw.getDpid().value(), this);
                     }
                 } catch (RegistryException e) {
                     log.error("Caught RegistryException in cleanup thread", e);
diff --git a/src/main/java/net/onrc/onos/core/topology/web/serializers/DeviceSerializer.java b/src/main/java/net/onrc/onos/core/topology/web/serializers/DeviceSerializer.java
index 61a8fd9..5319adf 100644
--- a/src/main/java/net/onrc/onos/core/topology/web/serializers/DeviceSerializer.java
+++ b/src/main/java/net/onrc/onos/core/topology/web/serializers/DeviceSerializer.java
@@ -8,7 +8,6 @@
 import org.codehaus.jackson.JsonGenerator;
 import org.codehaus.jackson.map.SerializerProvider;
 import org.codehaus.jackson.map.ser.std.SerializerBase;
-import org.openflow.util.HexString;
 
 public class DeviceSerializer extends SerializerBase<Device> {
 
@@ -25,8 +24,9 @@
         jsonGenerator.writeStartArray();
         for (Port port : dev.getAttachmentPoints()) {
             jsonGenerator.writeStartObject();
-            jsonGenerator.writeStringField("dpid", HexString.toHexString(port.getDpid()));
-            jsonGenerator.writeNumberField("port", port.getNumber());
+            jsonGenerator.writeStringField("dpid", port.getDpid().toString());
+            // XXX Should port number be treated as unsigned?
+            jsonGenerator.writeNumberField("port", port.getNumber().value());
             jsonGenerator.writeEndObject();
         }
         jsonGenerator.writeEndArray();
diff --git a/src/main/java/net/onrc/onos/core/topology/web/serializers/LinkSerializer.java b/src/main/java/net/onrc/onos/core/topology/web/serializers/LinkSerializer.java
index b34a011..1cecca5 100644
--- a/src/main/java/net/onrc/onos/core/topology/web/serializers/LinkSerializer.java
+++ b/src/main/java/net/onrc/onos/core/topology/web/serializers/LinkSerializer.java
@@ -7,7 +7,6 @@
 import org.codehaus.jackson.JsonGenerator;
 import org.codehaus.jackson.map.SerializerProvider;
 import org.codehaus.jackson.map.ser.std.SerializerBase;
-import org.openflow.util.HexString;
 
 public class LinkSerializer extends SerializerBase<Link> {
 
@@ -21,13 +20,14 @@
             throws IOException {
         jsonGenerator.writeStartObject();
         jsonGenerator.writeStringField("src-switch",
-                HexString.toHexString(link.getSrcSwitch().getDpid()));
+                link.getSrcSwitch().getDpid().toString());
+        // XXX port number as unsigned?
         jsonGenerator.writeNumberField("src-port",
-                link.getSrcPort().getNumber());
+                link.getSrcPort().getNumber().value());
         jsonGenerator.writeStringField("dst-switch",
-                HexString.toHexString(link.getDstSwitch().getDpid()));
+                link.getDstSwitch().getDpid().toString());
         jsonGenerator.writeNumberField("dst-port",
-                link.getDstPort().getNumber());
+                link.getDstPort().getNumber().value());
         jsonGenerator.writeEndObject();
     }
 
diff --git a/src/main/java/net/onrc/onos/core/topology/web/serializers/PortSerializer.java b/src/main/java/net/onrc/onos/core/topology/web/serializers/PortSerializer.java
index 156d2c0..52fbe44 100644
--- a/src/main/java/net/onrc/onos/core/topology/web/serializers/PortSerializer.java
+++ b/src/main/java/net/onrc/onos/core/topology/web/serializers/PortSerializer.java
@@ -7,7 +7,6 @@
 import org.codehaus.jackson.JsonGenerator;
 import org.codehaus.jackson.map.SerializerProvider;
 import org.codehaus.jackson.map.ser.std.SerializerBase;
-import org.openflow.util.HexString;
 
 public class PortSerializer extends SerializerBase<Port> {
 
@@ -21,8 +20,8 @@
             throws IOException {
         jsonGenerator.writeStartObject();
         jsonGenerator.writeStringField("state", "ACTIVE");
-        jsonGenerator.writeStringField("dpid", HexString.toHexString(port.getDpid()));
-        jsonGenerator.writeNumberField("number", port.getNumber());
+        jsonGenerator.writeStringField("dpid", port.getDpid().toString());
+        jsonGenerator.writeNumberField("number", port.getNumber().value());
         jsonGenerator.writeStringField("desc", port.getDescription());
         jsonGenerator.writeEndObject();
     }
diff --git a/src/main/java/net/onrc/onos/core/topology/web/serializers/SwitchPortSerializer.java b/src/main/java/net/onrc/onos/core/topology/web/serializers/SwitchPortSerializer.java
index c9820a5..13c5d56 100644
--- a/src/main/java/net/onrc/onos/core/topology/web/serializers/SwitchPortSerializer.java
+++ b/src/main/java/net/onrc/onos/core/topology/web/serializers/SwitchPortSerializer.java
@@ -4,8 +4,6 @@
 import org.codehaus.jackson.JsonGenerator;
 import org.codehaus.jackson.map.SerializerProvider;
 import org.codehaus.jackson.map.ser.std.SerializerBase;
-import org.openflow.util.HexString;
-
 import java.io.IOException;
 
 /**
@@ -36,9 +34,9 @@
         jsonGenerator.writeStartObject();
 
         jsonGenerator.writeStringField("dpid",
-                                       HexString.toHexString(switchPort.getDpid()));
+                                       switchPort.getDpid().toString());
         jsonGenerator.writeStringField("portNumber",
-                                       Long.toString(switchPort.getNumber()));
+                                       switchPort.getNumber().toString());
 
         jsonGenerator.writeEndObject();
     }
diff --git a/src/main/java/net/onrc/onos/core/topology/web/serializers/SwitchSerializer.java b/src/main/java/net/onrc/onos/core/topology/web/serializers/SwitchSerializer.java
index 89ee7ae..01bd22f 100644
--- a/src/main/java/net/onrc/onos/core/topology/web/serializers/SwitchSerializer.java
+++ b/src/main/java/net/onrc/onos/core/topology/web/serializers/SwitchSerializer.java
@@ -8,7 +8,6 @@
 import org.codehaus.jackson.JsonGenerator;
 import org.codehaus.jackson.map.SerializerProvider;
 import org.codehaus.jackson.map.ser.std.SerializerBase;
-import org.openflow.util.HexString;
 
 public class SwitchSerializer extends SerializerBase<Switch> {
 
@@ -21,7 +20,7 @@
                           SerializerProvider serializerProvider) throws IOException {
 
         jsonGenerator.writeStartObject();
-        jsonGenerator.writeStringField("dpid", HexString.toHexString(sw.getDpid()));
+        jsonGenerator.writeStringField("dpid", sw.getDpid().toString());
         jsonGenerator.writeStringField("state", "ACTIVE");
         jsonGenerator.writeArrayFieldStart("ports");
         for (Port port : sw.getPorts()) {