[CORD-2631] Handling dual links in T3

Change-Id: I1c1875902c3cc8744ecb9deb63a806d2c64c29ff
(cherry picked from commit e0686e729fbaf4ce236fbd409f323428a513c5b3)
diff --git a/src/main/java/org/onosproject/t3/impl/TroubleshootManager.java b/src/main/java/org/onosproject/t3/impl/TroubleshootManager.java
index c206176..21f56e8 100644
--- a/src/main/java/org/onosproject/t3/impl/TroubleshootManager.java
+++ b/src/main/java/org/onosproject/t3/impl/TroubleshootManager.java
@@ -131,6 +131,8 @@
      */
     private StaticPacketTrace getTrace(List<ConnectPoint> completePath, ConnectPoint in, StaticPacketTrace trace) {
 
+        log.debug("------------------------------------------------------------");
+
         //if the trace already contains the input connect point there is a loop
         if (pathContainsDevice(completePath, in.deviceId())) {
             trace.addResultMessage("Loop encountered in device " + in.deviceId());
@@ -151,6 +153,7 @@
         for (GroupsInDevice outputPath : trace.getGroupOuputs(in.deviceId())) {
 
             ConnectPoint cp = outputPath.getOutput();
+            log.debug("Connect point in {}", in);
             log.debug("Output path {}", cp);
 
             //Hosts for the the given output
@@ -160,7 +163,7 @@
 
             //If the two host collections contain the same item it means we reached the proper output
             if (!Collections.disjoint(hostsList, hosts)) {
-                log.debug("Stopping here because host is expected destination");
+                log.debug("Stopping here because host is expected destination {}, reached through", completePath);
                 trace.addResultMessage("Reached required destination Host " + cp);
                 computePath(completePath, trace, outputPath.getOutput());
                 break;
@@ -182,10 +185,32 @@
                 computePath(completePath, trace, outputPath.getOutput());
 
             } else {
+
+                //TODO this can be optimized if we use a Tree structure for paths.
+                //if we already have outputs let's check if the one we are considering starts from one of the devices
+                // in any of the ones we have.
+                if (trace.getCompletePaths().size() > 0) {
+                    ConnectPoint inputForOutput = null;
+                    List<ConnectPoint> previousPath = new ArrayList<>();
+                    for (List<ConnectPoint> path : trace.getCompletePaths()) {
+                        for (ConnectPoint connect : path) {
+                            //if the path already contains the input for the output we've found we use it
+                            if (connect.equals(in)) {
+                                inputForOutput = connect;
+                                previousPath = path;
+                                break;
+                            }
+                        }
+                    }
+                    //we use the pre-existing path up to the point we fork to a new output
+                    if (inputForOutput != null && completePath.contains(inputForOutput)) {
+                        List<ConnectPoint> temp = new ArrayList<>(previousPath);
+                        completePath = temp.subList(0, previousPath.indexOf(inputForOutput) + 1);
+                    }
+                }
+
                 //let's add the ouput for the input
                 completePath.add(cp);
-                log.debug("------------------------------------------------------------");
-                log.debug("Connect Point out {}", cp);
                 //let's compute the links for the given output
                 Set<Link> links = linkService.getEgressLinks(cp);
                 log.debug("Egress Links {}", links);
@@ -274,7 +299,6 @@
             traverseList.add(output);
         }
         trace.addCompletePath(traverseList);
-        completePath.clear();
     }
 
     /**
@@ -286,6 +310,12 @@
      * @return updated trace
      */
     private StaticPacketTrace traceInDevice(StaticPacketTrace trace, TrafficSelector packet, ConnectPoint in) {
+
+        //we already traversed this device.
+        if (trace.getGroupOuputs(in.deviceId()) != null) {
+            log.debug("Trace already contains device and given outputs");
+            return trace;
+        }
         log.debug("Packet {} coming in from {}", packet, in);
 
         //if device is not available exit here.