Cleaned-up templates and added package.html files.
diff --git a/net/api/src/main/java/org/onlab/onos/event/AbstractListenerManager.java b/net/api/src/main/java/org/onlab/onos/event/AbstractListenerManager.java
index d063b59..0ca3b8e 100644
--- a/net/api/src/main/java/org/onlab/onos/event/AbstractListenerManager.java
+++ b/net/api/src/main/java/org/onlab/onos/event/AbstractListenerManager.java
@@ -1,13 +1,13 @@
 package org.onlab.onos.event;
 
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import java.util.Set;
 import java.util.concurrent.CopyOnWriteArraySet;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Base implementation of a manager capable of tracking listeners and
@@ -16,7 +16,7 @@
 public class AbstractListenerManager<E extends Event, L extends EventListener<E>>
         implements EventSink<E> {
 
-    protected Logger log = LoggerFactory.getLogger(AbstractListenerManager.class);
+    private final Logger log = getLogger(getClass());
 
     private final Set<L> listeners = new CopyOnWriteArraySet<>();
 
diff --git a/net/api/src/main/javadoc/org/onlab/onos/package.html b/net/api/src/main/javadoc/org/onlab/onos/package.html
new file mode 100644
index 0000000..cda72f5
--- /dev/null
+++ b/net/api/src/main/javadoc/org/onlab/onos/package.html
@@ -0,0 +1,3 @@
+<body>
+ONOS Core API definitions.
+</body>
\ No newline at end of file
diff --git a/net/core/trivial/src/main/java/org/onlab/onos/event/impl/SimpleEventDispatcher.java b/net/core/trivial/src/main/java/org/onlab/onos/event/impl/SimpleEventDispatcher.java
index 67cbc73..7ef8735 100644
--- a/net/core/trivial/src/main/java/org/onlab/onos/event/impl/SimpleEventDispatcher.java
+++ b/net/core/trivial/src/main/java/org/onlab/onos/event/impl/SimpleEventDispatcher.java
@@ -1,46 +1,93 @@
 package org.onlab.onos.event.impl;
 
+import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Service;
+import org.onlab.onos.event.AbstractEvent;
+import org.onlab.onos.event.DefaultEventSinkBroker;
 import org.onlab.onos.event.Event;
 import org.onlab.onos.event.EventDispatchService;
 import org.onlab.onos.event.EventSink;
+import org.slf4j.Logger;
 
-import java.util.Set;
+import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static org.onlab.util.Tools.namedThreads;
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Simple implementation of an event dispatching service.
  */
 @Component(immediate = true)
 @Service
-public class SimpleEventDispatcher implements EventDispatchService {
+public class SimpleEventDispatcher extends DefaultEventSinkBroker
+        implements EventDispatchService {
 
-    private final ExecutorService executor = Executors.newSingleThreadExecutor();
+    private final Logger log = getLogger(getClass());
+
+    private final ExecutorService executor =
+            newSingleThreadExecutor(namedThreads("event-dispatch-%d"));
+
+    @SuppressWarnings("unchecked")
+    private static final Event KILL_PILL = new AbstractEvent(null, 0) {
+    };
+
+    private final BlockingQueue<Event> events = new LinkedBlockingQueue<>();
+
+    private volatile boolean stopped = false;
 
     @Override
     public void post(Event event) {
-
+        events.add(event);
     }
 
-    @Override
-    public <E extends Event> void addSink(Class<E> eventClass, EventSink<E> sink) {
-
+    @Activate
+    public void activate() {
+        stopped = false;
+        executor.execute(new DispatchLoop());
+        log.info("Started");
     }
 
-    @Override
-    public <E extends Event> void removeSink(Class<E> eventClass) {
-
+    @Deactivate
+    public void deactivate() {
+        stopped = true;
+        post(KILL_PILL);
+        log.info("Stopped");
     }
 
-    @Override
-    public <E extends Event> EventSink<E> getSink(Class<E> eventClass) {
-        return null;
+    // Auxiliary event dispatching loop that feeds off the events queue.
+    private class DispatchLoop implements Runnable {
+        @Override
+        @SuppressWarnings("unchecked")
+        public void run() {
+            log.info("Dispatch loop initiated");
+            while (!stopped) {
+                try {
+                    // Fetch the next event and if it is the kill-pill, bail
+                    Event event = events.take();
+                    if (event == KILL_PILL) {
+                        break;
+                    }
+
+                    // Locate the sink for the event class and use it to
+                    // process the event
+                    EventSink sink = getSink(event.getClass());
+                    if (sink != null) {
+                        sink.process(event);
+                    } else {
+                        log.warn("No sink registered for event class {}",
+                                 event.getClass());
+                    }
+                } catch (Throwable e) {
+                    log.warn("Error encountered while dispatching event:", e);
+                }
+            }
+            log.info("Dispatch loop terminated");
+        }
     }
 
-    @Override
-    public Set<Class<? extends Event>> getSinks() {
-        return null;
-    }
 }
diff --git a/net/core/trivial/src/main/java/org/onlab/onos/impl/GreetManager.java b/net/core/trivial/src/main/java/org/onlab/onos/impl/GreetManager.java
index 4f4ba68..e5baf0e 100644
--- a/net/core/trivial/src/main/java/org/onlab/onos/impl/GreetManager.java
+++ b/net/core/trivial/src/main/java/org/onlab/onos/impl/GreetManager.java
@@ -7,12 +7,12 @@
 import org.apache.felix.scr.annotations.Service;
 import org.onlab.onos.GreetService;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import java.util.HashSet;
 import java.util.Set;
 
 import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Trivial implementation of the seed service to demonstrate component and
@@ -22,7 +22,7 @@
 @Service
 public class GreetManager implements GreetService {
 
-    private final Logger log = LoggerFactory.getLogger(getClass());
+    private final Logger log = getLogger(getClass());
 
     private final Set<String> names = new HashSet<>();
 
diff --git a/net/core/trivial/src/main/java/org/onlab/onos/impl/SomeOtherComponent.java b/net/core/trivial/src/main/java/org/onlab/onos/impl/SomeOtherComponent.java
index 6cb0bfe..627573f 100644
--- a/net/core/trivial/src/main/java/org/onlab/onos/impl/SomeOtherComponent.java
+++ b/net/core/trivial/src/main/java/org/onlab/onos/impl/SomeOtherComponent.java
@@ -7,7 +7,8 @@
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.onlab.onos.GreetService;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Example of a component that does not provide any service, but consumes one.
@@ -15,7 +16,7 @@
 @Component(immediate = true)
 public class SomeOtherComponent {
 
-    private final Logger log = LoggerFactory.getLogger(SomeOtherComponent.class);
+    private final Logger log = getLogger(getClass());
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected GreetService service;
diff --git a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManager.java b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManager.java
index 7038284..a293183 100644
--- a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManager.java
+++ b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManager.java
@@ -3,6 +3,8 @@
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
 import org.onlab.onos.event.AbstractListenerManager;
 import org.onlab.onos.event.EventDispatchService;
@@ -22,11 +24,11 @@
 import org.onlab.onos.net.provider.AbstractProviderBroker;
 import org.onlab.onos.net.provider.AbstractProviderService;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import java.util.List;
 
 import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Provides basic implementation of the device SB &amp; NB APIs.
@@ -42,24 +44,25 @@
     public static final String DEVICE_DESCRIPTION_NULL = "Device description cannot be null";
     public static final String PORT_DESCRIPTION_NULL = "Port description cannot be null";
 
-    private Logger log = LoggerFactory.getLogger(SimpleDeviceManager.class);
+    private final Logger log = getLogger(getClass());
 
     private final AbstractListenerManager<DeviceEvent, DeviceListener>
             listenerManager = new AbstractListenerManager<>();
 
-    private EventDispatchService eventDispatcher;
-
     private final DeviceStore store = new DeviceStore();
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private EventDispatchService eventDispatcher;
+
     @Activate
     public void activate() {
-//        eventDispatcher.addSink(DeviceEvent.class, listenerManager);
+        eventDispatcher.addSink(DeviceEvent.class, listenerManager);
         log.info("Started");
     }
 
     @Deactivate
     public void deactivate() {
-//        eventDispatcher.removeSink(DeviceEvent.class);
+        eventDispatcher.removeSink(DeviceEvent.class);
         log.info("Stopped");
     }
 
diff --git a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleHostManager.java b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleHostManager.java
index 81397cf..0c0c983 100644
--- a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleHostManager.java
+++ b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleHostManager.java
@@ -3,55 +3,56 @@
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
+import org.onlab.onos.event.AbstractListenerManager;
+import org.onlab.onos.event.EventDispatchService;
 import org.onlab.onos.net.host.HostDescription;
+import org.onlab.onos.net.host.HostEvent;
+import org.onlab.onos.net.host.HostListener;
 import org.onlab.onos.net.host.HostProvider;
 import org.onlab.onos.net.host.HostProviderBroker;
 import org.onlab.onos.net.host.HostProviderService;
 import org.onlab.onos.net.provider.AbstractProviderBroker;
 import org.onlab.onos.net.provider.AbstractProviderService;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Provides basic implementation of the host SB &amp; NB APIs.
  */
 @Component(immediate = true)
 @Service
-public class SimpleHostManager implements HostProviderBroker {
+public class SimpleHostManager
+        extends AbstractProviderBroker<HostProvider, HostProviderService>
+        implements HostProviderBroker {
 
-    private Logger log = LoggerFactory.getLogger(SimpleHostManager.class);
+    private final Logger log = getLogger(getClass());
 
-    private final HostProviderBroker broker = new InternalBroker();
+    private final AbstractListenerManager<HostEvent, HostListener>
+            listenerManager = new AbstractListenerManager<>();
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private EventDispatchService eventDispatcher;
+
 
     @Activate
     public void activate() {
+        eventDispatcher.addSink(HostEvent.class, listenerManager);
         log.info("Started");
     }
 
     @Deactivate
     public void deactivate() {
+        eventDispatcher.removeSink(HostEvent.class);
         log.info("Stopped");
     }
 
     @Override
-    public HostProviderService register(HostProvider provider) {
-        return broker.register(provider);
-    }
-
-    @Override
-    public void unregister(HostProvider provider) {
-        broker.unregister(provider);
-    }
-
-    // Internal delegate for tracking various providers and issuing them a
-    // personalized provider service.
-    private class InternalBroker extends AbstractProviderBroker<HostProvider, HostProviderService>
-            implements HostProviderBroker {
-        @Override
-        protected HostProviderService createProviderService(HostProvider provider) {
-            return new InternalHostProviderService(provider);
-        }
+    protected HostProviderService createProviderService(HostProvider provider) {
+        return new InternalHostProviderService(provider);
     }
 
     // Personalized host provider service issued to the supplied provider.
diff --git a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkManager.java b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkManager.java
index 6283e0b..73fedab 100644
--- a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkManager.java
+++ b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkManager.java
@@ -3,55 +3,55 @@
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
+import org.onlab.onos.event.AbstractListenerManager;
+import org.onlab.onos.event.EventDispatchService;
 import org.onlab.onos.net.link.LinkDescription;
+import org.onlab.onos.net.link.LinkEvent;
+import org.onlab.onos.net.link.LinkListener;
 import org.onlab.onos.net.link.LinkProvider;
 import org.onlab.onos.net.link.LinkProviderBroker;
 import org.onlab.onos.net.link.LinkProviderService;
 import org.onlab.onos.net.provider.AbstractProviderBroker;
 import org.onlab.onos.net.provider.AbstractProviderService;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Provides basic implementation of the link SB &amp; NB APIs.
  */
 @Component(immediate = true)
 @Service
-public class SimpleLinkManager implements LinkProviderBroker {
+public class SimpleLinkManager
+        extends AbstractProviderBroker<LinkProvider, LinkProviderService>
+        implements LinkProviderBroker {
 
-    private Logger log = LoggerFactory.getLogger(SimpleLinkManager.class);
+    private final Logger log = getLogger(getClass());
 
-    private final LinkProviderBroker broker = new InternalBroker();
+    private final AbstractListenerManager<LinkEvent, LinkListener>
+            listenerManager = new AbstractListenerManager<>();
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private EventDispatchService eventDispatcher;
 
     @Activate
     public void activate() {
+        eventDispatcher.addSink(LinkEvent.class, listenerManager);
         log.info("Started");
     }
 
     @Deactivate
     public void deactivate() {
+        eventDispatcher.removeSink(LinkEvent.class);
         log.info("Stopped");
     }
 
     @Override
-    public LinkProviderService register(LinkProvider provider) {
-        return broker.register(provider);
-    }
-
-    @Override
-    public void unregister(LinkProvider provider) {
-        broker.unregister(provider);
-    }
-
-    // Internal delegate for tracking various providers and issuing them a
-    // personalized provider service.
-    private class InternalBroker extends AbstractProviderBroker<LinkProvider, LinkProviderService>
-            implements LinkProviderBroker {
-        @Override
-        protected LinkProviderService createProviderService(LinkProvider provider) {
-            return new InternalLinkProviderService(provider);
-        }
+    protected LinkProviderService createProviderService(LinkProvider provider) {
+        return new InternalLinkProviderService(provider);
     }
 
     // Personalized link provider service issued to the supplied provider.
diff --git a/net/core/trivial/src/main/javadoc/org/onlab/onos/event/impl/package.html b/net/core/trivial/src/main/javadoc/org/onlab/onos/event/impl/package.html
new file mode 100644
index 0000000..a22d62d
--- /dev/null
+++ b/net/core/trivial/src/main/javadoc/org/onlab/onos/event/impl/package.html
@@ -0,0 +1,3 @@
+<body>
+ONOS local event dispatching mechanism.
+</body>
\ No newline at end of file
diff --git a/net/core/trivial/src/main/javadoc/org/onlab/onos/impl/package.html b/net/core/trivial/src/main/javadoc/org/onlab/onos/impl/package.html
new file mode 100644
index 0000000..087085c
--- /dev/null
+++ b/net/core/trivial/src/main/javadoc/org/onlab/onos/impl/package.html
@@ -0,0 +1,3 @@
+<body>
+ONOS Core infrastructure implementations.
+</body>
\ No newline at end of file
diff --git a/net/pom.xml b/net/pom.xml
index bd4fa6e..fa146d9 100644
--- a/net/pom.xml
+++ b/net/pom.xml
@@ -26,6 +26,11 @@
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>org.onlab.onos</groupId>
+            <artifactId>onlab-misc</artifactId>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/pom.xml b/pom.xml
index 9ff1197..207a44f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -112,6 +112,12 @@
             <!-- ONOS related -->
             <dependency>
                 <groupId>org.onlab.onos</groupId>
+                <artifactId>onlab-misc</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>org.onlab.onos</groupId>
                 <artifactId>onos-api</artifactId>
                 <version>${project.version}</version>
             </dependency>
@@ -260,13 +266,13 @@
                         <group>
                             <title>Network Model &amp; Services</title>
                             <packages>
-                                org.onlab.onos.*
+                                org.onlab.onos:org.onlab.onos.*
                             </packages>
                         </group>
                         <group>
                             <title>Core Subsystems</title>
                             <packages>
-                                org.onlab.onos.net.trivial.impl:org.onlab.onos.net.*.impl
+                                org.onlab.onos.net.trivial.impl:org.onlab.onos.net.*.impl:org.onlab.onos.impl:org.onlab.onos.event.impl
                             </packages>
                         </group>
                         <group>
diff --git a/providers/of/device/src/main/java/org/onlab/onos/provider/of/device/impl/OpenFlowDeviceProvider.java b/providers/of/device/src/main/java/org/onlab/onos/provider/of/device/impl/OpenFlowDeviceProvider.java
index e601ac7..5977848 100644
--- a/providers/of/device/src/main/java/org/onlab/onos/provider/of/device/impl/OpenFlowDeviceProvider.java
+++ b/providers/of/device/src/main/java/org/onlab/onos/provider/of/device/impl/OpenFlowDeviceProvider.java
@@ -12,8 +12,10 @@
 import org.onlab.onos.net.device.DeviceProviderService;
 import org.onlab.onos.net.provider.AbstractProvider;
 import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.onos.of.controller.OpenFlowController;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Provider which uses an OpenFlow controller to detect network
@@ -22,17 +24,16 @@
 @Component(immediate = true)
 public class OpenFlowDeviceProvider extends AbstractProvider implements DeviceProvider {
 
-    private final Logger log = LoggerFactory.getLogger(OpenFlowDeviceProvider.class);
+    private final Logger log = getLogger(getClass());
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected DeviceProviderBroker providerBroker;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected OpenFlowController controller;
+
     private DeviceProviderService providerService;
 
-//    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-//    protected OpenFlowController controller;
-
-
     /**
      * Creates an OpenFlow device provider.
      */
diff --git a/providers/of/host/src/main/java/org/onlab/onos/provider/of/host/impl/OpenFlowHostProvider.java b/providers/of/host/src/main/java/org/onlab/onos/provider/of/host/impl/OpenFlowHostProvider.java
index ff7837a..2faeb43 100644
--- a/providers/of/host/src/main/java/org/onlab/onos/provider/of/host/impl/OpenFlowHostProvider.java
+++ b/providers/of/host/src/main/java/org/onlab/onos/provider/of/host/impl/OpenFlowHostProvider.java
@@ -11,8 +11,10 @@
 import org.onlab.onos.net.host.HostProviderService;
 import org.onlab.onos.net.provider.AbstractProvider;
 import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.onos.of.controller.OpenFlowController;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Provider which uses an OpenFlow controller to detect network
@@ -21,15 +23,15 @@
 @Component(immediate = true)
 public class OpenFlowHostProvider extends AbstractProvider implements HostProvider {
 
-    private final Logger log = LoggerFactory.getLogger(OpenFlowHostProvider.class);
+    private final Logger log = getLogger(getClass());
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected HostProviderBroker providerBroker;
 
-    private HostProviderService providerService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected OpenFlowController controller;
 
-//    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-//    protected OpenFlowController controller;
+    private HostProviderService providerService;
 
     /**
      * Creates an OpenFlow host provider.
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 88b5874..dacf3a8 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
@@ -10,8 +10,10 @@
 import org.onlab.onos.net.link.LinkProviderService;
 import org.onlab.onos.net.provider.AbstractProvider;
 import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.onos.of.controller.OpenFlowController;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Provider which uses an OpenFlow controller to detect network
@@ -20,15 +22,15 @@
 @Component(immediate = true)
 public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvider {
 
-    private final Logger log = LoggerFactory.getLogger(OpenFlowLinkProvider.class);
+    private final Logger log = getLogger(getClass());
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected LinkProviderBroker providerBroker;
 
-    private LinkProviderService providerService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected OpenFlowController controller;
 
-//    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-//    protected OpenFlowController controller;
+    private LinkProviderService providerService;
 
     /**
      * Creates an OpenFlow link provider.
diff --git a/providers/pom.xml b/providers/pom.xml
index 71f6f0d..fc73d3b 100644
--- a/providers/pom.xml
+++ b/providers/pom.xml
@@ -24,7 +24,11 @@
         <dependency>
             <groupId>org.onlab.onos</groupId>
             <artifactId>onos-api</artifactId>
-            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onlab.onos</groupId>
+            <artifactId>onlab-misc</artifactId>
         </dependency>
 
         <dependency>
diff --git a/utils/misc/pom.xml b/utils/misc/pom.xml
new file mode 100644
index 0000000..5862727
--- /dev/null
+++ b/utils/misc/pom.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onlab.onos</groupId>
+        <artifactId>onlab-utils</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>onlab-misc</artifactId>
+    <packaging>bundle</packaging>
+
+    <description>Miscellaneous ON.Lab utilities</description>
+
+    <dependencies>
+    </dependencies>
+
+</project>
diff --git a/utils/misc/src/main/java/org/onlab/util/Foo.java b/utils/misc/src/main/java/org/onlab/util/Foo.java
deleted file mode 100644
index 8113e1f..0000000
--- a/utils/misc/src/main/java/org/onlab/util/Foo.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package org.onlab.util;
-
-public class Foo {
-}
diff --git a/utils/misc/src/main/java/org/onlab/util/Tools.java b/utils/misc/src/main/java/org/onlab/util/Tools.java
new file mode 100644
index 0000000..e1e9ed7
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/util/Tools.java
@@ -0,0 +1,23 @@
+package org.onlab.util;
+
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+
+import java.util.concurrent.ThreadFactory;
+
+public abstract class Tools {
+
+    private Tools() {
+    }
+
+    /**
+     * Returns a thread factory that produces threads named according to the
+     * supplied name pattern.
+     *
+     * @param pattern name pattern
+     * @return thread factory
+     */
+    public static ThreadFactory namedThreads(String pattern) {
+        return new ThreadFactoryBuilder().setNameFormat(pattern).build();
+    }
+
+}