Enhanced the CLIs.
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/DeviceIdCompleter.java b/cli/src/main/java/org/onlab/onos/cli/net/DeviceIdCompleter.java
index 2614d51..5d38bca 100644
--- a/cli/src/main/java/org/onlab/onos/cli/net/DeviceIdCompleter.java
+++ b/cli/src/main/java/org/onlab/onos/cli/net/DeviceIdCompleter.java
@@ -24,7 +24,7 @@
         Iterator<Device> it = service.getDevices().iterator();
         SortedSet<String> strings = delegate.getStrings();
         while (it.hasNext()) {
-            strings.add(it.next().id().uri().toString());
+            strings.add(it.next().id().toString());
         }
 
         // Now let the completer do the work for figuring out what to offer.
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/DevicePortsListCommand.java b/cli/src/main/java/org/onlab/onos/cli/net/DevicePortsListCommand.java
index f09e39a..95f23af 100644
--- a/cli/src/main/java/org/onlab/onos/cli/net/DevicePortsListCommand.java
+++ b/cli/src/main/java/org/onlab/onos/cli/net/DevicePortsListCommand.java
@@ -2,10 +2,15 @@
 
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
-import org.onlab.onos.cli.AbstractShellCommand;
+import org.onlab.onos.net.Device;
 import org.onlab.onos.net.Port;
 import org.onlab.onos.net.device.DeviceService;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
 import static org.onlab.onos.net.DeviceId.deviceId;
 
 /**
@@ -13,21 +18,42 @@
  */
 @Command(scope = "onos", name = "ports",
          description = "Lists all ports of a device")
-public class DevicePortsListCommand extends AbstractShellCommand {
+public class DevicePortsListCommand extends DevicesListCommand {
 
-    private static final String FMT = "port=%s, state=%s";
+    private static final String FMT = "  port=%s, state=%s";
 
     @Argument(index = 0, name = "deviceId", description = "Device ID",
-              required = true, multiValued = false)
-    String deviceId = null;
+              required = false, multiValued = false)
+    String uri = null;
+
+    private static final Comparator<Port> PORT_COMPARATOR = new Comparator<Port>() {
+        @Override
+        public int compare(Port p1, Port p2) {
+            long delta = p1.number().toLong() - p2.number().toLong();
+            return delta == 0 ? 0 : (delta < 0 ? -1 : +1);
+        }
+    };
 
     @Override
     protected Object doExecute() throws Exception {
         DeviceService service = getService(DeviceService.class);
-        Iterable<Port> ports = service.getPorts(deviceId(deviceId));
-        for (Port port : ports) {
-            print(FMT, port.number(), port.isEnabled() ? "enabled" : "disabled");
+        if (uri == null) {
+            for (Device device : service.getDevices()) {
+                printDevicePorts(service, device);
+            }
+        } else {
+            printDevicePorts(service, service.getDevice(deviceId(uri)));
         }
         return null;
     }
+
+    private void printDevicePorts(DeviceService service, Device device) {
+        List<Port> ports = new ArrayList<>(service.getPorts(device.id()));
+        Collections.sort(ports, PORT_COMPARATOR);
+        printDevice(device, service.isAvailable(device.id()));
+        for (Port port : ports) {
+            print(FMT, port.number(), port.isEnabled() ? "enabled" : "disabled");
+        }
+    }
+
 }
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/DevicesListCommand.java b/cli/src/main/java/org/onlab/onos/cli/net/DevicesListCommand.java
index c7e2c8c..21bb892 100644
--- a/cli/src/main/java/org/onlab/onos/cli/net/DevicesListCommand.java
+++ b/cli/src/main/java/org/onlab/onos/cli/net/DevicesListCommand.java
@@ -13,14 +13,27 @@
 public class DevicesListCommand extends AbstractShellCommand {
 
     private static final String FMT =
-            "id=%s, type=%s, mfr=%s, hw=%s, sw=%s, serial=%s";
+            "id=%s, available=%s, type=%s, mfr=%s, hw=%s, sw=%s, serial=%s";
 
     @Override
     protected Object doExecute() throws Exception {
-        for (Device device : getService(DeviceService.class).getDevices()) {
-            print(FMT, device.id().uri(), device.type(), device.manufacturer(),
-                  device.hwVersion(), device.swVersion(), device.serialNumber());
+        DeviceService service = getService(DeviceService.class);
+        for (Device device : service.getDevices()) {
+            printDevice(device, service.isAvailable(device.id()));
         }
         return null;
     }
+
+    /**
+     * Prints information about the specified device.
+     *
+     * @param device      infrastructure device
+     * @param isAvailable true of device is available
+     */
+    protected void printDevice(Device device, boolean isAvailable) {
+        print(FMT, device.id(), isAvailable, device.type(),
+              device.manufacturer(), device.hwVersion(), device.swVersion(),
+              device.serialNumber());
+    }
+
 }
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/LinksListCommand.java b/cli/src/main/java/org/onlab/onos/cli/net/LinksListCommand.java
index d94d547..7197361 100644
--- a/cli/src/main/java/org/onlab/onos/cli/net/LinksListCommand.java
+++ b/cli/src/main/java/org/onlab/onos/cli/net/LinksListCommand.java
@@ -27,8 +27,8 @@
         Iterable<Link> links = deviceId != null ?
                 service.getDeviceLinks(deviceId(deviceId)) : service.getLinks();
         for (Link link : links) {
-            print(FMT, link.src().deviceId().uri(), link.src().port(),
-                  link.dst().deviceId().uri(), link.dst().port(), link.type());
+            print(FMT, link.src().deviceId(), link.src().port(),
+                  link.dst().deviceId(), link.dst().port(), link.type());
         }
         return null;
     }
diff --git a/net/api/src/main/java/org/onlab/onos/net/ElementId.java b/net/api/src/main/java/org/onlab/onos/net/ElementId.java
index 73e1f29..e205bb6 100644
--- a/net/api/src/main/java/org/onlab/onos/net/ElementId.java
+++ b/net/api/src/main/java/org/onlab/onos/net/ElementId.java
@@ -3,8 +3,6 @@
 import java.net.URI;
 import java.util.Objects;
 
-import static com.google.common.base.MoreObjects.toStringHelper;
-
 /**
  * Immutable representation of a network element identity.
  */
@@ -47,7 +45,7 @@
 
     @Override
     public String toString() {
-        return toStringHelper(this).add("uri", uri).toString();
+        return uri.toString();
     }
 
 }
diff --git a/net/api/src/main/java/org/onlab/onos/net/device/DeviceService.java b/net/api/src/main/java/org/onlab/onos/net/device/DeviceService.java
index 6c46627..8364935 100644
--- a/net/api/src/main/java/org/onlab/onos/net/device/DeviceService.java
+++ b/net/api/src/main/java/org/onlab/onos/net/device/DeviceService.java
@@ -55,13 +55,22 @@
 
     /**
      * Returns the port with the specified number and hosted by the given device.
-     * @param deviceId device identifier
+     *
+     * @param deviceId   device identifier
      * @param portNumber port number
      * @return device port
      */
     Port getPort(DeviceId deviceId, PortNumber portNumber);
 
     /**
+     * Indicates whether or not the device is presently online and available.
+     *
+     * @param deviceId device identifier
+     * @return true if the device is available
+     */
+    boolean isAvailable(DeviceId deviceId);
+
+    /**
      * Adds the specified device listener.
      *
      * @param listener device listener
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 cfe25f7..e522064 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
@@ -104,6 +104,12 @@
     }
 
     @Override
+    public boolean isAvailable(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+        return store.isAvailable(deviceId);
+    }
+
+    @Override
     public void addListener(DeviceListener listener) {
         listenerRegistry.addListener(listener);
     }
@@ -185,8 +191,10 @@
             checkNotNull(deviceId, DEVICE_ID_NULL);
             checkNotNull(portDescription, PORT_DESCRIPTION_NULL);
             checkValidity();
-            log.info("Device {} port status changed", deviceId);
             DeviceEvent event = store.updatePortStatus(deviceId, portDescription);
+            if (event != null) {
+                log.info("Device {} port status changed", deviceId);
+            }
             post(event);
         }
     }
diff --git a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceStore.java b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceStore.java
index 3c05aba..fdffad2 100644
--- a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceStore.java
+++ b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceStore.java
@@ -271,6 +271,16 @@
     }
 
     /**
+     * Indicates whether the specified device is available/online.
+     *
+     * @param deviceId device identifier
+     * @return true if device is available
+     */
+    boolean isAvailable(DeviceId deviceId) {
+        return availableDevices.contains(deviceId);
+    }
+
+    /**
      * Returns the mastership role determined for this device.
      *
      * @param deviceId device identifier
diff --git a/net/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManagerTest.java b/net/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManagerTest.java
index a6c9414..e5224db 100644
--- a/net/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManagerTest.java
+++ b/net/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManagerTest.java
@@ -104,6 +104,7 @@
         assertNotNull("one device expected", it.next());
         assertFalse("only one device expected", it.hasNext());
         assertEquals("incorrect device count", 1, service.getDeviceCount());
+        assertTrue("device should be available", service.isAvailable(DID1));
     }
 
     @Test
@@ -111,10 +112,12 @@
         connectDevice(DID1, SW1);
         connectDevice(DID2, SW1);
         validateEvents(DEVICE_ADDED, DEVICE_ADDED);
+        assertTrue("device should be available", service.isAvailable(DID1));
 
         // Disconnect
         providerService.deviceDisconnected(DID1);
         assertNotNull("device should not be found", service.getDevice(DID1));
+        assertFalse("device should not be available", service.isAvailable(DID1));
         validateEvents(DEVICE_AVAILABILITY_CHANGED);
 
         // Reconnect
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OpenFlowControllerImpl.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OpenFlowControllerImpl.java
index a58d796..2b1d1da 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OpenFlowControllerImpl.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OpenFlowControllerImpl.java
@@ -1,10 +1,5 @@
 package org.onlab.onos.of.controller.impl;
 
-import java.util.ArrayList;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -21,6 +16,14 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
 @Component(immediate = true)
 @Service
 public class OpenFlowControllerImpl implements OpenFlowController {
@@ -36,11 +39,11 @@
             new ConcurrentHashMap<Dpid, OpenFlowSwitch>();
 
     protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent();
-    protected ArrayList<OpenFlowSwitchListener> ofEventListener =
-            new ArrayList<OpenFlowSwitchListener>();
+    protected Set<OpenFlowSwitchListener> ofEventListener =
+            new HashSet<>();
 
-    protected ArrayList<PacketListener> ofPacketListener =
-            new ArrayList<PacketListener>();
+    protected List<PacketListener> ofPacketListener =
+            new ArrayList<>();
 
     private final Controller ctrl = new Controller();
 
@@ -114,19 +117,19 @@
     @Override
     public void processPacket(Dpid dpid, OFMessage msg) {
         switch (msg.getType()) {
-        case PORT_STATUS:
-            for (OpenFlowSwitchListener l : ofEventListener) {
-                l.portChanged(dpid, (OFPortStatus) msg);
-            }
-            break;
-        case PACKET_IN:
-            for (PacketListener p : ofPacketListener) {
-                //TODO fix me!
-                p.handlePacket(null);
-            }
-            break;
-        default:
-            log.warn("Handling message type {} not yet implemented", msg.getType());
+            case PORT_STATUS:
+                for (OpenFlowSwitchListener l : ofEventListener) {
+                    l.portChanged(dpid, (OFPortStatus) msg);
+                }
+                break;
+            case PACKET_IN:
+                for (PacketListener p : ofPacketListener) {
+                    //TODO fix me!
+                    p.handlePacket(null);
+                }
+                break;
+            default:
+                log.warn("Handling message type {} not yet implemented", msg.getType());
         }
     }
 
@@ -139,7 +142,6 @@
      * Implementation of an OpenFlow Agent which is responsible for
      * keeping track of connected switches and the state in which
      * they are.
-     *
      */
     public class OpenFlowSwitchAgent implements OpenFlowAgent {
 
@@ -150,7 +152,7 @@
         public boolean addConnectedSwitch(Dpid dpid, OpenFlowSwitch sw) {
             if (connectedSwitches.get(dpid) != null) {
                 log.error("Trying to add connectedSwitch but found a previous "
-                        + "value for dpid: {}", dpid);
+                                  + "value for dpid: {}", dpid);
                 return false;
             } else {
                 log.error("Added switch {}", dpid);
@@ -166,18 +168,18 @@
         public boolean validActivation(Dpid dpid) {
             if (connectedSwitches.get(dpid) == null) {
                 log.error("Trying to activate switch but is not in "
-                        + "connected switches: dpid {}. Aborting ..",
-                        dpid);
+                                  + "connected switches: dpid {}. Aborting ..",
+                          dpid);
                 return false;
             }
             if (activeMasterSwitches.get(dpid) != null ||
                     activeEqualSwitches.get(dpid) != null) {
                 log.error("Trying to activate switch but it is already "
-                        + "activated: dpid {}. Found in activeMaster: {} "
-                        + "Found in activeEqual: {}. Aborting ..", new Object[] {
-                                dpid,
-                                (activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y',
-                                        (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'});
+                                  + "activated: dpid {}. Found in activeMaster: {} "
+                                  + "Found in activeEqual: {}. Aborting ..", new Object[]{
+                        dpid,
+                        (activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y',
+                        (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'});
                 return false;
             }
             return true;
@@ -223,7 +225,7 @@
                 OpenFlowSwitch sw = activeEqualSwitches.remove(dpid);
                 if (sw == null) {
                     log.error("Transition to master called on sw {}, but switch "
-                            + "was not found in controller-cache", dpid);
+                                      + "was not found in controller-cache", dpid);
                     return;
                 }
                 log.info("Transitioned switch {} to MASTER", dpid);
@@ -244,7 +246,7 @@
                 OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
                 if (sw == null) {
                     log.error("Transition to equal called on sw {}, but switch "
-                            + "was not found in controller-cache", dpid);
+                                      + "was not found in controller-cache", dpid);
                     return;
                 }
                 log.info("Transitioned switch {} to EQUAL", dpid);
@@ -274,5 +276,4 @@
     }
 
 
-
 }
diff --git a/providers/of/device/src/main/java/org/onlab/onos/provider/of/device/impl/OpenFlowDeviceProvider.java b/providers/of/device/src/main/java/org/onlab/onos/provider/of/device/impl/OpenFlowDeviceProvider.java
index 136a237..eb26256 100644
--- a/providers/of/device/src/main/java/org/onlab/onos/provider/of/device/impl/OpenFlowDeviceProvider.java
+++ b/providers/of/device/src/main/java/org/onlab/onos/provider/of/device/impl/OpenFlowDeviceProvider.java
@@ -85,19 +85,19 @@
     @Override
     public void roleChanged(Device device, MastershipRole newRole) {
         switch (newRole) {
-        case MASTER:
-            controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
-                    RoleState.MASTER);
-            break;
-        case STANDBY:
-            controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
-                    RoleState.EQUAL);
-        case NONE:
-            controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
-                    RoleState.SLAVE);
-            break;
-        default:
-            log.error("Unknown Mastership state : {}", newRole);
+            case MASTER:
+                controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
+                                   RoleState.MASTER);
+                break;
+            case STANDBY:
+                controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
+                                   RoleState.EQUAL);
+            case NONE:
+                controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
+                                   RoleState.SLAVE);
+                break;
+            default:
+                log.error("Unknown Mastership state : {}", newRole);
 
         }
         log.info("Accepting mastership role change for device {}", device.id());
@@ -114,10 +114,10 @@
 
             DeviceDescription description =
                     new DefaultDeviceDescription(buildURI(dpid), Device.Type.SWITCH,
-                            sw.manfacturerDescription(),
-                            sw.hardwareDescription(),
-                            sw.softwareDescription(),
-                            sw.serialNumber());
+                                                 sw.manfacturerDescription(),
+                                                 sw.hardwareDescription(),
+                                                 sw.softwareDescription(),
+                                                 sw.serialNumber());
             providerService.deviceConnected(deviceId(uri), description);
             providerService.updatePorts(deviceId(uri), buildPortDescriptions(sw.getPorts()));
         }
@@ -140,6 +140,7 @@
 
         /**
          * Given a dpid builds a URI for the device.
+         *
          * @param dpid the dpid to build the uri from
          * @return returns a uri of the form of:<dpidHexForm>
          */
@@ -155,6 +156,7 @@
 
         /**
          * Builds a list of port descriptions for a given list of ports.
+         *
          * @param ports the list of ports
          * @return list of portdescriptions
          */
@@ -169,6 +171,7 @@
 
         /**
          * Build a portDescription from a given port.
+         *
          * @param port the port to build from.
          * @return portDescription for the port.
          */