Added Port.Type and plumbed it throughout.
diff --git a/core/api/src/main/java/org/onlab/onos/net/DefaultPort.java b/core/api/src/main/java/org/onlab/onos/net/DefaultPort.java
index 9d4f8a8..d9cd764 100644
--- a/core/api/src/main/java/org/onlab/onos/net/DefaultPort.java
+++ b/core/api/src/main/java/org/onlab/onos/net/DefaultPort.java
@@ -24,9 +24,14 @@
  */
 public class DefaultPort extends AbstractAnnotated implements Port {
 
+    /** Default port speed in Mbps. */
+    public static final long DEFAULT_SPEED = 1_000;
+
     private final Element element;
     private final PortNumber number;
     private final boolean isEnabled;
+    private final Type type;
+    private final long portSpeed;
 
     /**
      * Creates a network element attributed to the specified provider.
@@ -36,40 +41,35 @@
      * @param isEnabled   indicator whether the port is up and active
      * @param annotations optional key/value annotations
      */
-    public DefaultPort(Element element, PortNumber number,
-                       boolean isEnabled, Annotations... annotations) {
+    public DefaultPort(Element element, PortNumber number, boolean isEnabled,
+                       Annotations... annotations) {
+        this(element, number, isEnabled, Type.COPPER, DEFAULT_SPEED, annotations);
+    }
+
+    /**
+     * Creates a network element attributed to the specified provider.
+     *
+     * @param element     parent network element
+     * @param number      port number
+     * @param isEnabled   indicator whether the port is up and active
+     * @param type        port type
+     * @param portSpeed   port speed in Mbs
+     * @param annotations optional key/value annotations
+     */
+    public DefaultPort(Element element, PortNumber number, boolean isEnabled,
+                       Type type, long portSpeed, Annotations... annotations) {
         super(annotations);
         this.element = element;
         this.number = number;
         this.isEnabled = isEnabled;
+        this.type = type;
+        this.portSpeed = portSpeed;
+
     }
 
     @Override
-    public int hashCode() {
-        return Objects.hash(number, isEnabled);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof DefaultPort) {
-            final DefaultPort other = (DefaultPort) obj;
-            return Objects.equals(this.element.id(), other.element.id()) &&
-                    Objects.equals(this.number, other.number) &&
-                    Objects.equals(this.isEnabled, other.isEnabled);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return toStringHelper(this)
-                .add("element", element.id())
-                .add("number", number)
-                .add("isEnabled", isEnabled)
-                .toString();
+    public Element element() {
+        return element;
     }
 
     @Override
@@ -83,8 +83,45 @@
     }
 
     @Override
-    public Element element() {
-        return element;
+    public Type type() {
+        return type;
+    }
+
+    @Override
+    public long portSpeed() {
+        return portSpeed;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(number, isEnabled, type, portSpeed);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultPort) {
+            final DefaultPort other = (DefaultPort) obj;
+            return Objects.equals(this.element.id(), other.element.id()) &&
+                    Objects.equals(this.number, other.number) &&
+                    Objects.equals(this.isEnabled, other.isEnabled) &&
+                    Objects.equals(this.type, other.type) &&
+                    Objects.equals(this.portSpeed, other.portSpeed);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("element", element.id())
+                .add("number", number)
+                .add("isEnabled", isEnabled)
+                .add("type", type)
+                .add("portSpeed", portSpeed)
+                .toString();
     }
 
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/Port.java b/core/api/src/main/java/org/onlab/onos/net/Port.java
index 7bf6af3..2153593 100644
--- a/core/api/src/main/java/org/onlab/onos/net/Port.java
+++ b/core/api/src/main/java/org/onlab/onos/net/Port.java
@@ -21,6 +21,26 @@
  */
 public interface Port extends Annotated {
 
+    /** Represents coarse port type classification. */
+    public enum Type {
+        /**
+         * Signifies copper-based connectivity.
+         */
+        COPPER,
+
+        /**
+         * Signifies optical fiber-based connectivity.
+         */
+        FIBER
+    }
+
+    /**
+     * Returns the parent network element to which this port belongs.
+     *
+     * @return parent network element
+     */
+    Element element();
+
     /**
      * Returns the port number.
      *
@@ -36,12 +56,18 @@
     boolean isEnabled();
 
     /**
-     * Returns the parent network element to which this port belongs.
+     * Returns the port type.
      *
-     * @return parent network element
+     * @return port type
      */
-    Element element();
+    Type type();
 
-    // set of port attributes
+    /**
+     * Returns the current port speed in Mbps.
+     *
+     * @return current port speed
+     */
+    long portSpeed();
 
+    // TODO: more attributes?
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/device/DefaultPortDescription.java b/core/api/src/main/java/org/onlab/onos/net/device/DefaultPortDescription.java
index 47e3280..9688827 100644
--- a/core/api/src/main/java/org/onlab/onos/net/device/DefaultPortDescription.java
+++ b/core/api/src/main/java/org/onlab/onos/net/device/DefaultPortDescription.java
@@ -15,11 +15,12 @@
  */
 package org.onlab.onos.net.device;
 
+import com.google.common.base.MoreObjects;
 import org.onlab.onos.net.AbstractDescription;
 import org.onlab.onos.net.PortNumber;
 import org.onlab.onos.net.SparseAnnotations;
 
-import com.google.common.base.MoreObjects;
+import static org.onlab.onos.net.Port.Type;
 
 /**
  * Default implementation of immutable port description.
@@ -27,32 +28,62 @@
 public class DefaultPortDescription extends AbstractDescription
         implements PortDescription {
 
+    private static final long DEFAULT_SPEED = 1_000;
+
     private final PortNumber number;
     private final boolean isEnabled;
+    private final Type type;
+    private final long portSpeed;
 
     /**
      * Creates a port description using the supplied information.
      *
-     * @param number       port number
-     * @param isEnabled    port enabled state
-     * @param annotations  optional key/value annotations map
+     * @param number      port number
+     * @param isEnabled   port enabled state
+     * @param annotations optional key/value annotations map
      */
     public DefaultPortDescription(PortNumber number, boolean isEnabled,
-                SparseAnnotations... annotations) {
-        super(annotations);
-        this.number = number;
-        this.isEnabled = isEnabled;
+                                  SparseAnnotations... annotations) {
+        this(number, isEnabled, Type.COPPER, DEFAULT_SPEED, annotations);
     }
 
     /**
      * Creates a port description using the supplied information.
      *
-     * @param base         PortDescription to get basic information from
-     * @param annotations  optional key/value annotations map
+     * @param number      port number
+     * @param isEnabled   port enabled state
+     * @param type        port type
+     * @param portSpeed   port speed in Mbps
+     * @param annotations optional key/value annotations map
+     */
+    public DefaultPortDescription(PortNumber number, boolean isEnabled,
+                                  Type type, long portSpeed,
+                                  SparseAnnotations...annotations) {
+        super(annotations);
+        this.number = number;
+        this.isEnabled = isEnabled;
+        this.type = type;
+        this.portSpeed = portSpeed;
+    }
+
+    // Default constructor for serialization
+    private DefaultPortDescription() {
+        this.number = null;
+        this.isEnabled = false;
+        this.portSpeed = DEFAULT_SPEED;
+        this.type = Type.COPPER;
+    }
+
+    /**
+     * Creates a port description using the supplied information.
+     *
+     * @param base        PortDescription to get basic information from
+     * @param annotations optional key/value annotations map
      */
     public DefaultPortDescription(PortDescription base,
-            SparseAnnotations annotations) {
-        this(base.portNumber(), base.isEnabled(), annotations);
+                                  SparseAnnotations annotations) {
+        this(base.portNumber(), base.isEnabled(), base.type(), base.portSpeed(),
+             annotations);
     }
 
     @Override
@@ -66,17 +97,24 @@
     }
 
     @Override
+    public Type type() {
+        return type;
+    }
+
+    @Override
+    public long portSpeed() {
+        return portSpeed;
+    }
+
+    @Override
     public String toString() {
         return MoreObjects.toStringHelper(getClass())
                 .add("number", number)
                 .add("isEnabled", isEnabled)
+                .add("type", type)
+                .add("portSpeed", portSpeed)
                 .add("annotations", annotations())
                 .toString();
     }
 
-    // default constructor for serialization
-    private DefaultPortDescription() {
-        this.number = null;
-        this.isEnabled = false;
-    }
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/device/PortDescription.java b/core/api/src/main/java/org/onlab/onos/net/device/PortDescription.java
index cdee005..b134d83 100644
--- a/core/api/src/main/java/org/onlab/onos/net/device/PortDescription.java
+++ b/core/api/src/main/java/org/onlab/onos/net/device/PortDescription.java
@@ -18,13 +18,13 @@
 import org.onlab.onos.net.Description;
 import org.onlab.onos.net.PortNumber;
 
+import static org.onlab.onos.net.Port.Type;
+
 /**
  * Information about a port.
  */
 public interface PortDescription extends Description {
 
-    // TODO: possibly relocate this to a common ground so that this can also used by host tracking if required
-
     /**
      * Returns the port number.
      *
@@ -39,4 +39,18 @@
      */
     boolean isEnabled();
 
+    /**
+     * Returns the port type.
+     *
+     * @return port type
+     */
+    Type type();
+
+    /**
+     * Returns the current port speed in Mbps.
+     *
+     * @return current port speed
+     */
+    long portSpeed();
+
 }
diff --git a/core/api/src/test/java/org/onlab/onos/net/DefaultPortTest.java b/core/api/src/test/java/org/onlab/onos/net/DefaultPortTest.java
index 3d3d3d3..ebc3107 100644
--- a/core/api/src/test/java/org/onlab/onos/net/DefaultPortTest.java
+++ b/core/api/src/test/java/org/onlab/onos/net/DefaultPortTest.java
@@ -23,6 +23,8 @@
 import static org.junit.Assert.assertEquals;
 import static org.onlab.onos.net.Device.Type.SWITCH;
 import static org.onlab.onos.net.DeviceId.deviceId;
+import static org.onlab.onos.net.Port.Type.COPPER;
+import static org.onlab.onos.net.Port.Type.FIBER;
 import static org.onlab.onos.net.PortNumber.portNumber;
 
 /**
@@ -35,15 +37,16 @@
     private static final DeviceId DID2 = deviceId("of:bar");
     private static final PortNumber P1 = portNumber(1);
     private static final PortNumber P2 = portNumber(2);
+    private static final long SP1 = 1_000_000;
 
     @Test
     public void testEquality() {
         Device device = new DefaultDevice(PID, DID1, SWITCH, "m", "h", "s", "n",
                                           new ChassisId());
-        Port p1 = new DefaultPort(device, portNumber(1), true);
-        Port p2 = new DefaultPort(device, portNumber(1), true);
-        Port p3 = new DefaultPort(device, portNumber(2), true);
-        Port p4 = new DefaultPort(device, portNumber(2), true);
+        Port p1 = new DefaultPort(device, portNumber(1), true, COPPER, SP1);
+        Port p2 = new DefaultPort(device, portNumber(1), true, COPPER, SP1);
+        Port p3 = new DefaultPort(device, portNumber(2), true, FIBER, SP1);
+        Port p4 = new DefaultPort(device, portNumber(2), true, FIBER, SP1);
         Port p5 = new DefaultPort(device, portNumber(1), false);
 
         new EqualsTester().addEqualityGroup(p1, p2)
@@ -56,10 +59,12 @@
     public void basics() {
         Device device = new DefaultDevice(PID, DID1, SWITCH, "m", "h", "s", "n",
                                           new ChassisId());
-        Port port = new DefaultPort(device, portNumber(1), true);
+        Port port = new DefaultPort(device, portNumber(1), true, FIBER, SP1);
         assertEquals("incorrect element", device, port.element());
         assertEquals("incorrect number", portNumber(1), port.number());
         assertEquals("incorrect state", true, port.isEnabled());
+        assertEquals("incorrect speed", SP1, port.portSpeed());
+        assertEquals("incorrect type", FIBER, port.type());
     }
 
 }
diff --git a/core/net/src/main/java/org/onlab/onos/net/device/impl/DeviceManager.java b/core/net/src/main/java/org/onlab/onos/net/device/impl/DeviceManager.java
index e163dc5..7759550 100644
--- a/core/net/src/main/java/org/onlab/onos/net/device/impl/DeviceManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/device/impl/DeviceManager.java
@@ -67,8 +67,8 @@
 @Component(immediate = true)
 @Service
 public class DeviceManager
-    extends AbstractProviderRegistry<DeviceProvider, DeviceProviderService>
-    implements DeviceService, DeviceAdminService, DeviceProviderRegistry {
+        extends AbstractProviderRegistry<DeviceProvider, DeviceProviderService>
+        implements DeviceService, DeviceAdminService, DeviceProviderRegistry {
 
     private static final String DEVICE_ID_NULL = "Device ID cannot be null";
     private static final String PORT_NUMBER_NULL = "Port number cannot be null";
@@ -227,8 +227,8 @@
 
     // Personalized device provider service issued to the supplied provider.
     private class InternalDeviceProviderService
-    extends AbstractProviderService<DeviceProvider>
-    implements DeviceProviderService {
+            extends AbstractProviderService<DeviceProvider>
+            implements DeviceProviderService {
 
         InternalDeviceProviderService(DeviceProvider provider) {
             super(provider);
@@ -236,7 +236,7 @@
 
         @Override
         public void deviceConnected(DeviceId deviceId,
-                DeviceDescription deviceDescription) {
+                                    DeviceDescription deviceDescription) {
             checkNotNull(deviceId, DEVICE_ID_NULL);
             checkNotNull(deviceDescription, DEVICE_DESCRIPTION_NULL);
             checkValidity();
@@ -267,7 +267,7 @@
             deviceClockProviderService.setMastershipTerm(deviceId, term);
 
             DeviceEvent event = store.createOrUpdateDevice(provider().id(),
-                    deviceId, deviceDescription);
+                                                           deviceId, deviceDescription);
 
             // If there was a change of any kind, tell the provider
             // that this instance is the master.
@@ -337,14 +337,14 @@
 
         @Override
         public void updatePorts(DeviceId deviceId,
-                List<PortDescription> portDescriptions) {
+                                List<PortDescription> portDescriptions) {
             checkNotNull(deviceId, DEVICE_ID_NULL);
             checkNotNull(portDescriptions,
-                    "Port descriptions list cannot be null");
+                         "Port descriptions list cannot be null");
             checkValidity();
 
             List<DeviceEvent> events = store.updatePorts(this.provider().id(),
-                    deviceId, portDescriptions);
+                                                         deviceId, portDescriptions);
             for (DeviceEvent event : events) {
                 post(event);
             }
@@ -352,13 +352,13 @@
 
         @Override
         public void portStatusChanged(DeviceId deviceId,
-                PortDescription portDescription) {
+                                      PortDescription portDescription) {
             checkNotNull(deviceId, DEVICE_ID_NULL);
             checkNotNull(portDescription, PORT_DESCRIPTION_NULL);
             checkValidity();
 
             final DeviceEvent event = store.updatePortStatus(this.provider().id(),
-                        deviceId, portDescription);
+                                                             deviceId, portDescription);
             if (event != null) {
                 log.info("Device {} port {} status changed", deviceId, event
                         .port().number());
@@ -370,7 +370,7 @@
         public void unableToAssertRole(DeviceId deviceId, MastershipRole role) {
             // FIXME: implement response to this notification
             log.warn("Failed to assert role [{}] onto Device {}", role,
-                    deviceId);
+                     deviceId);
             if (role == MastershipRole.MASTER) {
                 mastershipService.relinquishMastership(deviceId);
                 // TODO: Shouldn't we be triggering event?
@@ -393,7 +393,7 @@
         // random cache size
         private final int cacheSize = 5;
         // temporarily stores term number + events to check for duplicates. A hack.
-        private HashMultimap<Integer, RoleInfo>  eventCache =
+        private HashMultimap<Integer, RoleInfo> eventCache =
                 HashMultimap.create();
 
         @Override
@@ -414,7 +414,7 @@
                 if (!myNodeId.equals(term.master())) {
                     // something went wrong in consistency, let go
                     log.warn("Mastership has changed after this event."
-                            + "Term Service suggests {} for {}", term, did);
+                                     + "Term Service suggests {} for {}", term, did);
                     // FIXME: Is it possible to let go of MASTER role
                     //        but remain on STANDBY list?
                     mastershipService.relinquishMastership(did);
@@ -435,11 +435,12 @@
                         return;
                     }
                     //flag the device as online. Is there a better way to do this?
-                    DeviceEvent devEvent = store.createOrUpdateDevice(device.providerId(), did,
-                            new DefaultDeviceDescription(
-                                    did.uri(), device.type(), device.manufacturer(),
-                                    device.hwVersion(), device.swVersion(),
-                                    device.serialNumber(), device.chassisId()));
+                    DeviceEvent devEvent =
+                            store.createOrUpdateDevice(device.providerId(), did,
+                                                       new DefaultDeviceDescription(
+                                                               did.uri(), device.type(), device.manufacturer(),
+                                                               device.hwVersion(), device.swVersion(),
+                                                               device.serialNumber(), device.chassisId()));
                     post(devEvent);
                 }
                 applyRole(did, MastershipRole.MASTER);
@@ -476,7 +477,7 @@
 
     // Store delegate to re-post events emitted from the store.
     private class InternalStoreDelegate
-    implements DeviceStoreDelegate {
+            implements DeviceStoreDelegate {
         @Override
         public void notify(DeviceEvent event) {
             post(event);
diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/device/impl/GossipDeviceStore.java b/core/store/dist/src/main/java/org/onlab/onos/store/device/impl/GossipDeviceStore.java
index f3ae7a4..5449277 100644
--- a/core/store/dist/src/main/java/org/onlab/onos/store/device/impl/GossipDeviceStore.java
+++ b/core/store/dist/src/main/java/org/onlab/onos/store/device/impl/GossipDeviceStore.java
@@ -543,8 +543,9 @@
                                    Port newPort,
                                    Map<PortNumber, Port> ports) {
         if (oldPort.isEnabled() != newPort.isEnabled() ||
-            !AnnotationsUtil.isEqual(oldPort.annotations(), newPort.annotations())) {
-
+                oldPort.type() != newPort.type() ||
+                oldPort.portSpeed() != newPort.portSpeed() ||
+                !AnnotationsUtil.isEqual(oldPort.annotations(), newPort.annotations())) {
             ports.put(oldPort.number(), newPort);
             return new DeviceEvent(PORT_UPDATED, device, newPort);
         }
@@ -867,7 +868,10 @@
             }
         }
 
-        return new DefaultPort(device, number, isEnabled, annotations);
+        return portDesc == null ?
+                new DefaultPort(device, number, false, annotations) :
+                new DefaultPort(device, number, isEnabled, portDesc.value().type(),
+                                portDesc.value().portSpeed(), annotations);
     }
 
     /**
diff --git a/core/store/serializers/src/main/java/org/onlab/onos/store/serializers/KryoNamespaces.java b/core/store/serializers/src/main/java/org/onlab/onos/store/serializers/KryoNamespaces.java
index 4fc88b6..e5f57a8 100644
--- a/core/store/serializers/src/main/java/org/onlab/onos/store/serializers/KryoNamespaces.java
+++ b/core/store/serializers/src/main/java/org/onlab/onos/store/serializers/KryoNamespaces.java
@@ -115,6 +115,7 @@
                     //
                     ControllerNode.State.class,
                     Device.Type.class,
+                    Port.Type.class,
                     ChassisId.class,
                     DefaultAnnotations.class,
                     DefaultControllerNode.class,
diff --git a/core/store/serializers/src/test/java/org/onlab/onos/store/serializers/KryoSerializerTest.java b/core/store/serializers/src/test/java/org/onlab/onos/store/serializers/KryoSerializerTest.java
index 4e7a8e0..a4f098a 100644
--- a/core/store/serializers/src/test/java/org/onlab/onos/store/serializers/KryoSerializerTest.java
+++ b/core/store/serializers/src/test/java/org/onlab/onos/store/serializers/KryoSerializerTest.java
@@ -15,13 +15,10 @@
  */
 package org.onlab.onos.store.serializers;
 
-import static org.junit.Assert.assertEquals;
-import static org.onlab.onos.net.DeviceId.deviceId;
-import static org.onlab.onos.net.PortNumber.portNumber;
-import static java.util.Arrays.asList;
-
-import java.nio.ByteBuffer;
-
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.testing.EqualsTester;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -50,10 +47,12 @@
 import org.onlab.packet.MacAddress;
 import org.onlab.util.KryoNamespace;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.testing.EqualsTester;
+import java.nio.ByteBuffer;
+
+import static java.util.Arrays.asList;
+import static org.junit.Assert.assertEquals;
+import static org.onlab.onos.net.DeviceId.deviceId;
+import static org.onlab.onos.net.PortNumber.portNumber;
 
 public class KryoSerializerTest {
 
diff --git a/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleDeviceStore.java b/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleDeviceStore.java
index a4a47e2..0c7fb0c 100644
--- a/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleDeviceStore.java
+++ b/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleDeviceStore.java
@@ -291,8 +291,9 @@
                                    Port newPort,
                                    Map<PortNumber, Port> ports) {
         if (oldPort.isEnabled() != newPort.isEnabled() ||
+                oldPort.type() != newPort.type() ||
+                oldPort.portSpeed() != newPort.portSpeed() ||
                 !AnnotationsUtil.isEqual(oldPort.annotations(), newPort.annotations())) {
-
             ports.put(oldPort.number(), newPort);
             return new DeviceEvent(PORT_UPDATED, device, newPort);
         }
@@ -510,7 +511,10 @@
             }
         }
 
-        return new DefaultPort(device, number, isEnabled, annotations);
+        return portDesc == null ?
+                new DefaultPort(device, number, false, annotations) :
+                new DefaultPort(device, number, isEnabled, portDesc.type(),
+                                portDesc.portSpeed(), annotations);
     }
 
     /**