Added simple link manager implementation.
Added link admin stuff; unit tests to come.
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 1c7306f..63fb2cc 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
@@ -50,7 +50,7 @@
     private final SimpleLinkStore store = new SimpleLinkStore();
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    private EventDeliveryService eventDispatcher;
+    protected EventDeliveryService eventDispatcher;
 
     @Activate
     public void activate() {
diff --git a/net/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleLinkManagerTest.java b/net/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleLinkManagerTest.java
new file mode 100644
index 0000000..710cb08
--- /dev/null
+++ b/net/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleLinkManagerTest.java
@@ -0,0 +1,126 @@
+package org.onlab.onos.net.trivial.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.onos.event.Event;
+import org.onlab.onos.net.Device;
+import org.onlab.onos.net.DeviceId;
+import org.onlab.onos.net.MastershipRole;
+import org.onlab.onos.net.Port;
+import org.onlab.onos.net.PortNumber;
+import org.onlab.onos.net.device.DefaultDeviceDescription;
+import org.onlab.onos.net.device.DefaultPortDescription;
+import org.onlab.onos.net.device.DeviceAdminService;
+import org.onlab.onos.net.device.DeviceDescription;
+import org.onlab.onos.net.device.DeviceEvent;
+import org.onlab.onos.net.device.DeviceListener;
+import org.onlab.onos.net.device.DeviceProvider;
+import org.onlab.onos.net.device.DeviceProviderRegistry;
+import org.onlab.onos.net.device.DeviceProviderService;
+import org.onlab.onos.net.device.DeviceService;
+import org.onlab.onos.net.device.PortDescription;
+import org.onlab.onos.net.link.LinkAdminService;
+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.LinkProviderRegistry;
+import org.onlab.onos.net.link.LinkProviderService;
+import org.onlab.onos.net.link.LinkService;
+import org.onlab.onos.net.provider.AbstractProvider;
+import org.onlab.onos.net.provider.ProviderId;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import static org.junit.Assert.*;
+import static org.onlab.onos.net.Device.Type.SWITCH;
+import static org.onlab.onos.net.DeviceId.deviceId;
+import static org.onlab.onos.net.device.DeviceEvent.Type.*;
+
+/**
+ * Test codifying the link service & link provider service contracts.
+ */
+public class SimpleLinkManagerTest {
+
+    private static final ProviderId PID = new ProviderId("foo");
+    private static final DeviceId DID1 = deviceId("of:foo");
+    private static final DeviceId DID2 = deviceId("of:bar");
+    private static final String MFR = "whitebox";
+    private static final String HW = "1.1.x";
+    private static final String SW1 = "3.8.1";
+    private static final String SW2 = "3.9.5";
+    private static final String SN = "43311-12345";
+
+    private static final PortNumber P1 = PortNumber.portNumber(1);
+    private static final PortNumber P2 = PortNumber.portNumber(2);
+    private static final PortNumber P3 = PortNumber.portNumber(3);
+
+
+    private SimpleLinkManager mgr;
+
+    protected LinkService service;
+    protected LinkAdminService admin;
+    protected LinkProviderRegistry registry;
+    protected LinkProviderService providerService;
+    protected TestProvider provider;
+    protected TestListener listener = new TestListener();
+
+    @Before
+    public void setUp() {
+        mgr = new SimpleLinkManager();
+        service = mgr;
+        admin = mgr;
+        registry = mgr;
+        mgr.eventDispatcher = new TestEventDispatcher();
+        mgr.activate();
+
+        service.addListener(listener);
+
+        provider = new TestProvider();
+        providerService = registry.register(provider);
+        assertTrue("provider should be registered",
+                   registry.getProviders().contains(provider.id()));
+    }
+
+    @After
+    public void tearDown() {
+        registry.unregister(provider);
+        assertFalse("provider should not be registered",
+                    registry.getProviders().contains(provider.id()));
+        service.removeListener(listener);
+        mgr.deactivate();
+    }
+
+
+    protected void validateEvents(Enum... types) {
+        int i = 0;
+        assertEquals("wrong events received", types.length, listener.events.size());
+        for (Event event : listener.events) {
+            assertEquals("incorrect event type", types[i], event.type());
+            i++;
+        }
+        listener.events.clear();
+    }
+
+
+    private class TestProvider extends AbstractProvider implements LinkProvider {
+        private Device deviceReceived;
+        private MastershipRole roleReceived;
+
+        public TestProvider() {
+            super(PID);
+        }
+    }
+
+    private static class TestListener implements LinkListener {
+        final List<LinkEvent> events = new ArrayList<>();
+
+        @Override
+        public void event(LinkEvent event) {
+            events.add(event);
+        }
+    }
+
+}