CORD-1583 More bug fixes in dual-ToR scenarios

 - reentrant lock was not being used correctly
 - fixHashGroup in group handler was not updating global store correctly
 - linkUp was not being noted in seenLinks if configuration came after switches connected
 - serialization error in global objective store due to missing kryo for Sets
 - damaged routepath computation was not taking pair-devs into account
 - switch failures were leading to improper ecmpSpg graph updates, and missed hash-group changes
 - implemented more next-objective verification as group sub-system can go out-of-sync with objective-store

Change-Id: If3cfdd715e9b69820894b49def31f75ceb748863
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/NextNeighbors.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/NextNeighbors.java
index 1a0507b..eaca1aa 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/NextNeighbors.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/NextNeighbors.java
@@ -25,27 +25,60 @@
 
 import org.onosproject.net.DeviceId;
 
+/**
+ * Represents the nexthop information associated with a route-path towards a
+ * set of destinations.
+ */
 public class NextNeighbors {
     private final Map<DeviceId, Set<DeviceId>> dstNextHops;
     private final int nextId;
 
+    /**
+     * Constructor.
+     *
+     * @param dstNextHops map of destinations and the next-hops towards each dest
+     * @param nextId id of nextObjective that manifests the next-hop info
+     */
     public NextNeighbors(Map<DeviceId, Set<DeviceId>> dstNextHops, int nextId) {
         this.dstNextHops = dstNextHops;
         this.nextId = nextId;
     }
 
+    /**
+     * Returns a map of destinations and the next-hops towards them.
+     *
+     * @return map of destinations and the next-hops towards them
+     */
     public Map<DeviceId, Set<DeviceId>> dstNextHops() {
         return dstNextHops;
     }
 
+    /**
+     * Set of next-hops towards the given destination.
+     *
+     * @param deviceId the destination
+     * @return set of nexthops towards the destination
+     */
     public Set<DeviceId> nextHops(DeviceId deviceId) {
         return dstNextHops.get(deviceId);
     }
 
+    /**
+     * Return the nextId representing the nextObjective towards the next-hops.
+     *
+     * @return nextId representing the nextObjective towards the next-hops
+     */
     public int nextId() {
         return nextId;
     }
 
+    /**
+     * Checks if the given nextHopId is a valid next hop to any one of the
+     * destinations.
+     *
+     * @param nextHopId the deviceId for the next hop
+     * @return true if given next
+     */
     public boolean containsNextHop(DeviceId nextHopId) {
         for (Set<DeviceId> nextHops : dstNextHops.values()) {
             if (nextHops != null && nextHops.contains(nextHopId)) {
@@ -55,6 +88,14 @@
         return false;
     }
 
+    /**
+     * Returns a set of destinations which have the given nextHopId as one
+     * of the next-hops to that destination.
+     *
+     * @param nextHopId the deviceId for the next hop
+     * @return set of deviceIds that have the given nextHopId as a next-hop
+     *          which could be empty if no destinations were found
+     */
     public Set<DeviceId> getDstForNextHop(DeviceId nextHopId) {
         Set<DeviceId> dstSet = new HashSet<>();
         for (DeviceId dstKey : dstNextHops.keySet()) {