Added graceful shutdown for upstart service.
Reworked slightly the mastership & device managers and stores to make it work (sort-of) in the distributed env.
diff --git a/core/api/src/main/java/org/onlab/onos/cluster/ClusterAdminService.java b/core/api/src/main/java/org/onlab/onos/cluster/ClusterAdminService.java
new file mode 100644
index 0000000..4f98804
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/cluster/ClusterAdminService.java
@@ -0,0 +1,15 @@
+package org.onlab.onos.cluster;
+
+/**
+ * Service for administering the cluster node membership.
+ */
+public interface ClusterAdminService {
+
+    /**
+     * Removes the specified node from the cluster node list.
+     *
+     * @param nodeId controller node identifier
+     */
+    void removeNode(NodeId nodeId);
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/cluster/ClusterStore.java b/core/api/src/main/java/org/onlab/onos/cluster/ClusterStore.java
index 7d4b71f..4579190 100644
--- a/core/api/src/main/java/org/onlab/onos/cluster/ClusterStore.java
+++ b/core/api/src/main/java/org/onlab/onos/cluster/ClusterStore.java
@@ -8,7 +8,7 @@
 public interface ClusterStore {
 
     /**
-     * Returns the local controller instance.
+     * Returns the local controller node.
      *
      * @return local controller instance
      */
@@ -22,7 +22,7 @@
     Set<ControllerNode> getNodes();
 
     /**
-     * Returns the specified controller instance.
+     * Returns the specified controller node.
      *
      * @param nodeId controller instance identifier
      * @return controller instance
@@ -30,11 +30,18 @@
     ControllerNode getNode(NodeId nodeId);
 
     /**
-     * Returns the availability state of the specified controller instance.
+     * Returns the availability state of the specified controller node.
      *
      * @param nodeId controller instance identifier
      * @return availability state
      */
     ControllerNode.State getState(NodeId nodeId);
 
+    /**
+     * Removes the specified node from the inventory of cluster nodes.
+     *
+     * @param nodeId controller instance identifier
+     */
+    void removeNode(NodeId nodeId);
+
 }
diff --git a/core/api/src/main/java/org/onlab/onos/cluster/MastershipProvider.java b/core/api/src/main/java/org/onlab/onos/cluster/MastershipProvider.java
deleted file mode 100644
index 69376cf..0000000
--- a/core/api/src/main/java/org/onlab/onos/cluster/MastershipProvider.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.onlab.onos.cluster;
-
-import org.onlab.onos.net.provider.Provider;
-
-/**
- * Abstraction of a mastership information provider.
- */
-public interface MastershipProvider extends Provider {
-    // do we get role info from the local OFcontroller impl?
-    // needs to also read from distributed store and emit events?
-    // roleChanged(DeviceId deviceId, MastershipRole newRole);
-}
diff --git a/core/api/src/main/java/org/onlab/onos/cluster/MastershipProviderService.java b/core/api/src/main/java/org/onlab/onos/cluster/MastershipProviderService.java
deleted file mode 100644
index 111b2ca..0000000
--- a/core/api/src/main/java/org/onlab/onos/cluster/MastershipProviderService.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.onlab.onos.cluster;
-
-import org.onlab.onos.net.DeviceId;
-import org.onlab.onos.net.MastershipRole;
-import org.onlab.onos.net.provider.ProviderService;
-
-public interface MastershipProviderService extends
-        ProviderService<MastershipProvider> {
-
-    /**
-     * Signals the core that mastership has changed for a device.
-     *
-     * @param deviceId the device ID
-     * @param role the new mastership role of this controller instance
-     */
-    void roleChanged(NodeId nodeId, DeviceId deviceId, MastershipRole role);
-
-}
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 8da4aa5..31b4bcc 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
@@ -14,6 +14,32 @@
 public interface MastershipService {
 
     /**
+     * Returns the role of the local node for the specified device, without
+     * triggering master selection.
+     *
+     * @return role of the current node
+     */
+    MastershipRole getLocalRole(DeviceId deviceId);
+
+    /**
+     * Returns the mastership status of the local controller for a given
+     * device forcing master selection if necessary.
+     *
+     * @param deviceId the the identifier of the device
+     * @return the role of this controller instance
+     */
+    MastershipRole requestRoleFor(DeviceId deviceId);
+
+    /**
+     * Abandons mastership of the specified device on the local node thus
+     * forcing selection of a new master. If the local node is not a master
+     * for this device, no action will be taken.
+     *
+     * @param deviceId the identifier of the device
+     */
+    void relinquishMastership(DeviceId deviceId);
+
+    /**
      * Returns the current master for a given device.
      *
      * @param deviceId the identifier of the device
@@ -30,17 +56,6 @@
     Set<DeviceId> getDevicesOf(NodeId nodeId);
 
     /**
-     * Returns the mastership status of this controller for a given device.
-     *
-     * @param deviceId the the identifier of the device
-     * @return the role of this controller instance
-     */
-    MastershipRole requestRoleFor(DeviceId deviceId);
-
-    // TODO: add facet for requesting a different master than the current one;
-    // abandon mastership (due to loss of connection)
-
-    /**
      * Adds 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 cb4a076..3e2ee03 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
@@ -14,26 +14,21 @@
     // three things to map: NodeId, DeviceId, MastershipRole
 
     /**
-     * Sets a device's role for a specified controller instance.
+     * Requests role of the local node for the specified device.
      *
-     * @param instance controller instance identifier
      * @param deviceId device identifier
-     * @param role     new role
-     * @return a mastership event
+     * @return established or newly negotiated mastership role
      */
-    MastershipEvent setRole(NodeId instance, DeviceId deviceId,
-                            MastershipRole role);
+    MastershipRole requestRole(DeviceId deviceId);
 
     /**
-     * Adds or updates mastership information for a device.
+     * Returns the role of a device for a specific controller instance.
      *
-     * @param instance controller instance identifier
-     * @param deviceId device identifier
-     * @param role     new role
-     * @return a mastership event
+     * @param nodeId   the instance identifier
+     * @param deviceId the device identifiers
+     * @return the role
      */
-    MastershipEvent addOrUpdateDevice(NodeId instance, DeviceId deviceId,
-                                      MastershipRole role);
+    MastershipRole getRole(NodeId nodeId, DeviceId deviceId);
 
     /**
      * Returns the master for a device.
@@ -52,11 +47,13 @@
     Set<DeviceId> getDevices(NodeId nodeId);
 
     /**
-     * Returns the role of a device for a specific controller instance.
+     * Sets a device's role for a specified controller instance.
      *
-     * @param nodeId the instance identifier
-     * @param deviceId   the device identifiers
-     * @return the role
+     * @param nodeId   controller instance identifier
+     * @param deviceId device identifier
+     * @param role     new role
+     * @return a mastership event
      */
-    MastershipRole getRole(NodeId nodeId, DeviceId deviceId);
+    MastershipEvent setRole(NodeId nodeId, DeviceId deviceId,
+                            MastershipRole role);
 }
diff --git a/core/api/src/main/java/org/onlab/onos/cluster/NodeId.java b/core/api/src/main/java/org/onlab/onos/cluster/NodeId.java
index 2430d52..5ff2fbc 100644
--- a/core/api/src/main/java/org/onlab/onos/cluster/NodeId.java
+++ b/core/api/src/main/java/org/onlab/onos/cluster/NodeId.java
@@ -9,11 +9,6 @@
 
     private final String id;
 
-    // Default constructor for serialization
-    protected NodeId() {
-        id = null;
-    }
-
     /**
      * Creates a new cluster node identifier from the specified string.
      *
diff --git a/core/api/src/main/java/org/onlab/onos/net/device/DeviceAdminService.java b/core/api/src/main/java/org/onlab/onos/net/device/DeviceAdminService.java
index fbfec31..fdcaa9b 100644
--- a/core/api/src/main/java/org/onlab/onos/net/device/DeviceAdminService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/device/DeviceAdminService.java
@@ -1,7 +1,6 @@
 package org.onlab.onos.net.device;
 
 import org.onlab.onos.net.DeviceId;
-import org.onlab.onos.net.MastershipRole;
 
 /**
  * Service for administering the inventory of infrastructure devices.
@@ -9,16 +8,6 @@
 public interface DeviceAdminService {
 
     /**
-     * Applies the current mastership role for the specified device.
-     *
-     * @param deviceId device identifier
-     * @param role     requested role
-     * @deprecated Will be removed in favor of MastershipAdminService.setRole()
-     */
-//    @Deprecated
-    void setRole(DeviceId deviceId, MastershipRole role);
-
-    /**
      * Removes the device with the specified identifier.
      *
      * @param deviceId device identifier
diff --git a/core/api/src/main/java/org/onlab/onos/net/device/DeviceStore.java b/core/api/src/main/java/org/onlab/onos/net/device/DeviceStore.java
index 3ed477b..ef111e9 100644
--- a/core/api/src/main/java/org/onlab/onos/net/device/DeviceStore.java
+++ b/core/api/src/main/java/org/onlab/onos/net/device/DeviceStore.java
@@ -2,7 +2,6 @@
 
 import org.onlab.onos.net.Device;
 import org.onlab.onos.net.DeviceId;
-import org.onlab.onos.net.MastershipRole;
 import org.onlab.onos.net.Port;
 import org.onlab.onos.net.PortNumber;
 import org.onlab.onos.net.provider.ProviderId;
@@ -104,23 +103,6 @@
     boolean isAvailable(DeviceId deviceId);
 
     /**
-     * Returns the mastership role determined for this device.
-     *
-     * @param deviceId device identifier
-     * @return mastership role
-     */
-    MastershipRole getRole(DeviceId deviceId);
-
-    /**
-     * Administratively sets the role of the specified device.
-     *
-     * @param deviceId device identifier
-     * @param role     mastership role to apply
-     * @return mastership role change event or null if no change
-     */
-    DeviceEvent setRole(DeviceId deviceId, MastershipRole role);
-
-    /**
      * Administratively removes the specified device from the store.
      *
      * @param deviceId device to be removed