Added some tests.
diff --git a/net/api/src/main/java/org/onlab/onos/net/provider/AbstractProviderRegistry.java b/net/api/src/main/java/org/onlab/onos/net/provider/AbstractProviderRegistry.java
index 6975447..02a486e 100644
--- a/net/api/src/main/java/org/onlab/onos/net/provider/AbstractProviderRegistry.java
+++ b/net/api/src/main/java/org/onlab/onos/net/provider/AbstractProviderRegistry.java
@@ -1,10 +1,13 @@
 package org.onlab.onos.net.provider;
 
+import com.google.common.collect.ImmutableSet;
+
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
 
-import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
 
 /**
  * Base implementation of provider registry.
@@ -28,7 +31,7 @@
     @Override
     public synchronized S register(P provider) {
         checkNotNull(provider, "Provider cannot be null");
-        checkArgument(!services.containsKey(provider), "Provider %s already registered", provider.id());
+        checkState(!services.containsKey(provider.id()), "Provider %s already registered", provider.id());
         S service = createProviderService(provider);
         services.put(provider.id(), service);
         return service;
@@ -37,10 +40,16 @@
     @Override
     public synchronized void unregister(P provider) {
         checkNotNull(provider, "Provider cannot be null");
-        S service = services.get(provider);
+        S service = services.get(provider.id());
         if (service != null && service instanceof AbstractProviderService) {
             ((AbstractProviderService) service).invalidate();
-            services.remove(provider);
+            services.remove(provider.id());
         }
     }
+
+    @Override
+    public synchronized Set<ProviderId> getProviders() {
+        return ImmutableSet.copyOf(services.keySet());
+    }
+
 }
diff --git a/net/api/src/main/java/org/onlab/onos/net/provider/ProviderRegistry.java b/net/api/src/main/java/org/onlab/onos/net/provider/ProviderRegistry.java
index 93436fc..08975e2 100644
--- a/net/api/src/main/java/org/onlab/onos/net/provider/ProviderRegistry.java
+++ b/net/api/src/main/java/org/onlab/onos/net/provider/ProviderRegistry.java
@@ -1,5 +1,7 @@
 package org.onlab.onos.net.provider;
 
+import java.util.Set;
+
 /**
  * Registry for tracking information providers with the core.
  *
@@ -29,4 +31,11 @@
      */
     void unregister(P provider);
 
+    /**
+     * Returns a set of currently registered provider identities.
+     *
+     * @return set of provider identifiers
+     */
+    Set<ProviderId> getProviders();
+
 }
diff --git a/net/api/src/test/java/org/onlab/onos/net/provider/AbstractProviderRegistryTest.java b/net/api/src/test/java/org/onlab/onos/net/provider/AbstractProviderRegistryTest.java
new file mode 100644
index 0000000..abbe5be
--- /dev/null
+++ b/net/api/src/test/java/org/onlab/onos/net/provider/AbstractProviderRegistryTest.java
@@ -0,0 +1,74 @@
+package org.onlab.onos.net.provider;
+
+import org.junit.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test of the base provider registry.
+ */
+public class AbstractProviderRegistryTest {
+
+    private class TestProviderService extends AbstractProviderService<TestProvider> {
+        protected TestProviderService(TestProvider provider) {
+            super(provider);
+        }
+    }
+
+    private class TestProviderRegistry extends AbstractProviderRegistry<TestProvider, TestProviderService> {
+        @Override
+        protected TestProviderService createProviderService(TestProvider provider) {
+            return new TestProviderService(provider);
+        }
+    }
+
+    @Test
+    public void basics() {
+        TestProviderRegistry registry = new TestProviderRegistry();
+        assertEquals("incorrect provider count", 0, registry.getProviders().size());
+
+        ProviderId fooId = new ProviderId("foo");
+        TestProvider pFoo = new TestProvider(fooId);
+        TestProviderService psFoo = registry.register(pFoo);
+        assertEquals("incorrect provider count", 1, registry.getProviders().size());
+        assertThat("provider not found", registry.getProviders().contains(fooId));
+        assertEquals("incorrect provider", psFoo.provider(), pFoo);
+
+        ProviderId barId = new ProviderId("bar");
+        TestProvider pBar = new TestProvider(barId);
+        TestProviderService psBar = registry.register(pBar);
+        assertEquals("incorrect provider count", 2, registry.getProviders().size());
+        assertThat("provider not found", registry.getProviders().contains(barId));
+        assertEquals("incorrect provider", psBar.provider(), pBar);
+
+        psFoo.checkValidity();
+        registry.unregister(pFoo);
+        psBar.checkValidity();
+        assertEquals("incorrect provider count", 1, registry.getProviders().size());
+        assertThat("provider not found", registry.getProviders().contains(barId));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void duplicateRegistration() {
+        TestProviderRegistry registry = new TestProviderRegistry();
+        TestProvider pFoo = new TestProvider(new ProviderId("foo"));
+        registry.register(pFoo);
+        registry.register(pFoo);
+    }
+
+    @Test
+    public void voidUnregistration() {
+        TestProviderRegistry registry = new TestProviderRegistry();
+        registry.unregister(new TestProvider(new ProviderId("foo")));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void unregistration() {
+        TestProviderRegistry registry = new TestProviderRegistry();
+        TestProvider pFoo = new TestProvider(new ProviderId("foo"));
+        TestProviderService psFoo = registry.register(pFoo);
+        registry.unregister(pFoo);
+        psFoo.checkValidity();
+    }
+}
diff --git a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/DeviceStore.java b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/DeviceStore.java
index f907e35..c874600 100644
--- a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/DeviceStore.java
+++ b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/DeviceStore.java
@@ -2,6 +2,8 @@
 
 import org.onlab.onos.net.Device;
 import org.onlab.onos.net.DeviceId;
+import org.onlab.onos.net.Port;
+import org.onlab.onos.net.PortNumber;
 import org.onlab.onos.net.device.DeviceDescription;
 import org.onlab.onos.net.device.DeviceEvent;
 import org.onlab.onos.net.device.PortDescription;
@@ -66,4 +68,35 @@
                                         PortDescription portDescription) {
         return null;
     }
+
+    /**
+     * Returns the device with the specified identifier.
+     *
+     * @param deviceId device identifier
+     * @return device
+     */
+    public Device getDevice(DeviceId deviceId) {
+        return null;
+    }
+
+    /**
+     * Returns the list of ports that belong to the specified device.
+     *
+     * @param deviceId device identifier
+     * @return list of device ports
+     */
+    public List<Port> getPorts(DeviceId deviceId) {
+        return null;
+    }
+
+    /**
+     * Returns the specified device port.
+     *
+     * @param deviceId   device identifier
+     * @param portNumber port number
+     * @return device port
+     */
+    public Port getPort(DeviceId deviceId, PortNumber portNumber) {
+        return null;
+    }
 }
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 4344fd0..b713f00 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
@@ -80,20 +80,20 @@
     @Override
     public Device getDevice(DeviceId deviceId) {
         checkNotNull(deviceId, DEVICE_ID_NULL);
-        return null;
+        return store.getDevice(deviceId);
     }
 
     @Override
     public List<Port> getPorts(DeviceId deviceId) {
         checkNotNull(deviceId, DEVICE_ID_NULL);
-        return null;
+        return store.getPorts(deviceId);
     }
 
     @Override
     public Port getPort(DeviceId deviceId, PortNumber portNumber) {
         checkNotNull(deviceId, DEVICE_ID_NULL);
         checkNotNull(portNumber, PORT_NUMBER_NULL);
-        return null;
+        return store.getPort(deviceId, portNumber);
     }
 
     @Override