Working on model annotations; still in progress.
diff --git a/core/api/src/main/java/org/onlab/onos/net/AbstractAnnotated.java b/core/api/src/main/java/org/onlab/onos/net/AbstractAnnotated.java
new file mode 100644
index 0000000..f3c4b86
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/AbstractAnnotated.java
@@ -0,0 +1,45 @@
+package org.onlab.onos.net;
+
+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;
+
+/**
+ * Base abstraction of an annotated entity.
+ */
+public class AbstractAnnotated implements Annotated {
+
+    private static final Map<String, String> EMPTY = new HashMap<>();
+
+    private final Map<String, String> annotations;
+
+    // For serialization
+    protected AbstractAnnotated() {
+        this.annotations = EMPTY;
+    }
+
+    /**
+     * Creates a new entity, annotated with the specified annotations.
+     *
+     * @param annotations optional key/value annotations map
+     */
+    protected AbstractAnnotated(Map<String, String>[] annotations) {
+        checkArgument(annotations.length <= 1, "Only one set of annotations is expected");
+        this.annotations = annotations.length == 1 ? annotations[0] : EMPTY;
+    }
+
+    @Override
+    public Set<String> annotationKeys() {
+        return ImmutableSet.copyOf(annotations.keySet());
+    }
+
+    @Override
+    public String annotation(String key) {
+        return annotations.get(key);
+    }
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/AbstractModel.java b/core/api/src/main/java/org/onlab/onos/net/AbstractModel.java
index cbafad9..6bdda72 100644
--- a/core/api/src/main/java/org/onlab/onos/net/AbstractModel.java
+++ b/core/api/src/main/java/org/onlab/onos/net/AbstractModel.java
@@ -1,33 +1,32 @@
 package org.onlab.onos.net;
 
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
 import org.onlab.onos.net.provider.ProviderId;
 
 import java.util.Map;
-import java.util.Set;
 
 /**
  * Base implementation of a network model entity.
  */
-public class AbstractModel implements Provided, Annotated {
+public class AbstractModel extends AbstractAnnotated implements Provided {
 
     private final ProviderId providerId;
 
-    // FIXME: figure out whether to make this concurrent or immutable
-    private final Map<String, String> annotations = Maps.newHashMap();
-
     // For serialization
     public AbstractModel() {
         providerId = null;
     }
 
     /**
-     * Creates a model entity attributed to the specified provider.
+     * Creates a model entity attributed to the specified provider and
+     * optionally annotated.
      *
-     * @param providerId identity of the provider
+     * @param providerId  identity of the provider
+     * @param annotations optional key/value annotations
      */
-    protected AbstractModel(ProviderId providerId) {
+    @SafeVarargs
+    protected AbstractModel(ProviderId providerId,
+                            Map<String, String>... annotations) {
+        super(annotations);
         this.providerId = providerId;
     }
 
@@ -36,13 +35,4 @@
         return providerId;
     }
 
-    @Override
-    public Set<String> annotationKeys() {
-        return ImmutableSet.copyOf(annotations.keySet());
-    }
-
-    @Override
-    public String annotation(String key) {
-        return annotations.get(key);
-    }
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/Description.java b/core/api/src/main/java/org/onlab/onos/net/Description.java
index 38338c1..8b5464b 100644
--- a/core/api/src/main/java/org/onlab/onos/net/Description.java
+++ b/core/api/src/main/java/org/onlab/onos/net/Description.java
@@ -3,5 +3,5 @@
 /**
  * Base abstraction of a piece of information about network elements.
  */
-public interface Description {
+public interface Description extends Annotated {
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/device/DefaultDeviceDescription.java b/core/api/src/main/java/org/onlab/onos/net/device/DefaultDeviceDescription.java
index 833625d..f5bc0d6 100644
--- a/core/api/src/main/java/org/onlab/onos/net/device/DefaultDeviceDescription.java
+++ b/core/api/src/main/java/org/onlab/onos/net/device/DefaultDeviceDescription.java
@@ -1,6 +1,9 @@
 package org.onlab.onos.net.device;
 
+import org.onlab.onos.net.AbstractAnnotated;
+
 import java.net.URI;
+import java.util.Map;
 
 import static com.google.common.base.MoreObjects.toStringHelper;
 import static com.google.common.base.Preconditions.checkNotNull;
@@ -9,7 +12,8 @@
 /**
  * Default implementation of immutable device description entity.
  */
-public class DefaultDeviceDescription implements DeviceDescription {
+public class DefaultDeviceDescription extends AbstractAnnotated
+        implements DeviceDescription {
     private final URI uri;
     private final Type type;
     private final String manufacturer;
@@ -26,10 +30,14 @@
      * @param hwVersion    device HW version
      * @param swVersion    device SW version
      * @param serialNumber device serial number
+     * @param annotations  optional key/value annotations map
      */
+    @SafeVarargs
     public DefaultDeviceDescription(URI uri, Type type, String manufacturer,
                                     String hwVersion, String swVersion,
-                                    String serialNumber) {
+                                    String serialNumber,
+                                    Map<String, String>... annotations) {
+        super(annotations);
         this.uri = checkNotNull(uri, "Device URI cannot be null");
         this.type = checkNotNull(type, "Device type cannot be null");
         this.manufacturer = manufacturer;
diff --git a/core/api/src/main/java/org/onlab/onos/net/host/DefaultHostDescription.java b/core/api/src/main/java/org/onlab/onos/net/host/DefaultHostDescription.java
index 0a419fd..6190183 100644
--- a/core/api/src/main/java/org/onlab/onos/net/host/DefaultHostDescription.java
+++ b/core/api/src/main/java/org/onlab/onos/net/host/DefaultHostDescription.java
@@ -1,38 +1,62 @@
 package org.onlab.onos.net.host;
 
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-import java.util.HashSet;
-import java.util.Set;
-
+import com.google.common.collect.ImmutableSet;
+import org.onlab.onos.net.AbstractAnnotated;
 import org.onlab.onos.net.HostLocation;
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 
-import com.google.common.collect.ImmutableSet;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
 
-public class DefaultHostDescription implements HostDescription {
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Default implementation of an immutable host description.
+ */
+public class DefaultHostDescription extends AbstractAnnotated
+        implements HostDescription {
 
     private final MacAddress mac;
     private final VlanId vlan;
     private final HostLocation location;
     private final Set<IpPrefix> ips;
 
+    /**
+     * Creates a host description using the supplied information.
+     *
+     * @param mac         host MAC address
+     * @param vlan        host VLAN identifier
+     * @param location    host location
+     * @param annotations optional key/value annotations map
+     */
+    @SafeVarargs
     public DefaultHostDescription(MacAddress mac, VlanId vlan,
-            HostLocation loc) {
-        this.mac = mac;
-        this.vlan = vlan;
-        this.location = loc;
-        this.ips = new HashSet<IpPrefix>();
+                                  HostLocation location,
+                                  Map<String, String>... annotations) {
+        this(mac, vlan, location, new HashSet<IpPrefix>(), annotations);
     }
 
+    /**
+     * Creates a host description using the supplied information.
+     *
+     * @param mac         host MAC address
+     * @param vlan        host VLAN identifier
+     * @param location    host location
+     * @param ips         of host IP addresses
+     * @param annotations optional key/value annotations map
+     */
+    @SafeVarargs
     public DefaultHostDescription(MacAddress mac, VlanId vlan,
-            HostLocation loc, Set<IpPrefix> ips) {
+                                  HostLocation location, Set<IpPrefix> ips,
+                                  Map<String, String>... annotations) {
+        super(annotations);
         this.mac = mac;
         this.vlan = vlan;
-        this.location = loc;
-        this.ips = new HashSet<IpPrefix>(ips);
+        this.location = location;
+        this.ips = new HashSet<>(ips);
     }
 
     @Override
diff --git a/core/api/src/main/java/org/onlab/onos/net/topology/DefaultGraphDescription.java b/core/api/src/main/java/org/onlab/onos/net/topology/DefaultGraphDescription.java
index 94a6abf..1369fda 100644
--- a/core/api/src/main/java/org/onlab/onos/net/topology/DefaultGraphDescription.java
+++ b/core/api/src/main/java/org/onlab/onos/net/topology/DefaultGraphDescription.java
@@ -2,6 +2,7 @@
 
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Maps;
+import org.onlab.onos.net.AbstractAnnotated;
 import org.onlab.onos.net.ConnectPoint;
 import org.onlab.onos.net.Device;
 import org.onlab.onos.net.DeviceId;
@@ -12,7 +13,8 @@
 /**
  * Default implementation of an immutable topology graph data carrier.
  */
-public class DefaultGraphDescription implements GraphDescription {
+public class DefaultGraphDescription extends AbstractAnnotated
+        implements GraphDescription {
 
     private final long nanos;
     private final ImmutableSet<TopologyVertex> vertexes;
@@ -25,11 +27,16 @@
      * Creates a minimal topology graph description to allow core to construct
      * and process the topology graph.
      *
-     * @param nanos   time in nanos of when the topology description was created
-     * @param devices collection of infrastructure devices
-     * @param links   collection of infrastructure links
+     * @param nanos       time in nanos of when the topology description was created
+     * @param devices     collection of infrastructure devices
+     * @param links       collection of infrastructure links
+     * @param annotations optional key/value annotations map
      */
-    public DefaultGraphDescription(long nanos, Iterable<Device> devices, Iterable<Link> links) {
+    @SafeVarargs
+    public DefaultGraphDescription(long nanos, Iterable<Device> devices,
+                                   Iterable<Link> links,
+                                   Map<String, String>... annotations) {
+        super(annotations);
         this.nanos = nanos;
         this.vertexes = buildVertexes(devices);
         this.edges = buildEdges(links);