Remove the local onos/core/Pair.java class and replace it with
the corresponding "org.apache.commons.lang3.tuple.Pair" from Apache.

Usage differences:
 * "new Pair<>(a, b)" -> "Pair.of(a, b)"
    Note that "Pair.of()" returns immutable pair by definition: ImmutablePair

 * "Pair.getFirst()" -> "Pair.getLeft()"
   "Pair.getSecond()" -> "Pair.getRight()"

Also, few replacements for HashMap and similar containers:
"new HashMap<Foo, Bar>()" -> "new HashMap<>()"

Change-Id: I7a3d8a34dac37c672f0d1779f83f50dfeba8dec7
diff --git a/src/main/java/net/onrc/onos/api/flowmanager/SingleSrcTreeFlow.java b/src/main/java/net/onrc/onos/api/flowmanager/SingleSrcTreeFlow.java
index 5b26a04..3e70f4b 100644
--- a/src/main/java/net/onrc/onos/api/flowmanager/SingleSrcTreeFlow.java
+++ b/src/main/java/net/onrc/onos/api/flowmanager/SingleSrcTreeFlow.java
@@ -12,9 +12,10 @@
 import net.onrc.onos.core.matchaction.action.OutputAction;
 import net.onrc.onos.core.matchaction.match.PacketMatch;
 import net.onrc.onos.core.util.Dpid;
-import net.onrc.onos.core.util.Pair;
 import net.onrc.onos.core.util.SwitchPort;
 
+import org.apache.commons.lang3.tuple.Pair;
+
 /**
  * A Flow object expressing the point-to-multipoints tree flow for the packet
  * layer.
diff --git a/src/main/java/net/onrc/onos/core/flowprogrammer/FlowPusher.java b/src/main/java/net/onrc/onos/core/flowprogrammer/FlowPusher.java
index a02f0d5..c40eac0 100644
--- a/src/main/java/net/onrc/onos/core/flowprogrammer/FlowPusher.java
+++ b/src/main/java/net/onrc/onos/core/flowprogrammer/FlowPusher.java
@@ -25,8 +25,8 @@
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 import net.onrc.onos.core.intent.FlowEntry;
-import net.onrc.onos.core.util.Pair;
 
+import org.apache.commons.lang3.tuple.Pair;
 import org.projectfloodlight.openflow.protocol.OFBarrierReply;
 import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
 import org.projectfloodlight.openflow.protocol.OFFactory;
@@ -85,8 +85,7 @@
         boolean toBeDeleted = false;
 
         SwitchQueue() {
-            rawQueues = new ArrayList<Queue<SwitchQueueEntry>>(
-                    MsgPriority.values().length);
+            rawQueues = new ArrayList<>(MsgPriority.values().length);
             for (int i = 0; i < MsgPriority.values().length; ++i) {
                 rawQueues.add(i, new ArrayDeque<SwitchQueueEntry>());
             }
@@ -410,7 +409,7 @@
      * Begin processing queue.
      */
     public void start() {
-        threadMap = new HashMap<Long, FlowPusherThread>();
+        threadMap = new HashMap<>();
         for (long i = 0; i < numberThread; ++i) {
             FlowPusherThread thread = new FlowPusherThread();
 
@@ -572,7 +571,7 @@
             Collection<Pair<IOFSwitch, FlowEntry>> entries, MsgPriority priority) {
 
         for (Pair<IOFSwitch, FlowEntry> entry : entries) {
-            add(entry.getFirst(), entry.getSecond(), priority);
+            add(entry.getLeft(), entry.getRight(), priority);
         }
     }
 
@@ -583,10 +582,9 @@
 
     @Override
     public void pushFlowEntry(IOFSwitch sw, FlowEntry flowEntry, MsgPriority priority) {
-        Collection<Pair<IOFSwitch, FlowEntry>> entries =
-                new LinkedList<Pair<IOFSwitch, FlowEntry>>();
+        Collection<Pair<IOFSwitch, FlowEntry>> entries = new LinkedList<>();
 
-        entries.add(new Pair<IOFSwitch, FlowEntry>(sw, flowEntry));
+        entries.add(Pair.of(sw, flowEntry));
         pushFlowEntries(entries, priority);
     }
 
diff --git a/src/main/java/net/onrc/onos/core/flowprogrammer/IFlowPusherService.java b/src/main/java/net/onrc/onos/core/flowprogrammer/IFlowPusherService.java
index e94119a..25162aa 100644
--- a/src/main/java/net/onrc/onos/core/flowprogrammer/IFlowPusherService.java
+++ b/src/main/java/net/onrc/onos/core/flowprogrammer/IFlowPusherService.java
@@ -6,8 +6,8 @@
 import net.floodlightcontroller.core.internal.OFMessageFuture;
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.onrc.onos.core.intent.FlowEntry;
-import net.onrc.onos.core.util.Pair;
 
+import org.apache.commons.lang3.tuple.Pair;
 import org.projectfloodlight.openflow.protocol.OFBarrierReply;
 import org.projectfloodlight.openflow.protocol.OFMessage;
 
diff --git a/src/main/java/net/onrc/onos/core/intent/runtime/PlanInstallRuntime.java b/src/main/java/net/onrc/onos/core/intent/runtime/PlanInstallRuntime.java
index 8a444d7..d9a235b 100644
--- a/src/main/java/net/onrc/onos/core/intent/runtime/PlanInstallRuntime.java
+++ b/src/main/java/net/onrc/onos/core/intent/runtime/PlanInstallRuntime.java
@@ -14,8 +14,8 @@
 import net.floodlightcontroller.core.internal.OFMessageFuture;
 import net.onrc.onos.core.flowprogrammer.IFlowPusherService;
 import net.onrc.onos.core.intent.FlowEntry;
-import net.onrc.onos.core.util.Pair;
 
+import org.apache.commons.lang3.tuple.Pair;
 import org.projectfloodlight.openflow.protocol.OFBarrierReply;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -182,7 +182,7 @@
                     log.debug("Skipping flow entry: {}", entry);
                     continue;
                 }
-                entries.add(new Pair<>(sw, entry));
+                entries.add(Pair.of(sw, entry));
                 modifiedSwitches.add(sw);
                 FlowModCount.countFlowEntry(sw, entry);
             }
@@ -197,11 +197,11 @@
             // wait for confirmation messages before proceeding
             List<Pair<IOFSwitch, OFMessageFuture<OFBarrierReply>>> barriers = new ArrayList<>();
             for (IOFSwitch sw : modifiedSwitches) {
-                barriers.add(new Pair<>(sw, pusher.barrierAsync(sw)));
+                barriers.add(Pair.of(sw, pusher.barrierAsync(sw)));
             }
             for (Pair<IOFSwitch, OFMessageFuture<OFBarrierReply>> pair : barriers) {
-                IOFSwitch sw = pair.getFirst();
-                OFMessageFuture<OFBarrierReply> future = pair.getSecond();
+                IOFSwitch sw = pair.getLeft();
+                OFMessageFuture<OFBarrierReply> future = pair.getRight();
                 try {
                     future.get();
                 } catch (InterruptedException | ExecutionException e) {
diff --git a/src/main/java/net/onrc/onos/core/util/Pair.java b/src/main/java/net/onrc/onos/core/util/Pair.java
deleted file mode 100644
index 66b60b8..0000000
--- a/src/main/java/net/onrc/onos/core/util/Pair.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package net.onrc.onos.core.util;
-
-import java.util.Objects;
-
-/**
- * A generic class representing a pair of two values.
- *
- * If a user supplies immutable objects, the pair become immutable.
- * Otherwise, the pair become mutable.
- *
- * @param <F> the type of the first value
- * @param <S> the type type of the second value
- */
-public final class Pair<F, S> {
-    private final F first;        // The first value in the pair
-    private final S second;       // The second value in the pair
-
-    /**
-     * Constructor for a pair of two values.
-     *
-     * @param first  the first value in the pair.
-     * @param second the second value in the pair.
-     */
-    public Pair(F first, S second) {
-        this.first = first;
-        this.second = second;
-    }
-
-    /**
-     * Get the first value of the Pair.
-     *
-     * @return the first value of the Pair.
-     */
-    public F getFirst() {
-        return first;
-    }
-
-    /**
-     * Get the second value of the Pair.
-     *
-     * @return the second value of the Pair.
-     */
-    public S getSecond() {
-        return second;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("<%s, %s>", first, second);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (o == this) {
-            return true;
-        }
-
-        if (!(o instanceof Pair)) {
-            return false;
-        }
-
-        Pair<?, ?> that = (Pair<?, ?>) o;
-        return Objects.equals(this.first, that.first)
-                && Objects.equals(this.second, that.second);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(this.first, this.second);
-    }
-}
diff --git a/src/test/java/net/onrc/onos/core/newintent/SingleSrcTreeFlowIntentInstallerTest.java b/src/test/java/net/onrc/onos/core/newintent/SingleSrcTreeFlowIntentInstallerTest.java
index 755fa87..a874ea4 100644
--- a/src/test/java/net/onrc/onos/core/newintent/SingleSrcTreeFlowIntentInstallerTest.java
+++ b/src/test/java/net/onrc/onos/core/newintent/SingleSrcTreeFlowIntentInstallerTest.java
@@ -10,8 +10,8 @@
 import net.onrc.onos.core.matchaction.action.OutputAction;
 import net.onrc.onos.core.matchaction.match.PacketMatchBuilder;
 import net.onrc.onos.core.util.Dpid;
-import net.onrc.onos.core.util.Pair;
 import net.onrc.onos.core.util.SwitchPort;
+import org.apache.commons.lang3.tuple.Pair;
 import org.junit.Test;
 
 import java.util.HashSet;
@@ -90,8 +90,8 @@
         tree.add(new FlowLink(port13, port31));
 
         Set<Pair<Dpid, OutputAction>> actions = new HashSet<>();
-        actions.add(new Pair<>(egress1.getDpid(), new OutputAction(egress1.getPortNumber())));
-        actions.add(new Pair<>(egress2.getDpid(), new OutputAction(egress2.getPortNumber())));
+        actions.add(Pair.of(egress1.getDpid(), new OutputAction(egress1.getPortNumber())));
+        actions.add(Pair.of(egress2.getDpid(), new OutputAction(egress2.getPortNumber())));
 
         return new SingleSrcTreeFlow(
                 flowId,
diff --git a/src/test/java/net/onrc/onos/core/newintent/SingleSrcTreeFlowIntentTest.java b/src/test/java/net/onrc/onos/core/newintent/SingleSrcTreeFlowIntentTest.java
index cfd9391..a9a3dbf 100644
--- a/src/test/java/net/onrc/onos/core/newintent/SingleSrcTreeFlowIntentTest.java
+++ b/src/test/java/net/onrc/onos/core/newintent/SingleSrcTreeFlowIntentTest.java
@@ -10,10 +10,11 @@
 import net.onrc.onos.core.matchaction.match.PacketMatch;
 import net.onrc.onos.core.matchaction.match.PacketMatchBuilder;
 import net.onrc.onos.core.util.Dpid;
-import net.onrc.onos.core.util.Pair;
 import net.onrc.onos.core.util.PortNumber;
 import net.onrc.onos.core.util.SwitchPort;
 
+import org.apache.commons.lang3.tuple.Pair;
+
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
@@ -41,8 +42,8 @@
     @Override
     protected SingleSrcTreeFlowIntent createOne() {
         Set<Pair<Dpid, OutputAction>> actions = new HashSet<>(Arrays.asList(
-                new Pair<>(dpid2, action2),
-                new Pair<>(dpid3, action3)
+                Pair.of(dpid2, action2),
+                Pair.of(dpid3, action3)
         ));
         SingleSrcTreeFlow tree = new SingleSrcTreeFlow(flowId1, match,
                 new SwitchPort(dpid1, port3), createTree(), actions
@@ -53,8 +54,8 @@
     @Override
     protected SingleSrcTreeFlowIntent createAnother() {
         Set<Pair<Dpid, OutputAction>> actions = new HashSet<>(Arrays.asList(
-                new Pair<>(dpid1, action1),
-                new Pair<>(dpid3, action3)
+                Pair.of(dpid1, action1),
+                Pair.of(dpid3, action3)
         ));
         SingleSrcTreeFlow tree = new SingleSrcTreeFlow(flowId2, match,
                 new SwitchPort(dpid2, port3), createTree(), actions
diff --git a/src/test/java/net/onrc/onos/core/util/PairTest.java b/src/test/java/net/onrc/onos/core/util/PairTest.java
deleted file mode 100644
index 954b01f..0000000
--- a/src/test/java/net/onrc/onos/core/util/PairTest.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package net.onrc.onos.core.util;
-
-import org.junit.Test;
-
-import static net.onrc.onos.core.util.ImmutableClassChecker.assertThatClassIsImmutable;
-
-/**
- * PairTest class tests the immutability of Pair class when immutable objects are supplied.
- */
-public class PairTest {
-    /**
-     * Tests Pair class satisfies the guideline for immutable objects
-     * by using ImmutableClassChecker framework.
-     */
-    @Test
-    public void pairClassFollowsGuidelineForImmutableObject() {
-        assertThatClassIsImmutable(Pair.class);
-    }
-}