Fixed equals methods for better efficiency.
Cleaned up ClusterService API.
diff --git a/core/api/src/main/java/org/onlab/onos/cluster/ClusterEvent.java b/core/api/src/main/java/org/onlab/onos/cluster/ClusterEvent.java
index 6737f68..300a143 100644
--- a/core/api/src/main/java/org/onlab/onos/cluster/ClusterEvent.java
+++ b/core/api/src/main/java/org/onlab/onos/cluster/ClusterEvent.java
@@ -8,7 +8,7 @@
 public class ClusterEvent extends AbstractEvent<ClusterEvent.Type, ControllerInstance> {
 
     /**
-     * Type of device events.
+     * Type of cluster-related events.
      */
     public enum Type {
         /**
@@ -24,14 +24,13 @@
         /**
          * Signifies that a cluster instance became active.
          */
-        INSTANCE_ACTIVE,
+        INSTANCE_ACTIVATED,
 
         /**
          * Signifies that a cluster instance became inactive.
          */
-        INSTANCE_INACTIVE
+        INSTANCE_DEACTIVATED
     }
-    // TODO: do we need to fix the verv/adjective mix? discuss
 
     /**
      * Creates an event of a given type and for the specified instance and the
diff --git a/core/api/src/main/java/org/onlab/onos/cluster/ClusterEventListener.java b/core/api/src/main/java/org/onlab/onos/cluster/ClusterEventListener.java
new file mode 100644
index 0000000..5cc4ea0
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/cluster/ClusterEventListener.java
@@ -0,0 +1,9 @@
+package org.onlab.onos.cluster;
+
+import org.onlab.onos.event.EventListener;
+
+/**
+ * Entity capable of receiving device cluster-related events.
+ */
+public interface ClusterEventListener  extends EventListener<ClusterEvent> {
+}
diff --git a/core/api/src/main/java/org/onlab/onos/cluster/ClusterService.java b/core/api/src/main/java/org/onlab/onos/cluster/ClusterService.java
index afbf0d5..017ccd2 100644
--- a/core/api/src/main/java/org/onlab/onos/cluster/ClusterService.java
+++ b/core/api/src/main/java/org/onlab/onos/cluster/ClusterService.java
@@ -21,9 +21,19 @@
      * @return availability state
      */
     ControllerInstance.State getState(ControllerInstance instance);
-    // TODO: determine if this would be better attached to ControllerInstance directly
 
+    /**
+     * Adds the specified cluster event listener.
+     *
+     * @param listener the cluster listener
+     */
+    void addListener(ClusterEventListener listener);
 
-    // addListener, removeListener
+    /**
+     * Removes the specified cluster event listener.
+     *
+     * @param listener the cluster listener
+     */
+    void removeListener(ClusterEventListener listener);
 
 }
diff --git a/core/api/src/main/java/org/onlab/onos/cluster/InstanceId.java b/core/api/src/main/java/org/onlab/onos/cluster/InstanceId.java
index 7292a85..14f1eda 100644
--- a/core/api/src/main/java/org/onlab/onos/cluster/InstanceId.java
+++ b/core/api/src/main/java/org/onlab/onos/cluster/InstanceId.java
@@ -1,7 +1,50 @@
 package org.onlab.onos.cluster;
 
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
 /**
  * Controller cluster identity.
  */
-public interface InstanceId {
+public class InstanceId {
+
+    private final String id;
+
+    // Default constructor for serialization
+    protected InstanceId() {
+        id = null;
+    }
+
+    /**
+     * Creates a new cluster instance identifier from the specified string.
+     *
+     * @param id string identifier
+     */
+    public InstanceId(String id) {
+        this.id = id;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof InstanceId) {
+            final InstanceId other = (InstanceId) obj;
+            return Objects.equals(this.id, other.id);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("id", id).toString();
+    }
+
 }
diff --git a/core/api/src/main/java/org/onlab/onos/cluster/MastershipListener.java b/core/api/src/main/java/org/onlab/onos/cluster/MastershipListener.java
index 8a49c31..71d65be 100644
--- a/core/api/src/main/java/org/onlab/onos/cluster/MastershipListener.java
+++ b/core/api/src/main/java/org/onlab/onos/cluster/MastershipListener.java
@@ -6,5 +6,4 @@
  * Entity capable of receiving device mastership-related events.
  */
 public interface MastershipListener extends EventListener<MastershipEvent> {
-
 }
diff --git a/core/api/src/main/java/org/onlab/onos/cluster/MastershipService.java b/core/api/src/main/java/org/onlab/onos/cluster/MastershipService.java
index 3592aeb..bc5f19c 100644
--- a/core/api/src/main/java/org/onlab/onos/cluster/MastershipService.java
+++ b/core/api/src/main/java/org/onlab/onos/cluster/MastershipService.java
@@ -38,14 +38,14 @@
     MastershipRole requestRoleFor(DeviceId deviceId);
 
     /**
-     * Adds the specified mastership listener.
+     * Adds the specified mastership change listener.
      *
      * @param listener the mastership listener
      */
     void addListener(MastershipListener listener);
 
     /**
-     * Removes the specified device listener.
+     * Removes the specified mastership change listener.
      *
      * @param listener the mastership listener
      */
diff --git a/core/api/src/main/java/org/onlab/onos/cluster/MastershipStore.java b/core/api/src/main/java/org/onlab/onos/cluster/MastershipStore.java
index dad4a75..67eeff5 100644
--- a/core/api/src/main/java/org/onlab/onos/cluster/MastershipStore.java
+++ b/core/api/src/main/java/org/onlab/onos/cluster/MastershipStore.java
@@ -20,8 +20,8 @@
      * @param role     new role
      * @return a mastership event
      */
-    MastershipEvent setRole(
-            InstanceId instance, DeviceId deviceId, MastershipRole role);
+    MastershipEvent setRole(InstanceId instance, DeviceId deviceId,
+                            MastershipRole role);
 
     /**
      * Adds or updates the mastership information for a device.
@@ -31,8 +31,8 @@
      * @param role     new role
      * @return a mastership event
      */
-    MastershipEvent addOrUpdateDevice(
-            InstanceId instance, DeviceId deviceId, MastershipRole role);
+    MastershipEvent addOrUpdateDevice(InstanceId instance, DeviceId deviceId,
+                                      MastershipRole role);
 
     /**
      * Returns the master for a device.
@@ -45,7 +45,7 @@
     /**
      * Returns the devices that a controller instance is master of.
      *
-     * @param  instanceId the instance identifier
+     * @param instanceId the instance identifier
      * @return a set of device identifiers
      */
     Set<DeviceId> getDevices(InstanceId instanceId);
@@ -54,7 +54,7 @@
      * Returns the role of a device for a specific controller instance.
      *
      * @param instanceId the instance identifier
-     * @param deviceId the device identifiers
+     * @param deviceId   the device identifiers
      * @return the role
      */
     MastershipRole getRole(InstanceId instanceId, DeviceId deviceId);
diff --git a/core/api/src/main/java/org/onlab/onos/net/ConnectPoint.java b/core/api/src/main/java/org/onlab/onos/net/ConnectPoint.java
index 8f332e9..35adde9 100644
--- a/core/api/src/main/java/org/onlab/onos/net/ConnectPoint.java
+++ b/core/api/src/main/java/org/onlab/onos/net/ConnectPoint.java
@@ -66,6 +66,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof ConnectPoint) {
             final ConnectPoint other = (ConnectPoint) obj;
             return Objects.equals(this.elementId, other.elementId) &&
diff --git a/core/api/src/main/java/org/onlab/onos/net/DefaultDevice.java b/core/api/src/main/java/org/onlab/onos/net/DefaultDevice.java
index c6e65f5..29a8d17 100644
--- a/core/api/src/main/java/org/onlab/onos/net/DefaultDevice.java
+++ b/core/api/src/main/java/org/onlab/onos/net/DefaultDevice.java
@@ -85,6 +85,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof DefaultDevice) {
             final DefaultDevice other = (DefaultDevice) obj;
             return Objects.equals(this.id, other.id) &&
diff --git a/core/api/src/main/java/org/onlab/onos/net/DefaultHost.java b/core/api/src/main/java/org/onlab/onos/net/DefaultHost.java
index fad9147..8a2d6e6 100644
--- a/core/api/src/main/java/org/onlab/onos/net/DefaultHost.java
+++ b/core/api/src/main/java/org/onlab/onos/net/DefaultHost.java
@@ -63,6 +63,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof DefaultHost) {
             final DefaultHost other = (DefaultHost) obj;
             return Objects.equals(this.id, other.id) &&
diff --git a/core/api/src/main/java/org/onlab/onos/net/DefaultLink.java b/core/api/src/main/java/org/onlab/onos/net/DefaultLink.java
index e937bf3..8771faa 100644
--- a/core/api/src/main/java/org/onlab/onos/net/DefaultLink.java
+++ b/core/api/src/main/java/org/onlab/onos/net/DefaultLink.java
@@ -53,6 +53,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof DefaultLink) {
             final DefaultLink other = (DefaultLink) obj;
             return Objects.equals(this.src, other.src) &&
diff --git a/core/api/src/main/java/org/onlab/onos/net/DefaultPath.java b/core/api/src/main/java/org/onlab/onos/net/DefaultPath.java
index 63c9e88..cab41b8 100644
--- a/core/api/src/main/java/org/onlab/onos/net/DefaultPath.java
+++ b/core/api/src/main/java/org/onlab/onos/net/DefaultPath.java
@@ -57,11 +57,14 @@
 
     @Override
     public int hashCode() {
-        return 31 * super.hashCode() + Objects.hash(links);
+        return Objects.hash(links);
     }
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof DefaultPath) {
             final DefaultPath other = (DefaultPath) obj;
             return Objects.equals(this.links, other.links);
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 375becd..d07def8 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
@@ -58,6 +58,9 @@
 
     @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()) &&
diff --git a/core/api/src/main/java/org/onlab/onos/net/ElementId.java b/core/api/src/main/java/org/onlab/onos/net/ElementId.java
index a75f11e..d2cd398 100644
--- a/core/api/src/main/java/org/onlab/onos/net/ElementId.java
+++ b/core/api/src/main/java/org/onlab/onos/net/ElementId.java
@@ -40,6 +40,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof ElementId) {
             final ElementId that = (ElementId) obj;
             return this.getClass() == that.getClass() &&
diff --git a/core/api/src/main/java/org/onlab/onos/net/PortNumber.java b/core/api/src/main/java/org/onlab/onos/net/PortNumber.java
index 56e15a2..cfb11d5 100644
--- a/core/api/src/main/java/org/onlab/onos/net/PortNumber.java
+++ b/core/api/src/main/java/org/onlab/onos/net/PortNumber.java
@@ -79,6 +79,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof PortNumber) {
             final PortNumber other = (PortNumber) obj;
             return this.number == other.number;
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowRule.java b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowRule.java
index d3745b4..bd4c7f3 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowRule.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowRule.java
@@ -147,7 +147,6 @@
      * @see java.lang.Object#equals(java.lang.Object)
      */
     public boolean equals(Object obj) {
-
         if (this == obj) {
             return true;
         }
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/DefaultInboundPacket.java b/core/api/src/main/java/org/onlab/onos/net/packet/DefaultInboundPacket.java
index 8c57adc..fb31b10 100644
--- a/core/api/src/main/java/org/onlab/onos/net/packet/DefaultInboundPacket.java
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/DefaultInboundPacket.java
@@ -54,6 +54,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof InboundPacket) {
             final DefaultInboundPacket other = (DefaultInboundPacket) obj;
             return Objects.equals(this.receivedFrom, other.receivedFrom) &&
diff --git a/core/api/src/main/java/org/onlab/onos/net/provider/ProviderId.java b/core/api/src/main/java/org/onlab/onos/net/provider/ProviderId.java
index 5fc0150..8d3d571 100644
--- a/core/api/src/main/java/org/onlab/onos/net/provider/ProviderId.java
+++ b/core/api/src/main/java/org/onlab/onos/net/provider/ProviderId.java
@@ -50,12 +50,12 @@
         if (this == obj) {
             return true;
         }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
+        if (obj instanceof ProviderId) {
+            final ProviderId other = (ProviderId) obj;
+            return Objects.equals(this.scheme, other.scheme) &&
+                    Objects.equals(this.id, other.id);
         }
-        final ProviderId other = (ProviderId) obj;
-        return Objects.equals(this.scheme, other.scheme) &&
-                Objects.equals(this.id, other.id);
+        return false;
     }
 
     @Override
diff --git a/core/api/src/main/java/org/onlab/onos/net/topology/ClusterId.java b/core/api/src/main/java/org/onlab/onos/net/topology/ClusterId.java
index 502eee1..9f0e20b 100644
--- a/core/api/src/main/java/org/onlab/onos/net/topology/ClusterId.java
+++ b/core/api/src/main/java/org/onlab/onos/net/topology/ClusterId.java
@@ -43,6 +43,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof ClusterId) {
             final ClusterId other = (ClusterId) obj;
             return Objects.equals(this.id, other.id);
diff --git a/core/api/src/main/java/org/onlab/onos/net/topology/DefaultTopologyCluster.java b/core/api/src/main/java/org/onlab/onos/net/topology/DefaultTopologyCluster.java
index f33dcf7..b6cc9bd 100644
--- a/core/api/src/main/java/org/onlab/onos/net/topology/DefaultTopologyCluster.java
+++ b/core/api/src/main/java/org/onlab/onos/net/topology/DefaultTopologyCluster.java
@@ -59,6 +59,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof DefaultTopologyCluster) {
             final DefaultTopologyCluster other = (DefaultTopologyCluster) obj;
             return Objects.equals(this.id, other.id) &&
diff --git a/core/api/src/main/java/org/onlab/onos/net/topology/DefaultTopologyEdge.java b/core/api/src/main/java/org/onlab/onos/net/topology/DefaultTopologyEdge.java
index 00eb3d2..c399f3c 100644
--- a/core/api/src/main/java/org/onlab/onos/net/topology/DefaultTopologyEdge.java
+++ b/core/api/src/main/java/org/onlab/onos/net/topology/DefaultTopologyEdge.java
@@ -50,6 +50,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof DefaultTopologyEdge) {
             final DefaultTopologyEdge other = (DefaultTopologyEdge) obj;
             return Objects.equals(this.link, other.link);
diff --git a/core/api/src/main/java/org/onlab/onos/net/topology/DefaultTopologyVertex.java b/core/api/src/main/java/org/onlab/onos/net/topology/DefaultTopologyVertex.java
index 7bc231e..4337f58 100644
--- a/core/api/src/main/java/org/onlab/onos/net/topology/DefaultTopologyVertex.java
+++ b/core/api/src/main/java/org/onlab/onos/net/topology/DefaultTopologyVertex.java
@@ -32,6 +32,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof DefaultTopologyVertex) {
             final DefaultTopologyVertex other = (DefaultTopologyVertex) obj;
             return Objects.equals(this.deviceId, other.deviceId);
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/PathKey.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/PathKey.java
index 8030823..da3b055 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/PathKey.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/PathKey.java
@@ -28,6 +28,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof PathKey) {
             final PathKey other = (PathKey) obj;
             return Objects.equals(this.src, other.src) && Objects.equals(this.dst, other.dst);
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkStore.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkStore.java
index 3792fd6..5c99682 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkStore.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkStore.java
@@ -179,6 +179,9 @@
 
         @Override
         public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
             if (obj instanceof LinkKey) {
                 final LinkKey other = (LinkKey) obj;
                 return Objects.equals(this.src, other.src) &&
diff --git a/utils/misc/src/main/java/org/onlab/graph/AbstractEdge.java b/utils/misc/src/main/java/org/onlab/graph/AbstractEdge.java
index 163a147..4d1546b 100644
--- a/utils/misc/src/main/java/org/onlab/graph/AbstractEdge.java
+++ b/utils/misc/src/main/java/org/onlab/graph/AbstractEdge.java
@@ -41,6 +41,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof AbstractEdge) {
             final AbstractEdge other = (AbstractEdge) obj;
             return Objects.equals(this.src, other.src) && Objects.equals(this.dst, other.dst);
diff --git a/utils/misc/src/main/java/org/onlab/graph/AdjacencyListsGraph.java b/utils/misc/src/main/java/org/onlab/graph/AdjacencyListsGraph.java
index a0d569b..981d09b 100644
--- a/utils/misc/src/main/java/org/onlab/graph/AdjacencyListsGraph.java
+++ b/utils/misc/src/main/java/org/onlab/graph/AdjacencyListsGraph.java
@@ -80,6 +80,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof AdjacencyListsGraph) {
             AdjacencyListsGraph that = (AdjacencyListsGraph) obj;
             return this.getClass() == that.getClass() &&
diff --git a/utils/misc/src/main/java/org/onlab/graph/DefaultMutablePath.java b/utils/misc/src/main/java/org/onlab/graph/DefaultMutablePath.java
index 401e9e9..09a20a4 100644
--- a/utils/misc/src/main/java/org/onlab/graph/DefaultMutablePath.java
+++ b/utils/misc/src/main/java/org/onlab/graph/DefaultMutablePath.java
@@ -107,6 +107,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof DefaultMutablePath) {
             final DefaultMutablePath other = (DefaultMutablePath) obj;
             return Objects.equals(this.cost, other.cost) &&
diff --git a/utils/misc/src/main/java/org/onlab/graph/DefaultPath.java b/utils/misc/src/main/java/org/onlab/graph/DefaultPath.java
index a43dd0f..a4fc386 100644
--- a/utils/misc/src/main/java/org/onlab/graph/DefaultPath.java
+++ b/utils/misc/src/main/java/org/onlab/graph/DefaultPath.java
@@ -72,6 +72,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof DefaultPath) {
             final DefaultPath other = (DefaultPath) obj;
             return Objects.equals(this.src, other.src) &&
diff --git a/utils/misc/src/main/java/org/onlab/graph/Heap.java b/utils/misc/src/main/java/org/onlab/graph/Heap.java
index ecc4759..2f91083 100644
--- a/utils/misc/src/main/java/org/onlab/graph/Heap.java
+++ b/utils/misc/src/main/java/org/onlab/graph/Heap.java
@@ -166,6 +166,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof Heap) {
             Heap that = (Heap) obj;
             return this.getClass() == that.getClass() &&
diff --git a/utils/misc/src/test/java/org/onlab/graph/TestEdge.java b/utils/misc/src/test/java/org/onlab/graph/TestEdge.java
index 0accab3..aa85d88 100644
--- a/utils/misc/src/test/java/org/onlab/graph/TestEdge.java
+++ b/utils/misc/src/test/java/org/onlab/graph/TestEdge.java
@@ -39,6 +39,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof TestEdge) {
             final TestEdge other = (TestEdge) obj;
             return super.equals(obj) && Objects.equals(this.weight, other.weight);
diff --git a/utils/misc/src/test/java/org/onlab/graph/TestVertex.java b/utils/misc/src/test/java/org/onlab/graph/TestVertex.java
index 2e960f3..ca6890f 100644
--- a/utils/misc/src/test/java/org/onlab/graph/TestVertex.java
+++ b/utils/misc/src/test/java/org/onlab/graph/TestVertex.java
@@ -20,6 +20,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof TestVertex) {
             final TestVertex other = (TestVertex) obj;
             return Objects.equals(this.name, other.name);