Added javadocs and separated trivial implementations into distinct packages.
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManager.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/device/impl/SimpleDeviceManager.java
similarity index 99%
rename from core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManager.java
rename to core/trivial/src/main/java/org/onlab/onos/net/trivial/device/impl/SimpleDeviceManager.java
index 135edd9..221a249 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManager.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/device/impl/SimpleDeviceManager.java
@@ -1,4 +1,4 @@
-package org.onlab.onos.net.trivial.impl;
+package org.onlab.onos.net.trivial.device.impl;
 
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceStore.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/device/impl/SimpleDeviceStore.java
similarity index 99%
rename from core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceStore.java
rename to core/trivial/src/main/java/org/onlab/onos/net/trivial/device/impl/SimpleDeviceStore.java
index 1c1502e..6317b14 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceStore.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/device/impl/SimpleDeviceStore.java
@@ -1,4 +1,4 @@
-package org.onlab.onos.net.trivial.impl;
+package org.onlab.onos.net.trivial.device.impl;
 
 import com.google.common.collect.ImmutableList;
 import org.onlab.onos.net.DefaultDevice;
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkManager.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/link/impl/SimpleLinkManager.java
similarity index 99%
rename from core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkManager.java
rename to core/trivial/src/main/java/org/onlab/onos/net/trivial/link/impl/SimpleLinkManager.java
index 1930ea1..a817bb6 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkManager.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/link/impl/SimpleLinkManager.java
@@ -1,4 +1,4 @@
-package org.onlab.onos.net.trivial.impl;
+package org.onlab.onos.net.trivial.link.impl;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.slf4j.LoggerFactory.getLogger;
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkStore.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/link/impl/SimpleLinkStore.java
similarity index 99%
rename from core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkStore.java
rename to core/trivial/src/main/java/org/onlab/onos/net/trivial/link/impl/SimpleLinkStore.java
index 9de3d5b..2ba7a30 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkStore.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/link/impl/SimpleLinkStore.java
@@ -1,4 +1,4 @@
-package org.onlab.onos.net.trivial.impl;
+package org.onlab.onos.net.trivial.link.impl;
 
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.ImmutableSet;
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/DefaultTopology.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/topology/impl/DefaultTopology.java
similarity index 96%
rename from core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/DefaultTopology.java
rename to core/trivial/src/main/java/org/onlab/onos/net/trivial/topology/impl/DefaultTopology.java
index cb55819..c20acd8 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/DefaultTopology.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/topology/impl/DefaultTopology.java
@@ -1,4 +1,4 @@
-package org.onlab.onos.net.trivial.impl;
+package org.onlab.onos.net.trivial.topology.impl;
 
 import org.onlab.onos.net.AbstractModel;
 import org.onlab.onos.net.provider.ProviderId;
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleTopologyManager.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/topology/impl/SimpleTopologyManager.java
similarity index 98%
rename from core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleTopologyManager.java
rename to core/trivial/src/main/java/org/onlab/onos/net/trivial/topology/impl/SimpleTopologyManager.java
index 33b2a18..70f001c 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleTopologyManager.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/topology/impl/SimpleTopologyManager.java
@@ -1,4 +1,4 @@
-package org.onlab.onos.net.trivial.impl;
+package org.onlab.onos.net.trivial.topology.impl;
 
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleTopologyStore.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/topology/impl/SimpleTopologyStore.java
similarity index 98%
rename from core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleTopologyStore.java
rename to core/trivial/src/main/java/org/onlab/onos/net/trivial/topology/impl/SimpleTopologyStore.java
index 7944a53..1b9766d 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleTopologyStore.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/topology/impl/SimpleTopologyStore.java
@@ -1,4 +1,4 @@
-package org.onlab.onos.net.trivial.impl;
+package org.onlab.onos.net.trivial.topology.impl;
 
 import org.onlab.graph.Graph;
 import org.onlab.onos.event.Event;
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/DefaultTopologyDescription.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/topology/provider/impl/DefaultTopologyDescription.java
similarity index 68%
rename from core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/DefaultTopologyDescription.java
rename to core/trivial/src/main/java/org/onlab/onos/net/trivial/topology/provider/impl/DefaultTopologyDescription.java
index c438146..87d2c47 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/DefaultTopologyDescription.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/topology/provider/impl/DefaultTopologyDescription.java
@@ -1,29 +1,35 @@
-package org.onlab.onos.net.trivial.impl;
+package org.onlab.onos.net.trivial.topology.provider.impl;
 
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
 import com.google.common.collect.Sets;
 import org.onlab.graph.AdjacencyListsGraph;
 import org.onlab.graph.DijkstraGraphSearch;
 import org.onlab.graph.Graph;
 import org.onlab.graph.GraphPathSearch;
+import org.onlab.graph.TarjanGraphSearch;
 import org.onlab.onos.net.ConnectPoint;
 import org.onlab.onos.net.Device;
 import org.onlab.onos.net.DeviceId;
 import org.onlab.onos.net.Link;
 import org.onlab.onos.net.topology.ClusterId;
+import org.onlab.onos.net.topology.DefaultTopologyCluster;
 import org.onlab.onos.net.topology.LinkWeight;
 import org.onlab.onos.net.topology.TopoEdge;
 import org.onlab.onos.net.topology.TopoVertex;
 import org.onlab.onos.net.topology.TopologyCluster;
 import org.onlab.onos.net.topology.TopologyDescription;
 
+import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 
 import static com.google.common.base.MoreObjects.toStringHelper;
 import static org.onlab.graph.GraphPathSearch.Result;
+import static org.onlab.graph.TarjanGraphSearch.SCCResult;
 import static org.onlab.onos.net.Link.Type.INDIRECT;
 
 /**
@@ -33,25 +39,32 @@
 
     private static final GraphPathSearch<TopoVertex, TopoEdge> DIJKSTRA =
             new DijkstraGraphSearch<>();
+    private static final TarjanGraphSearch<TopoVertex, TopoEdge> TARJAN =
+            new TarjanGraphSearch<>();
 
     private final long nanos;
     private final Map<DeviceId, TopoVertex> vertexesById = Maps.newHashMap();
     private final Graph<TopoVertex, TopoEdge> graph;
     private final Map<DeviceId, Result<TopoVertex, TopoEdge>> results;
     private final Map<ClusterId, TopologyCluster> clusters;
-//    private final Multimap<ClusterId, DeviceId> clusterDevices;
-//    private final Multimap<ClusterId, Link> clusterLinks;
-//    private final Map<DeviceId, TopologyCluster> deviceClusters;
 
+    // Secondary look-up indexes
+    private Multimap<ClusterId, DeviceId> devicesByCluster;
+    private Multimap<ClusterId, Link> linksByCluster;
+    private Map<DeviceId, TopologyCluster> clustersByDevice;
 
+    /**
+     * Creates a topology description to carry topology vitals to the core.
+     *
+     * @param nanos   time in nanos of when the topology description was created
+     * @param devices collection of devices
+     * @param links
+     */
     DefaultTopologyDescription(long nanos, Iterable<Device> devices, Iterable<Link> links) {
         this.nanos = nanos;
         this.graph = buildGraph(devices, links);
         this.results = computeDefaultPaths();
         this.clusters = computeClusters();
-//        this.clusterDevices = clusterDevices;
-//        this.clusterLinks = clusterLinks;
-//        this.deviceClusters = deviceClusters;
     }
 
     // Constructs the topology graph using the supplied devices and links.
@@ -99,9 +112,62 @@
     // Computes topology SCC clusters using Tarjan algorithm.
     private Map<ClusterId, TopologyCluster> computeClusters() {
         Map<ClusterId, TopologyCluster> clusters = Maps.newHashMap();
+        SCCResult<TopoVertex, TopoEdge> result = TARJAN.search(graph, new NoIndirectLinksWeight());
+
+        // Extract both vertexes and edges from the results; the lists form
+        // pairs along the same index.
+        List<Set<TopoVertex>> clusterVertexes = result.clusterVertexes();
+        List<Set<TopoEdge>> clusterEdges = result.clusterEdges();
+
+        // Scan over the lists and create a cluster from the results.
+        for (int i = 0, n = result.clusterCount(); i < n; i++) {
+            Set<TopoVertex> vertexSet = clusterVertexes.get(i);
+            Set<TopoEdge> edgeSet = clusterEdges.get(i);
+
+            DefaultTopologyCluster cluster =
+                    new DefaultTopologyCluster(ClusterId.clusterId(i),
+                                               vertexSet.size(), edgeSet.size(),
+                                               findRoot(vertexSet).deviceId());
+
+            findClusterDevices(vertexSet, cluster);
+            findClusterLinks(edgeSet, cluster);
+        }
         return clusters;
     }
 
+    // Scan through the set of cluster vertices and convert it to a set of
+    // device ids; register the cluster by device id as well.
+    private void findClusterDevices(Set<TopoVertex> vertexSet,
+                                    DefaultTopologyCluster cluster) {
+        Set<DeviceId> ids = new HashSet<>(vertexSet.size());
+        for (TopoVertex v : vertexSet) {
+            DeviceId deviceId = v.deviceId();
+            devicesByCluster.put(cluster.id(), deviceId);
+            clustersByDevice.put(deviceId, cluster);
+        }
+    }
+
+    private void findClusterLinks(Set<TopoEdge> edgeSet,
+                                  DefaultTopologyCluster cluster) {
+        for (TopoEdge e : edgeSet) {
+            linksByCluster.put(cluster.id(), e.link());
+        }
+    }
+
+    // Finds the vertex whose device id is the lexicographical minimum in the
+    // specified set.
+    private TopoVertex findRoot(Set<TopoVertex> vertexSet) {
+        TopoVertex minVertex = null;
+        for (TopoVertex vertex : vertexSet) {
+            if (minVertex == null ||
+                    minVertex.deviceId().toString()
+                            .compareTo(minVertex.deviceId().toString()) < 0) {
+                minVertex = vertex;
+            }
+        }
+        return minVertex;
+    }
+
     // Fetches a vertex corresponding to the given connection point device.
     private TopoVertex vertexOf(ConnectPoint connectPoint) {
         DeviceId id = connectPoint.deviceId();
@@ -232,7 +298,7 @@
 
     // Link weight for measuring link cost as hop count with indirect links
     // being as expensive as traversing the entire graph to assume the worst.
-    private class HopCountLinkWeight implements LinkWeight {
+    private static class HopCountLinkWeight implements LinkWeight {
         private final int indirectLinkCost;
 
         public HopCountLinkWeight(int indirectLinkCost) {
@@ -247,4 +313,12 @@
         }
     }
 
+    // Link weight for preventing traversal over indirect links.
+    private static class NoIndirectLinksWeight implements LinkWeight {
+        @Override
+        public double weight(TopoEdge edge) {
+            return edge.link().type() == INDIRECT ? -1 : 1;
+        }
+    }
+
 }
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleTopologyProvider.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/topology/provider/impl/SimpleTopologyProvider.java
similarity index 98%
rename from core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleTopologyProvider.java
rename to core/trivial/src/main/java/org/onlab/onos/net/trivial/topology/provider/impl/SimpleTopologyProvider.java
index 0e9ea3d..7594c93 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleTopologyProvider.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/topology/provider/impl/SimpleTopologyProvider.java
@@ -1,4 +1,4 @@
-package org.onlab.onos.net.trivial.impl;
+package org.onlab.onos.net.trivial.topology.provider.impl;
 
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
diff --git a/core/trivial/src/main/javadoc/org/onlab/onos/event/impl/package.html b/core/trivial/src/main/javadoc/org/onlab/onos/event/impl/package.html
index a22d62d..87f0d91 100644
--- a/core/trivial/src/main/javadoc/org/onlab/onos/event/impl/package.html
+++ b/core/trivial/src/main/javadoc/org/onlab/onos/event/impl/package.html
@@ -1,3 +1,3 @@
 <body>
-ONOS local event dispatching mechanism.
+Local event dispatching mechanism.
 </body>
\ No newline at end of file
diff --git a/core/trivial/src/main/javadoc/org/onlab/onos/impl/package.html b/core/trivial/src/main/javadoc/org/onlab/onos/impl/package.html
index 087085c..84500a8 100644
--- a/core/trivial/src/main/javadoc/org/onlab/onos/impl/package.html
+++ b/core/trivial/src/main/javadoc/org/onlab/onos/impl/package.html
@@ -1,3 +1,3 @@
 <body>
-ONOS Core infrastructure implementations.
+Core infrastructure implementations.
 </body>
\ No newline at end of file
diff --git a/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/device/impl/package.html b/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/device/impl/package.html
new file mode 100644
index 0000000..2195da2
--- /dev/null
+++ b/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/device/impl/package.html
@@ -0,0 +1,3 @@
+<body>
+Core subsystem for tracking infrastructure devices.
+</body>
\ No newline at end of file
diff --git a/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/host/impl/package.html b/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/host/impl/package.html
new file mode 100644
index 0000000..79f7bb0
--- /dev/null
+++ b/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/host/impl/package.html
@@ -0,0 +1,3 @@
+<body>
+Core subsystem for tracking edn-station hosts.
+</body>
\ No newline at end of file
diff --git a/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/impl/package.html b/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/impl/package.html
deleted file mode 100644
index ba285bd..0000000
--- a/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/impl/package.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<body>
-ONOS core implementations.
-</body>
\ No newline at end of file
diff --git a/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/link/impl/package.html b/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/link/impl/package.html
new file mode 100644
index 0000000..5bba317
--- /dev/null
+++ b/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/link/impl/package.html
@@ -0,0 +1,3 @@
+<body>
+Core subsystem for tracking infrastructure links.
+</body>
\ No newline at end of file
diff --git a/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/topology/impl/package.html b/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/topology/impl/package.html
new file mode 100644
index 0000000..b4cca07
--- /dev/null
+++ b/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/topology/impl/package.html
@@ -0,0 +1,3 @@
+<body>
+Core subsystem for tracking consistent topology graph views.
+</body>
\ No newline at end of file
diff --git a/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/topology/provider/impl/package.html b/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/topology/provider/impl/package.html
new file mode 100644
index 0000000..ee67aa8
--- /dev/null
+++ b/core/trivial/src/main/javadoc/org/onlab/onos/net/trivial/topology/provider/impl/package.html
@@ -0,0 +1,3 @@
+<body>
+Built-in protocol-agnostic topology builder &amp; provider.
+</body>
\ No newline at end of file
diff --git a/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/TestEventDispatcher.java b/core/trivial/src/test/java/org/onlab/onos/event/impl/TestEventDispatcher.java
similarity index 94%
rename from core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/TestEventDispatcher.java
rename to core/trivial/src/test/java/org/onlab/onos/event/impl/TestEventDispatcher.java
index 82f8be5..9eb3980 100644
--- a/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/TestEventDispatcher.java
+++ b/core/trivial/src/test/java/org/onlab/onos/event/impl/TestEventDispatcher.java
@@ -1,4 +1,4 @@
-package org.onlab.onos.net.trivial.impl;
+package org.onlab.onos.event.impl;
 
 import org.onlab.onos.event.DefaultEventSinkRegistry;
 import org.onlab.onos.event.Event;
diff --git a/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManagerTest.java b/core/trivial/src/test/java/org/onlab/onos/net/trivial/device/impl/SimpleDeviceManagerTest.java
similarity index 98%
rename from core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManagerTest.java
rename to core/trivial/src/test/java/org/onlab/onos/net/trivial/device/impl/SimpleDeviceManagerTest.java
index bcece2d..4c1aff4 100644
--- a/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManagerTest.java
+++ b/core/trivial/src/test/java/org/onlab/onos/net/trivial/device/impl/SimpleDeviceManagerTest.java
@@ -1,4 +1,4 @@
-package org.onlab.onos.net.trivial.impl;
+package org.onlab.onos.net.trivial.device.impl;
 
 import org.junit.After;
 import org.junit.Before;
@@ -22,6 +22,7 @@
 import org.onlab.onos.net.device.PortDescription;
 import org.onlab.onos.net.provider.AbstractProvider;
 import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.onos.event.impl.TestEventDispatcher;
 
 import java.util.ArrayList;
 import java.util.Iterator;
diff --git a/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleLinkManagerTest.java b/core/trivial/src/test/java/org/onlab/onos/net/trivial/link/impl/SimpleLinkManagerTest.java
similarity index 98%
rename from core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleLinkManagerTest.java
rename to core/trivial/src/test/java/org/onlab/onos/net/trivial/link/impl/SimpleLinkManagerTest.java
index 8dd9e1d..6eace8f 100644
--- a/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleLinkManagerTest.java
+++ b/core/trivial/src/test/java/org/onlab/onos/net/trivial/link/impl/SimpleLinkManagerTest.java
@@ -1,4 +1,4 @@
-package org.onlab.onos.net.trivial.impl;
+package org.onlab.onos.net.trivial.link.impl;
 
 import com.google.common.collect.ImmutableSet;
 import org.junit.After;
@@ -21,6 +21,7 @@
 import org.onlab.onos.net.link.LinkService;
 import org.onlab.onos.net.provider.AbstractProvider;
 import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.onos.event.impl.TestEventDispatcher;
 
 import java.util.ArrayList;
 import java.util.Iterator;
diff --git a/pom.xml b/pom.xml
index 3ec7f1c..1002901 100644
--- a/pom.xml
+++ b/pom.xml
@@ -332,7 +332,7 @@
                         <group>
                             <title>Core Subsystems</title>
                             <packages>
-                                org.onlab.onos.net.trivial.impl:org.onlab.onos.net.*.impl:org.onlab.onos.impl:org.onlab.onos.event.impl
+                                org.onlab.onos.net.trivial.*:org.onlab.onos.net.*.impl:org.onlab.onos.impl:org.onlab.onos.event.impl
                             </packages>
                         </group>
                         <group>
diff --git a/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/LinkDiscovery.java b/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/LinkDiscovery.java
index 2e8fa55..407ded1 100644
--- a/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/LinkDiscovery.java
+++ b/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/LinkDiscovery.java
@@ -42,7 +42,7 @@
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.ONLabLddp;
 import org.onlab.packet.ONLabLddp.DPIDandPort;
-import org.onlab.timer.Timer;
+import org.onlab.util.Timer;
 import org.projectfloodlight.openflow.protocol.OFFactory;
 import org.projectfloodlight.openflow.protocol.OFMessage;
 import org.projectfloodlight.openflow.protocol.OFPacketOut;
diff --git a/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/OpenFlowLinkProvider.java b/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/OpenFlowLinkProvider.java
index 99ae8ce..a2bf045 100644
--- a/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/OpenFlowLinkProvider.java
+++ b/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/OpenFlowLinkProvider.java
@@ -23,7 +23,7 @@
 import org.onlab.onos.of.controller.OpenFlowSwitchListener;
 import org.onlab.onos.of.controller.PacketContext;
 import org.onlab.onos.of.controller.PacketListener;
-import org.onlab.timer.Timer;
+import org.onlab.util.Timer;
 import org.projectfloodlight.openflow.protocol.OFPortConfig;
 import org.projectfloodlight.openflow.protocol.OFPortDesc;
 import org.projectfloodlight.openflow.protocol.OFPortState;
diff --git a/utils/misc/src/main/java/org/onlab/timer/Timer.java b/utils/misc/src/main/java/org/onlab/timer/Timer.java
deleted file mode 100644
index 1f821a7..0000000
--- a/utils/misc/src/main/java/org/onlab/timer/Timer.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.onlab.timer;
-
-import org.jboss.netty.util.HashedWheelTimer;
-
-
-public final class Timer {
-
-    private Timer() {}
-
-    private static HashedWheelTimer timer;
-
-    public static HashedWheelTimer getTimer() {
-        if (Timer.timer == null) {
-            Timer.timer = new HashedWheelTimer();
-            Timer.timer.start();
-        }
-        return Timer.timer;
-    }
-
-}
diff --git a/utils/misc/src/main/java/org/onlab/util/Timer.java b/utils/misc/src/main/java/org/onlab/util/Timer.java
new file mode 100644
index 0000000..276138f
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/util/Timer.java
@@ -0,0 +1,30 @@
+package org.onlab.util;
+
+import org.jboss.netty.util.HashedWheelTimer;
+
+/**
+ * Hashed-wheel timer singleton. Care must be taken to shutdown the timer
+ * only when the VM is ready to exit.
+ */
+public final class Timer {
+
+    private static HashedWheelTimer timer;
+
+    // Ban public construction
+    private Timer() {
+    }
+
+    /**
+     * Returns the singleton hashed-wheel timer.
+     *
+     * @return hashed-wheel timer
+     */
+    public static HashedWheelTimer getTimer() {
+        if (Timer.timer == null) {
+            Timer.timer = new HashedWheelTimer();
+            Timer.timer.start();
+        }
+        return Timer.timer;
+    }
+
+}