Create local storage for topic candidates mapping. This also includes:

 - using Optional in Leadership, and some commenting.
 - using MutableBooleans + compute()

    part of: Device Mastership store on top of LeadershipService
    Reference: ONOS-76

Conflicts:
	core/api/src/main/java/org/onosproject/cluster/LeadershipService.java
	core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DistributedLeadershipManager.java

Change-Id: I7f090abb123cf23bb5126a935a6e72be00f3e3ce
diff --git a/core/api/src/main/java/org/onosproject/cluster/Leadership.java b/core/api/src/main/java/org/onosproject/cluster/Leadership.java
index a0c5e70..175de2d 100644
--- a/core/api/src/main/java/org/onosproject/cluster/Leadership.java
+++ b/core/api/src/main/java/org/onosproject/cluster/Leadership.java
@@ -17,6 +17,7 @@
 
 import java.util.Objects;
 import java.util.List;
+import java.util.Optional;
 
 import org.joda.time.DateTime;
 
@@ -33,19 +34,21 @@
  * rest in decreasing preference order.</li>
  * <li>The epoch is the logical age of a Leadership construct, and should be
  * used for comparing two Leaderships, but only of the same topic.</li>
+ * <li>The leader may be null if its accuracy can't be guaranteed. This applies
+ * to CANDIDATES_CHANGED events and candidate board contents.</li>
  * </ul>
  */
 public class Leadership {
 
     private final String topic;
-    private final NodeId leader;
+    private final Optional<NodeId> leader;
     private final List<NodeId> candidates;
     private final long epoch;
     private final long electedTime;
 
     public Leadership(String topic, NodeId leader, long epoch, long electedTime) {
         this.topic = topic;
-        this.leader = leader;
+        this.leader = Optional.of(leader);
         this.candidates = ImmutableList.of(leader);
         this.epoch = epoch;
         this.electedTime = electedTime;
@@ -54,7 +57,16 @@
     public Leadership(String topic, NodeId leader, List<NodeId> candidates,
             long epoch, long electedTime) {
         this.topic = topic;
-        this.leader = leader;
+        this.leader = Optional.of(leader);
+        this.candidates = ImmutableList.copyOf(candidates);
+        this.epoch = epoch;
+        this.electedTime = electedTime;
+    }
+
+    public Leadership(String topic, List<NodeId> candidates,
+            long epoch, long electedTime) {
+        this.topic = topic;
+        this.leader = Optional.empty();
         this.candidates = ImmutableList.copyOf(candidates);
         this.epoch = epoch;
         this.electedTime = electedTime;
@@ -74,8 +86,9 @@
      *
      * @return leader node.
      */
+    // This will return Optional<NodeId> in the future.
     public NodeId leader() {
-        return leader;
+        return leader.orElse(null);
     }
 
     /**
diff --git a/core/api/src/main/java/org/onosproject/cluster/LeadershipEvent.java b/core/api/src/main/java/org/onosproject/cluster/LeadershipEvent.java
index c4f59be..3456e22 100644
--- a/core/api/src/main/java/org/onosproject/cluster/LeadershipEvent.java
+++ b/core/api/src/main/java/org/onosproject/cluster/LeadershipEvent.java
@@ -43,14 +43,14 @@
         LEADER_REELECTED,
 
         /**
-         * Signifies that the leader has been booted and lost leadership. The event subject is the
-         * former leader.
+         * Signifies that the leader has been booted and lost leadership. The
+         * event subject is the former leader.
          */
         LEADER_BOOTED,
 
         /**
          * Signifies that the list of candidates for leadership for a topic has
-         * changed.
+         * changed. This event does not guarantee accurate leader information.
          */
         CANDIDATES_CHANGED
     }
diff --git a/core/api/src/main/java/org/onosproject/cluster/LeadershipService.java b/core/api/src/main/java/org/onosproject/cluster/LeadershipService.java
index 1acdc61..bc490d9 100644
--- a/core/api/src/main/java/org/onosproject/cluster/LeadershipService.java
+++ b/core/api/src/main/java/org/onosproject/cluster/LeadershipService.java
@@ -76,9 +76,9 @@
     /**
      * Returns the candidates for all known topics.
      *
-     * @return A map of topics to lists of NodeIds.
+     * @return A mapping from topics to up-to-date candidate info.
      */
-    Map<String, List<NodeId>> getCandidates();
+    Map<String, Leadership> getCandidates();
 
     /**
      * Returns the candidates for a given topic.