Adding ability to project device, link and host model as alternate entities.

Change-Id: If23c018b024a3bbe693f0e66888c5f1707e3f66d
diff --git a/apps/flowanalyzer/src/test/java/org/onosproject/flowanalyzer/MockLinkService.java b/apps/flowanalyzer/src/test/java/org/onosproject/flowanalyzer/MockLinkService.java
index 6ae2c2b..a922c16 100644
--- a/apps/flowanalyzer/src/test/java/org/onosproject/flowanalyzer/MockLinkService.java
+++ b/apps/flowanalyzer/src/test/java/org/onosproject/flowanalyzer/MockLinkService.java
@@ -1,27 +1,25 @@
 package org.onosproject.flowanalyzer;
 
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.link.LinkServiceAdapter;
-import org.onosproject.net.topology.TopologyEdge;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultLink;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.ElementId;
 import org.onosproject.net.HostId;
 import org.onosproject.net.Link;
-import org.onosproject.net.Annotations;
-import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.link.LinkServiceAdapter;
+import org.onosproject.net.topology.TopologyEdge;
 import org.onosproject.net.topology.TopologyVertex;
 
-import java.util.Set;
 import java.util.ArrayList;
-import java.util.List;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 import static org.onosproject.net.Link.State.ACTIVE;
 
-
 /**
- * Created by nikcheerla on 7/21/15.
+ * Test fixture for the flow analyzer.
  */
 public class MockLinkService extends LinkServiceAdapter {
     DefaultMutableTopologyGraph createdGraph = new DefaultMutableTopologyGraph(new HashSet<>(), new HashSet<>());
@@ -47,7 +45,7 @@
     @Override
     public Set<Link> getDeviceEgressLinks(DeviceId deviceId) {
         Set<Link> setL = new HashSet<>();
-        for (Link l: links) {
+        for (Link l : links) {
             if (l.src().elementId() instanceof DeviceId && l.src().deviceId().equals(deviceId)) {
                 setL.add(l);
             }
@@ -58,7 +56,7 @@
     @Override
     public Set<Link> getDeviceIngressLinks(DeviceId deviceId) {
         Set<Link> setL = new HashSet<>();
-        for (Link l: links) {
+        for (Link l : links) {
             if (l.dst().elementId() instanceof DeviceId && l.dst().deviceId().equals(deviceId)) {
                 setL.add(l);
             }
@@ -70,7 +68,7 @@
     @Override
     public Set<Link> getEgressLinks(ConnectPoint pt) {
         Set<Link> setL = new HashSet<>();
-        for (Link l: links) {
+        for (Link l : links) {
             if (l.src().equals(pt)) {
                 setL.add(l);
             }
@@ -81,7 +79,7 @@
     @Override
     public Set<Link> getIngressLinks(ConnectPoint pt) {
         Set<Link> setL = new HashSet<>();
-        for (Link l: links) {
+        for (Link l : links) {
             if (l.dst().equals(pt)) {
                 setL.add(l);
             }
@@ -92,7 +90,7 @@
     @Override
     public Set<Link> getLinks(ConnectPoint pt) {
         Set<Link> setL = new HashSet<>();
-        for (Link l: links) {
+        for (Link l : links) {
             if (l.src().equals(pt) || l.dst().equals(pt)) {
                 setL.add(l);
             }
@@ -119,47 +117,7 @@
         ConnectPoint src = new ConnectPoint(d1, PortNumber.portNumber(port));
         ConnectPoint dst = new ConnectPoint(d2, PortNumber.portNumber(port2));
         Link curLink;
-        curLink = new Link() {
-            @Override
-            public ConnectPoint src() {
-                return src;
-            }
-
-            @Override
-            public ConnectPoint dst() {
-                return dst;
-            }
-
-            @Override
-            public boolean isDurable() {
-                return true;
-            }
-
-            @Override
-            public boolean isExpected() {
-                return false;
-            }
-
-            @Override
-            public Annotations annotations() {
-                return null;
-            }
-
-            @Override
-            public Type type() {
-                return null;
-            }
-
-            @Override
-            public ProviderId providerId() {
-                return null;
-            }
-
-            @Override
-            public State state() {
-                return ACTIVE;
-            }
-        };
+        curLink = DefaultLink.builder().src(src).dst(dst).state(ACTIVE).build();
         links.add(curLink);
         if (d1 instanceof DeviceId && d2 instanceof DeviceId) {
             TopologyVertex v1 = () -> (DeviceId) d1, v2 = () -> (DeviceId) d2;
diff --git a/core/api/src/main/java/org/onosproject/net/AbstractElement.java b/core/api/src/main/java/org/onosproject/net/AbstractElement.java
index 595e7b9..79170f9 100644
--- a/core/api/src/main/java/org/onosproject/net/AbstractElement.java
+++ b/core/api/src/main/java/org/onosproject/net/AbstractElement.java
@@ -20,7 +20,7 @@
 /**
  * Base implementation of network elements, i.e. devices or hosts.
  */
-public abstract class AbstractElement extends AbstractModel implements Element {
+public abstract class AbstractElement extends AbstractProjectableModel implements Element {
 
     protected final ElementId id;
 
diff --git a/core/api/src/main/java/org/onosproject/net/AbstractProjectableModel.java b/core/api/src/main/java/org/onosproject/net/AbstractProjectableModel.java
new file mode 100644
index 0000000..6fee974
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/AbstractProjectableModel.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2014-2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net;
+
+import com.google.common.annotations.Beta;
+import org.onlab.util.ItemNotFoundException;
+import org.onosproject.net.driver.Behaviour;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverData;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.net.driver.Projectable;
+import org.onosproject.net.provider.ProviderId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkState;
+
+/**
+ * Base model entity, capable of being extended via projection mechanism.
+ */
+@Beta
+public abstract class AbstractProjectableModel extends AbstractModel implements Projectable {
+
+    private static Logger log = LoggerFactory.getLogger(AbstractProjectableModel.class);
+
+    protected static final String NO_DRIVER_SERVICE = "Driver service not bound yet";
+    protected static final String NO_DRIVER = "Driver has not been bound to %s";
+
+    // Static reference to the driver service; injected via setDriverService
+    private static DriverService driverService;
+
+    private Driver driver;
+
+    // For serialization
+    public AbstractProjectableModel() {
+    }
+
+    /**
+     * Creates a model entity attributed to the specified provider and
+     * optionally annotated.
+     *
+     * @param providerId  identity of the provider
+     * @param annotations optional key/value annotations
+     */
+    public AbstractProjectableModel(ProviderId providerId, Annotations[] annotations) {
+        super(providerId, annotations);
+    }
+
+    /**
+     * Injects the driver service reference for use during projections into
+     * various behaviours.
+     * <p>
+     * This is a privileged call; unauthorized invocations will result in
+     * illegal state exception
+     *
+     * @param key           opaque admin key object
+     * @param driverService injected driver service
+     * @throws IllegalStateException when invoked sans authorization
+     */
+    public static void setDriverService(Object key, DriverService driverService) {
+        // TODO: Rework this once we have means to enforce access to admin services in general
+        checkState(AbstractProjectableModel.driverService == key, "Unauthorized invocation");
+        AbstractProjectableModel.driverService = driverService;
+    }
+
+    /**
+     * Returns the currently bound driver service reference.
+     *
+     * @return driver service
+     */
+    protected static DriverService driverService() {
+        return driverService;
+    }
+
+    /**
+     * Returns the currently bound driver or null of no driver is bound.
+     *
+     * @return bound driver; null if none
+     */
+    protected Driver driver() {
+        return driver;
+    }
+
+    @Override
+    public <B extends Behaviour> B as(Class<B> projectionClass) {
+        checkState(driverService != null, NO_DRIVER_SERVICE);
+        if (driver == null) {
+            driver = locateDriver();
+        }
+        checkState(driver != null, NO_DRIVER, this);
+        return driver.createBehaviour(asData(), projectionClass);
+    }
+
+    @Override
+    public <B extends Behaviour> boolean is(Class<B> projectionClass) {
+        checkState(driverService != null, NO_DRIVER_SERVICE);
+        if (driver == null) {
+            driver = locateDriver();
+        }
+        checkState(driver != null, "Driver has not been bound to %s", this);
+        return driver.hasBehaviour(projectionClass);
+    }
+
+    /**
+     * Locates the driver to be used by this entity.
+     * <p>
+     * The default implementation derives the driver based on the {@code driver}
+     * annotation value.
+     *
+     * @return driver for alternate projections of this model entity or null
+     * if no driver is expected or driver is not found
+     */
+    protected Driver locateDriver() {
+        String driverName = annotations().value(AnnotationKeys.DRIVER);
+        if (driverName != null) {
+            try {
+                return driverService.getDriver(driverName);
+            } catch (ItemNotFoundException e) {
+                log.warn("Driver {} not found.", driverName);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns self as an immutable driver data instance.
+     *
+     * @return self as driver data
+     */
+    protected DriverData asData() {
+        return new AnnotationDriverData();
+    }
+
+
+    /**
+     * Projection of the parent entity as a driver data entity.
+     */
+    protected class AnnotationDriverData implements DriverData {
+        @Override
+        public Driver driver() {
+            return driver;
+        }
+
+        @Override
+        public DeviceId deviceId() {
+            throw new UnsupportedOperationException("Entity not a device");
+        }
+
+        @Override
+        public MutableAnnotations set(String key, String value) {
+            throw new UnsupportedOperationException("Entity is immutable");
+        }
+
+        @Override
+        public MutableAnnotations clear(String... keys) {
+            throw new UnsupportedOperationException("Entity is immutable");
+        }
+
+        @Override
+        public Set<String> keys() {
+            return annotations().keys();
+        }
+
+        @Override
+        public String value(String key) {
+            return annotations().value(key);
+        }
+    }
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/DefaultDevice.java b/core/api/src/main/java/org/onosproject/net/DefaultDevice.java
index f3f0fe7..401740a 100644
--- a/core/api/src/main/java/org/onosproject/net/DefaultDevice.java
+++ b/core/api/src/main/java/org/onosproject/net/DefaultDevice.java
@@ -15,12 +15,15 @@
  */
 package org.onosproject.net;
 
-import org.onosproject.net.provider.ProviderId;
 import org.onlab.packet.ChassisId;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverData;
+import org.onosproject.net.provider.ProviderId;
 
 import java.util.Objects;
 
 import static com.google.common.base.MoreObjects.toStringHelper;
+import static org.onlab.util.Tools.nullIsNotFound;
 
 /**
  * Default infrastructure device model implementation.
@@ -105,6 +108,33 @@
         return chassisId;
     }
 
+    /**
+     * Returns self as an immutable driver data instance.
+     *
+     * @return self as driver data
+     */
+    protected DriverData asData() {
+        return new DeviceDriverData();
+    }
+
+    @Override
+    protected Driver locateDriver() {
+        Driver driver = super.locateDriver();
+        return driver != null ? driver :
+                nullIsNotFound(driverService().getDriver(manufacturer, hwVersion, swVersion),
+                               "Driver not found");
+    }
+
+    /**
+     * Projection of the parent entity as a driver data entity.
+     */
+    protected class DeviceDriverData extends AnnotationDriverData {
+        @Override
+        public DeviceId deviceId() {
+            return id();
+        }
+    }
+
     @Override
     public int hashCode() {
         return Objects.hash(id, type, manufacturer, hwVersion, swVersion, serialNumber);
@@ -136,6 +166,7 @@
                 .add("hwVersion", hwVersion)
                 .add("swVersion", swVersion)
                 .add("serialNumber", serialNumber)
+                .add("driver", driver() != null ? driver().name() : "")
                 .toString();
     }
 
diff --git a/core/api/src/main/java/org/onosproject/net/DefaultLink.java b/core/api/src/main/java/org/onosproject/net/DefaultLink.java
index 1876db6..5515175 100644
--- a/core/api/src/main/java/org/onosproject/net/DefaultLink.java
+++ b/core/api/src/main/java/org/onosproject/net/DefaultLink.java
@@ -24,11 +24,10 @@
 import static org.onosproject.net.DefaultAnnotations.EMPTY;
 import static com.google.common.base.Preconditions.checkNotNull;
 
-
 /**
  * Default infrastructure link model implementation.
  */
-public class DefaultLink extends AbstractModel implements Link {
+public class DefaultLink extends AbstractProjectableModel implements Link {
 
     private final ConnectPoint src;
     private final ConnectPoint dst;
@@ -60,7 +59,7 @@
      * @param dst         link destination
      * @param type        link type
      * @param state       link state
-     * @param isExpected   indicates if the link is preconfigured
+     * @param isExpected  indicates if the link is preconfigured
      * @param annotations optional key/value annotations
      */
     private DefaultLink(ProviderId providerId, ConnectPoint src, ConnectPoint dst,
diff --git a/core/api/src/main/java/org/onosproject/net/Element.java b/core/api/src/main/java/org/onosproject/net/Element.java
index 6cdab9e..b918ad9 100644
--- a/core/api/src/main/java/org/onosproject/net/Element.java
+++ b/core/api/src/main/java/org/onosproject/net/Element.java
@@ -15,10 +15,12 @@
  */
 package org.onosproject.net;
 
+import org.onosproject.net.driver.Projectable;
+
 /**
  * Base abstraction of a network element, i.e. an infrastructure device or an end-station host.
  */
-public interface Element extends Annotated, Provided {
+public interface Element extends Annotated, Provided, Projectable {
 
     /**
      * Returns the network element identifier.
diff --git a/core/api/src/main/java/org/onosproject/net/Link.java b/core/api/src/main/java/org/onosproject/net/Link.java
index eb09290..9209138 100644
--- a/core/api/src/main/java/org/onosproject/net/Link.java
+++ b/core/api/src/main/java/org/onosproject/net/Link.java
@@ -15,10 +15,12 @@
  */
 package org.onosproject.net;
 
+import org.onosproject.net.driver.Projectable;
+
 /**
  * Abstraction of a network infrastructure link.
  */
-public interface Link extends Annotated, Provided, NetworkResource {
+public interface Link extends Annotated, Provided, Projectable, NetworkResource {
 
     /**
      * Coarse representation of the link type.
diff --git a/core/api/src/main/java/org/onosproject/net/driver/AbstractBehaviour.java b/core/api/src/main/java/org/onosproject/net/driver/AbstractBehaviour.java
index 784e6c5..6bb246b 100644
--- a/core/api/src/main/java/org/onosproject/net/driver/AbstractBehaviour.java
+++ b/core/api/src/main/java/org/onosproject/net/driver/AbstractBehaviour.java
@@ -18,7 +18,7 @@
 import static com.google.common.base.Preconditions.checkState;
 
 /**
- * Base implementation of device driver behaviour.
+ * Base implementation of a driver behaviour.
  */
 public class AbstractBehaviour implements Behaviour {
 
diff --git a/core/api/src/main/java/org/onosproject/net/driver/AbstractHandlerBehaviour.java b/core/api/src/main/java/org/onosproject/net/driver/AbstractHandlerBehaviour.java
index 66b21ff..2ba8f87 100644
--- a/core/api/src/main/java/org/onosproject/net/driver/AbstractHandlerBehaviour.java
+++ b/core/api/src/main/java/org/onosproject/net/driver/AbstractHandlerBehaviour.java
@@ -18,7 +18,7 @@
 import static com.google.common.base.Preconditions.checkState;
 
 /**
- * Base implementation of device driver handler behaviour.
+ * Base implementation of a driver handler behaviour.
  */
 public class AbstractHandlerBehaviour
         extends AbstractBehaviour implements HandlerBehaviour {
diff --git a/core/api/src/main/java/org/onosproject/net/driver/Behaviour.java b/core/api/src/main/java/org/onosproject/net/driver/Behaviour.java
index 6e28aa8..49a984e 100644
--- a/core/api/src/main/java/org/onosproject/net/driver/Behaviour.java
+++ b/core/api/src/main/java/org/onosproject/net/driver/Behaviour.java
@@ -16,8 +16,8 @@
 package org.onosproject.net.driver;
 
 /**
- * Representation of a facet of device behaviour that can be used to talk about
- * a device (in context of {@link DriverData}) or to a device (in context of
+ * Representation of a facet of behaviour that can be used to talk about
+ * an entity (in context of {@link DriverData}) or to an entity (in context of
  * {@link DriverHandler}).
  */
 public interface Behaviour {
diff --git a/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverData.java b/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverData.java
index 76d7932..3ea3bb9 100644
--- a/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverData.java
+++ b/core/api/src/main/java/org/onosproject/net/driver/DefaultDriverData.java
@@ -57,11 +57,6 @@
     }
 
     @Override
-    public <T extends Behaviour> T behaviour(Class<T> behaviourClass) {
-        return driver.createBehaviour(this, behaviourClass);
-    }
-
-    @Override
     public MutableAnnotations set(String key, String value) {
         properties.put(key, value);
         return this;
diff --git a/core/api/src/main/java/org/onosproject/net/driver/DriverData.java b/core/api/src/main/java/org/onosproject/net/driver/DriverData.java
index 64f1fd9..8f0eb97 100644
--- a/core/api/src/main/java/org/onosproject/net/driver/DriverData.java
+++ b/core/api/src/main/java/org/onosproject/net/driver/DriverData.java
@@ -19,7 +19,7 @@
 import org.onosproject.net.MutableAnnotations;
 
 /**
- * Container for data about a device. Data is stored using
+ * Container for data about an entity, e.g. device, link. Data is stored using
  * {@link org.onosproject.net.MutableAnnotations}.
  *
  * Note that only derivatives of {@link HandlerBehaviour} can expect mutability
@@ -45,10 +45,15 @@
     /**
      * Returns the specified facet of behaviour to access the device data.
      *
+     * Implementations are expected to defer to the backing driver for creation
+     * of the requested behaviour.
+     *
      * @param behaviourClass behaviour class
      * @param <T>            type of behaviour
      * @return requested behaviour or null if not supported
      */
-    <T extends Behaviour> T behaviour(Class<T> behaviourClass);
+    default <T extends Behaviour> T behaviour(Class<T> behaviourClass) {
+        return driver().createBehaviour(this, behaviourClass);
+    }
 
 }
diff --git a/core/api/src/main/java/org/onosproject/net/driver/HandlerBehaviour.java b/core/api/src/main/java/org/onosproject/net/driver/HandlerBehaviour.java
index b5771ac..c3bff33 100644
--- a/core/api/src/main/java/org/onosproject/net/driver/HandlerBehaviour.java
+++ b/core/api/src/main/java/org/onosproject/net/driver/HandlerBehaviour.java
@@ -16,8 +16,8 @@
 package org.onosproject.net.driver;
 
 /**
- * Representation of a facet of device behaviour that can be used to interact
- * with a device (in context of {@link org.onosproject.net.driver.DriverHandler}).
+ * Representation of a facet of behaviour that can be used to interact
+ * with an entity (in context of {@link org.onosproject.net.driver.DriverHandler}).
  */
 public interface HandlerBehaviour extends Behaviour {
 
diff --git a/core/api/src/main/java/org/onosproject/net/driver/Projectable.java b/core/api/src/main/java/org/onosproject/net/driver/Projectable.java
index 02dce7e..9cff6b4 100644
--- a/core/api/src/main/java/org/onosproject/net/driver/Projectable.java
+++ b/core/api/src/main/java/org/onosproject/net/driver/Projectable.java
@@ -38,7 +38,7 @@
      * Returns true if this entity is capable of being projected as the
      * specified class.
      *
-     * @param projectionClass projection class
+     * @param projectionClass requested projection class
      * @param <B> type of behaviour
      * @return true if the requested projection is supported
      */
diff --git a/core/api/src/main/java/org/onosproject/net/driver/package-info.java b/core/api/src/main/java/org/onosproject/net/driver/package-info.java
index fbc39a8..8306dfa 100644
--- a/core/api/src/main/java/org/onosproject/net/driver/package-info.java
+++ b/core/api/src/main/java/org/onosproject/net/driver/package-info.java
@@ -16,21 +16,23 @@
 
 /**
  * Set of facilities to allow the platform to be extended with
- * device specific behaviours and to allow modeling device behaviours while
- * hiding details of specific device driver implementations.
+ * device specific behaviours and to allow modeling device (and other entity)
+ * behaviours while hiding details of specific driver implementations.
+ * While primarily intended for devices, this subsystem can be used to abstract
+ * behaviours of other entities as well.
  * <p>
  * {@link org.onosproject.net.driver.Driver} is a representation of a
- * specific family of devices supports set of
+ * specific family of entities (devices, links, etc.) which supports set of
  * {@link org.onosproject.net.driver.Behaviour behaviour classes}. Default
  * implementation is provided by the platform and allows DriverProviders to
  * add different behaviour implementations via DriverService.
  * </p>
  * <p>
  * {@link org.onosproject.net.driver.DriverData} is a container for data
- * learned about a device. It is associated with a specific
+ * learned about an entity. It is associated with a specific
  * {@link org.onosproject.net.driver.Driver}
  * and provides set of {@link org.onosproject.net.driver.Behaviour behaviours}
- * for talking about a device. A default
+ * for talking about an entity. A default
  * implementation provided by platform and has mutable key/value store for use by
  * implementations of {@link org.onosproject.net.driver.Behaviour behaviours}.
  * </p>
diff --git a/core/api/src/test/java/org/onosproject/ui/topo/BiLinkTestBase.java b/core/api/src/test/java/org/onosproject/ui/topo/BiLinkTestBase.java
index bb7fc65..420ea7a 100644
--- a/core/api/src/test/java/org/onosproject/ui/topo/BiLinkTestBase.java
+++ b/core/api/src/test/java/org/onosproject/ui/topo/BiLinkTestBase.java
@@ -22,6 +22,7 @@
 import org.onosproject.net.Link;
 import org.onosproject.net.LinkKey;
 import org.onosproject.net.PortNumber;
+import org.onosproject.net.driver.Behaviour;
 import org.onosproject.net.provider.ProviderId;
 
 /**
@@ -63,6 +64,16 @@
         @Override public ProviderId providerId() {
             return null;
         }
+
+        @Override
+        public <B extends Behaviour> B as(Class<B> projectionClass) {
+            return null;
+        }
+
+        @Override
+        public <B extends Behaviour> boolean is(Class<B> projectionClass) {
+            return false;
+        }
     }
 
     protected static final DeviceId DEV_A_ID = DeviceId.deviceId("device-A");
diff --git a/core/api/src/test/java/org/onosproject/ui/topo/NodeSelectionTest.java b/core/api/src/test/java/org/onosproject/ui/topo/NodeSelectionTest.java
index 06a7858..09b088d 100644
--- a/core/api/src/test/java/org/onosproject/ui/topo/NodeSelectionTest.java
+++ b/core/api/src/test/java/org/onosproject/ui/topo/NodeSelectionTest.java
@@ -19,24 +19,18 @@
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableSet;
 import org.junit.Test;
-import org.onlab.packet.ChassisId;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onosproject.net.Annotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultHost;
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Host;
 import org.onosproject.net.HostId;
-import org.onosproject.net.HostLocation;
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.device.DeviceServiceAdapter;
 import org.onosproject.net.host.HostService;
 import org.onosproject.net.host.HostServiceAdapter;
-import org.onosproject.net.provider.ProviderId;
-
-import java.util.Set;
 
 import static org.junit.Assert.*;
 
@@ -45,106 +39,18 @@
  */
 public class NodeSelectionTest {
 
-    private static class FakeDevice implements Device {
-
-        private final DeviceId id;
-
+    private static class FakeDevice extends DefaultDevice {
         FakeDevice(DeviceId id) {
-            this.id = id;
-        }
-
-        @Override
-        public DeviceId id() {
-            return id;
-        }
-
-        @Override
-        public Type type() {
-            return null;
-        }
-
-        @Override
-        public String manufacturer() {
-            return null;
-        }
-
-        @Override
-        public String hwVersion() {
-            return null;
-        }
-
-        @Override
-        public String swVersion() {
-            return null;
-        }
-
-        @Override
-        public String serialNumber() {
-            return null;
-        }
-
-        @Override
-        public ChassisId chassisId() {
-            return null;
-        }
-
-        @Override
-        public Annotations annotations() {
-            return null;
-        }
-
-        @Override
-        public ProviderId providerId() {
-            return null;
+            super(null, id, null, null, null, null, null, null);
         }
     }
 
-    private static class FakeHost implements Host {
-
-        private final HostId id;
-
+    private static class FakeHost extends DefaultHost {
         FakeHost(HostId id) {
-            this.id = id;
-        }
-
-        @Override
-        public HostId id() {
-            return id;
-        }
-
-        @Override
-        public MacAddress mac() {
-            return null;
-        }
-
-        @Override
-        public VlanId vlan() {
-            return null;
-        }
-
-        @Override
-        public Set<IpAddress> ipAddresses() {
-            return null;
-        }
-
-        @Override
-        public HostLocation location() {
-            return null;
-        }
-
-        @Override
-        public Annotations annotations() {
-            return null;
-        }
-
-        @Override
-        public ProviderId providerId() {
-            return null;
+            super(null, id, null, null, null, ImmutableSet.of());
         }
     }
 
-
-
     private final ObjectMapper mapper = new ObjectMapper();
 
     private static final String IDS = "ids";
diff --git a/core/common/src/main/java/org/onosproject/codec/impl/PortCodec.java b/core/common/src/main/java/org/onosproject/codec/impl/PortCodec.java
index c6f2ac7..ef865cc 100644
--- a/core/common/src/main/java/org/onosproject/codec/impl/PortCodec.java
+++ b/core/common/src/main/java/org/onosproject/codec/impl/PortCodec.java
@@ -21,6 +21,7 @@
 import org.onosproject.codec.CodecContext;
 import org.onosproject.net.Annotations;
 import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
 import org.onosproject.net.DefaultPort;
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
@@ -99,62 +100,16 @@
     /**
      * Dummy Device which only holds DeviceId.
      */
-    private static final class DummyDevice implements Device {
-
-        private final DeviceId did;
-
+    private static final class DummyDevice extends DefaultDevice {
         /**
          * Constructs Dummy Device which only holds DeviceId.
          *
          * @param did device Id
          */
         public DummyDevice(DeviceId did) {
-            this.did = did;
-        }
-
-        @Override
-        public Annotations annotations() {
-            return DefaultAnnotations.EMPTY;
-        }
-
-        @Override
-        public ProviderId providerId() {
-            return new ProviderId(did.uri().getScheme(), "PortCodec");
-        }
-
-        @Override
-        public DeviceId id() {
-            return did;
-        }
-
-        @Override
-        public Type type() {
-            return Type.SWITCH;
-        }
-
-        @Override
-        public String manufacturer() {
-            return "dummy";
-        }
-
-        @Override
-        public String hwVersion() {
-            return "0";
-        }
-
-        @Override
-        public String swVersion() {
-            return "0";
-        }
-
-        @Override
-        public String serialNumber() {
-            return "0";
-        }
-
-        @Override
-        public ChassisId chassisId() {
-            return new ChassisId();
+            super(new ProviderId(did.uri().getScheme(), "PortCodec"), did,
+                  Type.SWITCH, "dummy", "0", "0", "0", new ChassisId(),
+                  DefaultAnnotations.EMPTY);
         }
     }
 }
diff --git a/core/net/src/main/java/org/onosproject/net/driver/impl/DriverManager.java b/core/net/src/main/java/org/onosproject/net/driver/impl/DriverManager.java
index 72492db..53a9a68 100644
--- a/core/net/src/main/java/org/onosproject/net/driver/impl/DriverManager.java
+++ b/core/net/src/main/java/org/onosproject/net/driver/impl/DriverManager.java
@@ -25,6 +25,7 @@
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
 import org.onlab.util.ItemNotFoundException;
+import org.onosproject.net.AbstractProjectableModel;
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.device.DeviceService;
@@ -72,15 +73,16 @@
 
     @Activate
     protected void activate() {
+        AbstractProjectableModel.setDriverService(null, this);
         log.info("Started");
     }
 
     @Deactivate
     protected void deactivate() {
+        AbstractProjectableModel.setDriverService(this, null);
         log.info("Stopped");
     }
 
-
     @Override
     public Set<DriverProvider> getProviders() {
         return ImmutableSet.copyOf(providers);