diff --git a/apps/t3/BUCK b/apps/t3/BUCK
index bca18be..a21999d 100644
--- a/apps/t3/BUCK
+++ b/apps/t3/BUCK
@@ -6,16 +6,23 @@
     '//core/api:onos-api',
     '//lib:org.apache.karaf.shell.console',
     '//cli:onos-cli',
+    '//drivers/default:onos-drivers-default',
+]
+
+TEST_DEPS = [
+    '//lib:TEST_ADAPTERS',
+    '//utils/misc:onlab-misc',
 ]
 
 osgi_jar_with_tests (
     deps = COMPILE_DEPS,
+    test_deps = TEST_DEPS,
 )
 
 onos_app (
     title = 'Trellis Troubleshooting Toolkit',
-    category = 'Utility',
-    url = 'http://onosproject.org',
+    category = 'Utilities',
+    url = 'https://wiki.opencord.org/pages/viewpage.action?pageId=4456974',
     description = 'Provides static analysis of flows and groups ' +
     'to determine the possible paths a packet may take.',
 )
diff --git a/apps/t3/pom.xml b/apps/t3/pom.xml
index ef1349e..e82a900 100644
--- a/apps/t3/pom.xml
+++ b/apps/t3/pom.xml
@@ -54,6 +54,12 @@
         </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+            <scope>test</scope>
+            <classifier>tests</classifier>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
             <artifactId>onos-core-primitives</artifactId>
             <version>${project.version}</version>
         </dependency>
@@ -70,6 +76,16 @@
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.scr.annotations</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-drivers-default</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-misc</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/apps/t3/src/main/java/org/onosproject/t3/api/GroupsInDevice.java b/apps/t3/src/main/java/org/onosproject/t3/api/GroupsInDevice.java
new file mode 100644
index 0000000..3cfb41a
--- /dev/null
+++ b/apps/t3/src/main/java/org/onosproject/t3/api/GroupsInDevice.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.t3.api;
+
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.group.Group;
+
+import java.util.List;
+
+/**
+ * Class to represent the groups in a device for a given output and packet.
+ */
+//FIXME consider removing.
+public class GroupsInDevice {
+
+    private ConnectPoint output;
+    private List<Group> groups;
+    private TrafficSelector selector;
+
+    /**
+     * Saves the given groups for the output connect point and the selector.
+     * @param output the output connect point
+     * @param groups the groups
+     * @param selector the selector representing the final packet
+     */
+    public GroupsInDevice(ConnectPoint output, List<Group> groups, TrafficSelector selector) {
+
+        this.output = output;
+        this.groups = groups;
+        this.selector = selector;
+    }
+
+    /**
+     * Returns the output connect point.
+     * @return the connect point
+     */
+    public ConnectPoint getOutput() {
+        return output;
+    }
+
+    /**
+     * Returns the groups.
+     * @return groups.
+     */
+    public List<Group> getGroups() {
+        return groups;
+    }
+
+    /**
+     * Returns the final packet after traversing the network.
+     * @return the selector with packet info
+     */
+    public TrafficSelector getFinalPacket() {
+        return selector;
+    }
+
+    @Override
+    public String toString() {
+        return "GroupsInDevice{" +
+                "output=" + output +
+                ", groups=" + groups +
+                ", selector=" + selector +
+                '}';
+    }
+
+}
diff --git a/apps/t3/src/main/java/org/onosproject/t3/api/StaticPacketTrace.java b/apps/t3/src/main/java/org/onosproject/t3/api/StaticPacketTrace.java
index e6ee8e8..cfc6371 100644
--- a/apps/t3/src/main/java/org/onosproject/t3/api/StaticPacketTrace.java
+++ b/apps/t3/src/main/java/org/onosproject/t3/api/StaticPacketTrace.java
@@ -16,10 +16,153 @@
 
 package org.onosproject.t3.api;
 
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.TrafficSelector;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 /**
  * Encapsulates the result of tracing a packet (traffic selector) through
  * the current topology.
  */
 public class StaticPacketTrace {
 
+    private final TrafficSelector inPacket;
+    private final ConnectPoint in;
+    List<List<ConnectPoint>> completePaths;
+    private Map<DeviceId, List<GroupsInDevice>> outputsForDevice;
+    private Map<DeviceId, List<FlowEntry>> flowsForDevice;
+    private StringBuilder resultMessage;
+
+    /**
+     * Builds the trace with a given packet and a connect point.
+     *
+     * @param packet the packet to trace
+     * @param in     the initial connect point
+     */
+    public StaticPacketTrace(TrafficSelector packet, ConnectPoint in) {
+        this.inPacket = packet;
+        this.in = in;
+        completePaths = new ArrayList<>();
+        outputsForDevice = new HashMap<>();
+        flowsForDevice = new HashMap<>();
+        resultMessage = new StringBuilder();
+    }
+
+    /**
+     * Return the initial packet.
+     *
+     * @return the initial packet in the form of a selector.
+     */
+    public TrafficSelector getInitialPacket() {
+        return inPacket;
+    }
+
+    /**
+     * Returns the first connect point the packet came in through.
+     *
+     * @return the connect point
+     */
+    public ConnectPoint getInitialConnectPoint() {
+        return in;
+    }
+
+    /**
+     * Add a result message for the Trace.
+     *
+     * @param resultMessage the message
+     */
+    public void addResultMessage(String resultMessage) {
+        if (this.resultMessage.length() != 0) {
+            this.resultMessage.append("\n");
+        }
+        this.resultMessage.append(resultMessage);
+    }
+
+    /**
+     * Return the result message.
+     *
+     * @return the message
+     */
+    public String resultMessage() {
+        return resultMessage.toString();
+    }
+
+    /**
+     * Adds the groups for a given device.
+     *
+     * @param deviceId   the device
+     * @param outputPath the groups in device objects
+     */
+    public void addGroupOutputPath(DeviceId deviceId, GroupsInDevice outputPath) {
+        if (!outputsForDevice.containsKey(deviceId)) {
+            outputsForDevice.put(deviceId, new ArrayList<>());
+        }
+        outputsForDevice.get(deviceId).add(outputPath);
+    }
+
+    /**
+     * Returns all the possible group-based outputs for a given device.
+     *
+     * @param deviceId the device
+     * @return the list of Groups for this device.
+     */
+    public List<GroupsInDevice> getGroupOuputs(DeviceId deviceId) {
+        return outputsForDevice.get(deviceId);
+    }
+
+    /**
+     * Adds a complete possible path.
+     *
+     * @param completePath the path
+     */
+    public void addCompletePath(List<ConnectPoint> completePath) {
+        completePaths.add(completePath);
+    }
+
+    /**
+     * Return all the possible path the packet can take through the network.
+     *
+     * @return a list of paths
+     */
+    public List<List<ConnectPoint>> getCompletePaths() {
+        return completePaths;
+    }
+
+    /**
+     * Add the flows traversed by the packet in a given device.
+     *
+     * @param deviceId the device considered
+     * @param flows    the flows
+     */
+    public void addFlowsForDevice(DeviceId deviceId, List<FlowEntry> flows) {
+        flowsForDevice.put(deviceId, flows);
+    }
+
+    /**
+     * Returns the flows matched by this trace's packet for a given device.
+     *
+     * @param deviceId the device
+     * @return the flows matched
+     */
+    public List<FlowEntry> getFlowsForDevice(DeviceId deviceId) {
+        return flowsForDevice.get(deviceId);
+    }
+
+    @Override
+    public String toString() {
+        return "StaticPacketTrace{" +
+                "inPacket=" + inPacket +
+                ", in=" + in +
+                ", completePaths=" + completePaths +
+                ", outputsForDevice=" + outputsForDevice +
+                ", flowsForDevice=" + flowsForDevice +
+                ", resultMessage=" + resultMessage +
+                '}';
+    }
 }
diff --git a/apps/t3/src/main/java/org/onosproject/t3/cli/TroubleshootTraceCommand.java b/apps/t3/src/main/java/org/onosproject/t3/cli/TroubleshootTraceCommand.java
new file mode 100644
index 0000000..a42872a
--- /dev/null
+++ b/apps/t3/src/main/java/org/onosproject/t3/cli/TroubleshootTraceCommand.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.t3.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onlab.packet.EthType;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.TpPort;
+import org.onlab.packet.VlanId;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.t3.api.StaticPacketTrace;
+import org.onosproject.t3.api.TroubleshootService;
+
+import java.util.List;
+
+/**
+ * Starts a Static Packet Trace for a given input and prints the result.
+ */
+@Command(scope = "onos", name = "troubleshoot",
+        description = "troubleshoots flows and groups between source and destination")
+public class TroubleshootTraceCommand extends AbstractShellCommand {
+
+
+    private static final String FLOW_SHORT_FORMAT = "    %s, bytes=%s, packets=%s, "
+            + "table=%s, priority=%s, selector=%s, treatment=%s";
+
+    private static final String GROUP_FORMAT =
+            "   id=0x%s, state=%s, type=%s, bytes=%s, packets=%s, appId=%s, referenceCount=%s";
+    private static final String GROUP_BUCKET_FORMAT =
+            "       id=0x%s, bucket=%s, bytes=%s, packets=%s, actions=%s";
+
+    @Option(name = "-v", aliases = "--verbose", description = "Outputs complete path")
+    private boolean verbosity1 = false;
+
+    @Option(name = "-vv", aliases = "--veryverbose", description = "Outputs flows and groups for every device")
+    private boolean verbosity2 = false;
+
+    @Option(name = "-s", aliases = "--srcIp", description = "Source IP")
+    String srcIp = null;
+
+    @Option(name = "-sp", aliases = "--srcPort", description = "Source Port", required = true)
+    String srcPort = null;
+
+    @Option(name = "-sm", aliases = "--srcMac", description = "Source MAC")
+    String srcMac = null;
+
+    @Option(name = "-et", aliases = "--ethType", description = "ETH Type", valueToShowInHelp = "ipv4")
+    String ethType = "ipv4";
+
+    @Option(name = "-stp", aliases = "--srcTcpPort", description = "Source TCP Port")
+    String srcTcpPort = null;
+
+    @Option(name = "-d", aliases = "--dstIp", description = "Destination IP", valueToShowInHelp = "255.255.255.255")
+    String dstIp = "255.255.255.255";
+
+    @Option(name = "-dm", aliases = "--dstMac", description = "Destination MAC")
+    String dstMac = null;
+
+    @Option(name = "-dtp", aliases = "dstTcpPort", description = "destination TCP Port")
+    String dstTcpPort = null;
+
+    @Option(name = "-vid", aliases = "--vlanId", description = "Vlan of incoming packet", valueToShowInHelp = "None")
+    String vlan = "None";
+
+    @Option(name = "-mb", aliases = "--mplsBos", description = "MPLS BOS", valueToShowInHelp = "True")
+    String mplsBos = "true";
+
+    @Override
+    protected void execute() {
+        TroubleshootService service = get(TroubleshootService.class);
+        ConnectPoint cp = ConnectPoint.deviceConnectPoint(srcPort);
+
+        //Input Port must be specified
+        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder()
+                .matchInPort(cp.port());
+
+        if (srcIp != null) {
+            selectorBuilder.matchIPSrc(IpAddress.valueOf(srcIp).toIpPrefix());
+        }
+
+        if (srcMac != null) {
+            selectorBuilder.matchEthSrc(MacAddress.valueOf(srcMac));
+        }
+
+        //if EthType option is not specified using IPv4
+        selectorBuilder.matchEthType(EthType.EtherType.valueOf(ethType.toUpperCase()).ethType().toShort());
+
+        if (srcTcpPort != null) {
+            selectorBuilder.matchTcpSrc(TpPort.tpPort(Integer.parseInt(srcTcpPort)));
+        }
+
+        //if destination Ip option is not specified using broadcast 255.255.255.255
+        selectorBuilder.matchIPDst(IpAddress.valueOf(dstIp).toIpPrefix());
+
+        if (dstMac != null) {
+            selectorBuilder.matchEthDst(MacAddress.valueOf(dstMac));
+        }
+        if (dstTcpPort != null) {
+            selectorBuilder.matchTcpDst(TpPort.tpPort(Integer.parseInt(dstTcpPort)));
+        }
+
+        //if vlan option is not specified using NONE
+        selectorBuilder.matchVlanId(VlanId.vlanId(vlan));
+
+        //if mplsBos option is not specified using True
+        selectorBuilder.matchMplsBos(Boolean.valueOf(mplsBos));
+
+        TrafficSelector packet = selectorBuilder.build();
+
+        //Printing the created packet
+        print("Tracing packet: %s", packet.criteria());
+
+        //Build the trace
+        StaticPacketTrace trace = service.trace(packet, cp);
+
+        //Print based on verbosity
+        if (verbosity1) {
+            printTrace(trace, false);
+        } else if (verbosity2) {
+            printTrace(trace, true);
+        } else {
+            print("Paths");
+            List<List<ConnectPoint>> paths = trace.getCompletePaths();
+            paths.forEach(path -> print("%s", path));
+        }
+        print("Result: \n%s", trace.resultMessage());
+    }
+
+    //prints the trace
+    private void printTrace(StaticPacketTrace trace, boolean verbose) {
+        List<List<ConnectPoint>> paths = trace.getCompletePaths();
+        paths.forEach(path -> {
+            print("Path %s", path);
+            ConnectPoint previous = null;
+            for (ConnectPoint connectPoint : path) {
+                if (previous == null || !previous.deviceId().equals(connectPoint.deviceId())) {
+                    print("Device %s", connectPoint.deviceId());
+                    print("Input from %s", connectPoint);
+                    printFlows(trace, verbose, connectPoint);
+                } else {
+                    printGroups(trace, verbose, connectPoint);
+                    print("Output through %s", connectPoint);
+                    print("");
+                }
+                previous = connectPoint;
+            }
+        });
+    }
+
+    //Prints the flows for a given trace and a specified level of verbosity
+    private void printFlows(StaticPacketTrace trace, boolean verbose, ConnectPoint connectPoint) {
+        print("Flows");
+        trace.getFlowsForDevice(connectPoint.deviceId()).forEach(f -> {
+            if (verbose) {
+                print(FLOW_SHORT_FORMAT, f.state(), f.bytes(), f.packets(),
+                        f.table(), f.priority(), f.selector().criteria(),
+                        printTreatment(f.treatment()));
+            } else {
+                print("   flowId=%s, selector=%s ", f.id(), f.selector().criteria());
+            }
+        });
+    }
+
+    //Prints the groups for a given trace and a specified level of verbosity
+    private void printGroups(StaticPacketTrace trace, boolean verbose, ConnectPoint connectPoint) {
+        print("Groups");
+        trace.getGroupOuputs(connectPoint.deviceId()).forEach(output -> {
+            if (output.getOutput().equals(connectPoint)) {
+                output.getGroups().forEach(group -> {
+                    if (verbose) {
+                        print(GROUP_FORMAT, Integer.toHexString(group.id().id()), group.state(), group.type(),
+                                group.bytes(), group.packets(), group.appId().name(), group.referenceCount());
+                        int i = 0;
+                        for (GroupBucket bucket : group.buckets().buckets()) {
+                            print(GROUP_BUCKET_FORMAT, Integer.toHexString(group.id().id()), ++i,
+                                    bucket.bytes(), bucket.packets(),
+                                    bucket.treatment().allInstructions());
+                        }
+                    } else {
+                        print("   groupId=%s", group.id());
+                    }
+                });
+                print("Outgoing Packet %s", output.getFinalPacket());
+            }
+        });
+    }
+
+    private String printTreatment(TrafficTreatment treatment) {
+        final String delimiter = ", ";
+        StringBuilder builder = new StringBuilder("[");
+        if (!treatment.immediate().isEmpty()) {
+            builder.append("immediate=" + treatment.immediate() + delimiter);
+        }
+        if (!treatment.deferred().isEmpty()) {
+            builder.append("deferred=" + treatment.deferred() + delimiter);
+        }
+        if (treatment.clearedDeferred()) {
+            builder.append("clearDeferred" + delimiter);
+        }
+        if (treatment.tableTransition() != null) {
+            builder.append("transition=" + treatment.tableTransition() + delimiter);
+        }
+        if (treatment.metered() != null) {
+            builder.append("meter=" + treatment.metered() + delimiter);
+        }
+        if (treatment.writeMetadata() != null) {
+            builder.append("metadata=" + treatment.writeMetadata() + delimiter);
+        }
+        // Chop off last delimiter
+        builder.replace(builder.length() - delimiter.length(), builder.length(), "");
+        builder.append("]");
+        return builder.toString();
+    }
+}
diff --git a/apps/t3/src/main/java/org/onosproject/t3/impl/Subnet.java b/apps/t3/src/main/java/org/onosproject/t3/impl/Subnet.java
new file mode 100644
index 0000000..ac5a741
--- /dev/null
+++ b/apps/t3/src/main/java/org/onosproject/t3/impl/Subnet.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.t3.impl;
+
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Utility class to test if an Ip is in a given subnet.
+ */
+public class Subnet {
+    private final int bytesSubnetCount;
+    private final BigInteger bigMask;
+    private final BigInteger bigSubnetMasked;
+
+    /**
+     * Constructor for use via format "192.168.0.0/24" or "2001:db8:85a3:880:0:0:0:0/57".
+     * @param subnetAddress the address
+     * @param bits the mask
+     */
+    public Subnet(InetAddress subnetAddress, int bits) {
+        bytesSubnetCount = subnetAddress.getAddress().length; // 4 or 16
+        bigMask = BigInteger.valueOf(-1).shiftLeft(bytesSubnetCount * 8 - bits); // mask = -1 << 32 - bits
+        bigSubnetMasked = new BigInteger(subnetAddress.getAddress()).and(bigMask);
+    }
+
+    /**
+     * Constructor for use via format "192.168.0.0/255.255.255.0" or single address.
+     * @param subnetAddress the address
+     * @param mask the mask
+     */
+    public Subnet(InetAddress subnetAddress, InetAddress mask) {
+        bytesSubnetCount = subnetAddress.getAddress().length;
+        // no mask given case is handled here.
+        bigMask = null == mask ? BigInteger.valueOf(-1) : new BigInteger(mask.getAddress());
+        bigSubnetMasked = new BigInteger(subnetAddress.getAddress()).and(bigMask);
+    }
+
+    /**
+     * Subnet factory method.
+     *
+     * @param subnetMask format: "192.168.0.0/24" or "192.168.0.0/255.255.255.0"
+     *                   or single address or "2001:db8:85a3:880:0:0:0:0/57"
+     * @return a new instance
+     * @throws UnknownHostException thrown if unsupported subnet mask.
+     */
+    public static Subnet createInstance(String subnetMask)
+            throws UnknownHostException {
+        final String[] stringArr = subnetMask.split("/");
+        if (2 > stringArr.length) {
+            return new Subnet(InetAddress.getByName(stringArr[0]), (InetAddress) null);
+        } else if (stringArr[1].contains(".") || stringArr[1].contains(":")) {
+            return new Subnet(InetAddress.getByName(stringArr[0]), InetAddress.getByName(stringArr[1]));
+        } else {
+            return new Subnet(InetAddress.getByName(stringArr[0]), Integer.parseInt(stringArr[1]));
+        }
+    }
+
+    /**
+     * Tests if the address is in the given subnet.
+     * @param address the address to test.
+     * @return true if inside the subnet
+     */
+    public boolean isInSubnet(InetAddress address) {
+        byte[] bytesAddress = address.getAddress();
+        if (this.bytesSubnetCount != bytesAddress.length) {
+            return false;
+        }
+        BigInteger bigAddress = new BigInteger(bytesAddress);
+        return bigAddress.and(this.bigMask).equals(this.bigSubnetMasked);
+    }
+
+    @Override
+    public final boolean equals(Object obj) {
+        if (!(obj instanceof Subnet)) {
+            return false;
+        }
+        final Subnet other = (Subnet) obj;
+        return bigSubnetMasked.equals(other.bigSubnetMasked) &&
+                bigMask.equals(other.bigMask) &&
+                bytesSubnetCount == other.bytesSubnetCount;
+    }
+
+    @Override
+    public final int hashCode() {
+        return bytesSubnetCount;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder buf = new StringBuilder();
+        bigInteger2IpString(buf, bigSubnetMasked, bytesSubnetCount);
+        buf.append('/');
+        bigInteger2IpString(buf, bigMask, bytesSubnetCount);
+        return buf.toString();
+    }
+
+    private void bigInteger2IpString(StringBuilder buf, BigInteger bigInteger, int displayBytes) {
+        boolean isIPv4 = 4 == displayBytes;
+        byte[] bytes = bigInteger.toByteArray();
+        int diffLen = displayBytes - bytes.length;
+        byte fillByte = 0 > (int) bytes[0] ? (byte) 0xFF : (byte) 0x00;
+
+        int integer;
+        for (int i = 0; i < displayBytes; i++) {
+            if (0 < i && !isIPv4 && i % 2 == 0) {
+                buf.append(':');
+            } else if (0 < i && isIPv4) {
+                buf.append('.');
+            }
+            integer = 0xFF & (i < diffLen ? fillByte : bytes[i - diffLen]);
+            if (!isIPv4 && 0x10 > integer) {
+                buf.append('0');
+            }
+            buf.append(isIPv4 ? integer : Integer.toHexString(integer));
+        }
+    }
+}
diff --git a/apps/t3/src/main/java/org/onosproject/t3/impl/TroubleshootManager.java b/apps/t3/src/main/java/org/onosproject/t3/impl/TroubleshootManager.java
index 03f1e75..1a5c946 100644
--- a/apps/t3/src/main/java/org/onosproject/t3/impl/TroubleshootManager.java
+++ b/apps/t3/src/main/java/org/onosproject/t3/impl/TroubleshootManager.java
@@ -16,22 +16,62 @@
 
 package org.onosproject.t3.impl;
 
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.VlanId;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.IndexTableId;
+import org.onosproject.net.flow.TableId;
 import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBucket;
 import org.onosproject.net.group.GroupService;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.t3.api.GroupsInDevice;
 import org.onosproject.t3.api.StaticPacketTrace;
 import org.onosproject.t3.api.TroubleshootService;
 import org.slf4j.Logger;
 
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.onlab.packet.EthType.EtherType;
+import static org.onosproject.net.flow.instructions.Instructions.GroupInstruction;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
- * Designates ...
+ * Manager to troubleshoot packets inside the network.
+ * Given a representation of a packet follows it's path in the network according to the existing flows and groups in
+ * the devices.
  */
 @Service
 @Component(immediate = true)
@@ -45,10 +85,554 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected GroupService groupService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkService linkService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DriverService driverService;
 
     @Override
     public StaticPacketTrace trace(TrafficSelector packet, ConnectPoint in) {
-        return null;
+        log.info("Tracing packet {} coming in through {}", packet, in);
+        StaticPacketTrace trace = new StaticPacketTrace(packet, in);
+        //FIXME this can be done recursively
+        trace = traceInDevice(trace, packet, in);
+        //Building output connect Points
+        List<ConnectPoint> path = new ArrayList<>();
+        trace = getTrace(path, in, trace);
+        return trace;
+    }
+
+    /**
+     * Computes a trace for a give packet that start in the network at the given connect point.
+     *
+     * @param completePath the path traversed by the packet
+     * @param in           the input connect point
+     * @param trace        the trace to build
+     * @return the build trace for that packet.
+     */
+    private StaticPacketTrace getTrace(List<ConnectPoint> completePath, ConnectPoint in, StaticPacketTrace trace) {
+
+        //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());
+            return trace;
+        }
+
+        //let's add the input connect point
+        completePath.add(in);
+
+        //If the trace has no outputs for the given input we stop here
+        if (trace.getGroupOuputs(in.deviceId()) == null) {
+            computePath(completePath, trace, null);
+            trace.addResultMessage("No output out of device " + in.deviceId() + ". Packet is dropped");
+            return trace;
+        }
+        //If the trace has ouputs we analyze them all
+        for (GroupsInDevice outputPath : trace.getGroupOuputs(in.deviceId())) {
+            log.debug("Output path {}", outputPath.getOutput());
+            //Hosts for the the given output
+            Set<Host> hostsList = hostService.getConnectedHosts(outputPath.getOutput());
+            //Hosts queried from the original ip or mac
+            Set<Host> hosts = getHosts(trace);
+
+            //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");
+                trace.addResultMessage("Reached required destination Host");
+                computePath(completePath, trace, outputPath.getOutput());
+                break;
+            } else {
+                ConnectPoint cp = outputPath.getOutput();
+                //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);
+                //No links means that the packet gets dropped.
+                if (links.size() == 0) {
+                    log.warn("No links out of {}", cp);
+                    computePath(completePath, trace, cp);
+                    trace.addResultMessage("No links depart from " + cp + ". Packet is dropped");
+                    return trace;
+                }
+                //For each link we trace the corresponding device
+                for (Link link : links) {
+                    ConnectPoint dst = link.dst();
+                    //change in-port to the dst link in port
+                    TrafficSelector.Builder updatedPacket = DefaultTrafficSelector.builder();
+                    outputPath.getFinalPacket().criteria().forEach(updatedPacket::add);
+                    updatedPacket.add(Criteria.matchInPort(dst.port()));
+                    log.debug("DST Connect Point {}", dst);
+                    //build the elements for that device
+                    traceInDevice(trace, updatedPacket.build(), dst);
+                    //continue the trace along the path
+                    getTrace(completePath, dst, trace);
+                }
+
+            }
+        }
+        return trace;
+    }
+
+    /**
+     * Checks if the path contains the device.
+     *
+     * @param completePath the path
+     * @param deviceId     the device to check
+     * @return true if the path contains the device
+     */
+    //TODO might prove costly, improvement: a class with both CPs and DeviceIds point.
+    private boolean pathContainsDevice(List<ConnectPoint> completePath, DeviceId deviceId) {
+        for (ConnectPoint cp : completePath) {
+            if (cp.deviceId().equals(deviceId)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Gets the hosts for the given initial packet.
+     *
+     * @param trace the trace we are building
+     * @return set of the hosts we are trying to reach
+     */
+    private Set<Host> getHosts(StaticPacketTrace trace) {
+        IPCriterion ipv4Criterion = ((IPCriterion) trace.getInitialPacket()
+                .getCriterion(Criterion.Type.IPV4_DST));
+        IPCriterion ipv6Criterion = ((IPCriterion) trace.getInitialPacket()
+                .getCriterion(Criterion.Type.IPV6_DST));
+        Set<Host> hosts = new HashSet<>();
+        if (ipv4Criterion != null) {
+            hosts.addAll(hostService.getHostsByIp(ipv4Criterion.ip().address()));
+        }
+        if (ipv6Criterion != null) {
+            hosts.addAll(hostService.getHostsByIp(ipv6Criterion.ip().address()));
+        }
+        EthCriterion ethCriterion = ((EthCriterion) trace.getInitialPacket()
+                .getCriterion(Criterion.Type.ETH_DST));
+        if (ethCriterion != null) {
+            hosts.addAll(hostService.getHostsByMac(ethCriterion.mac()));
+        }
+        return hosts;
+    }
+
+    /**
+     * Computes the list of traversed connect points.
+     *
+     * @param completePath the list of devices
+     * @param trace        the trace we are building
+     * @param output       the final output connect point
+     */
+    private void computePath(List<ConnectPoint> completePath, StaticPacketTrace trace, ConnectPoint output) {
+        List<ConnectPoint> traverseList = new ArrayList<>();
+        if (!completePath.contains(trace.getInitialConnectPoint())) {
+            traverseList.add(trace.getInitialConnectPoint());
+        }
+        traverseList.addAll(completePath);
+        if (output != null && !completePath.contains(output)) {
+            traverseList.add(output);
+        }
+        trace.addCompletePath(traverseList);
+        completePath.clear();
+    }
+
+    /**
+     * Traces the packet inside a device starting from an input connect point.
+     *
+     * @param trace  the trace we are building
+     * @param packet the packet we are tracing
+     * @param in     the input connect point.
+     * @return updated trace
+     */
+    private StaticPacketTrace traceInDevice(StaticPacketTrace trace, TrafficSelector packet, ConnectPoint in) {
+        log.debug("Packet {} coming in from {}", packet, in);
+        List<FlowEntry> flows = new ArrayList<>();
+        List<FlowEntry> outputFlows = new ArrayList<>();
+
+        FlowEntry nextTableIdEntry = findNextTableIdEntry(in.deviceId(), -1);
+        if (nextTableIdEntry == null) {
+            trace.addResultMessage("No flow rules for device " + in.deviceId() + ". Aborting");
+            return trace;
+        }
+        TableId tableId = nextTableIdEntry.table();
+        FlowEntry flowEntry;
+        boolean output = false;
+        while (!output) {
+            log.debug("Searching a Flow Entry on table {} for packet {}", tableId, packet);
+            //get the rule that matches the incoming packet
+            flowEntry = matchHighestPriority(packet, in, tableId);
+            log.debug("Found Flow Entry {}", flowEntry);
+
+            boolean isOfdpaHardware = TroubleshootUtils.hardwareOfdpaMap
+                    .getOrDefault(driverService.getDriver(in.deviceId()).name(), false);
+
+            //if the flow entry on a table is null and we are on hardware we treat as table miss, with few exceptions
+            if (flowEntry == null && isOfdpaHardware) {
+                log.debug("Ofdpa Hw setup, no flow rule means table miss");
+
+                //Handling Hardware Specifics
+                if (((IndexTableId) tableId).id() == 27) {
+                    //Apparently a miss but Table 27 on OFDPA is a fixed table
+                    packet = handleOfdpa27FixedTable(trace, packet);
+                }
+
+                //Finding next table to go In case of miss
+                nextTableIdEntry = findNextTableIdEntry(in.deviceId(), ((IndexTableId) tableId).id());
+                log.debug("Next table id entry {}", nextTableIdEntry);
+
+                //FIXME find better solution that enable granularity greater than 0 or all rules
+                //(another possibility is max tableId)
+                if (nextTableIdEntry == null && flows.size() == 0) {
+                    trace.addResultMessage("No flow rules for device" + in.deviceId() + ". Aborting");
+                    return trace;
+
+                } else if (nextTableIdEntry == null) {
+                    //Means that no more flow rules are present
+                    output = true;
+
+                } else if (((IndexTableId) tableId).id() == 20) {
+                    //if the table is 20 OFDPA skips to table 50
+                    log.debug("A miss on Table 20 on OFDPA means that we skip directly to table 50");
+                    tableId = IndexTableId.of(50);
+
+                } else {
+                    tableId = nextTableIdEntry.table();
+                }
+
+
+            } else if (flowEntry == null) {
+                trace.addResultMessage("Packet has no match on table " + tableId + " in device " +
+                        in.deviceId() + ". Dropping");
+                return trace;
+            } else {
+                //IF the table has a transition
+                if (flowEntry.treatment().tableTransition() != null) {
+                    //update the next table we transitions to
+                    tableId = IndexTableId.of(flowEntry.treatment().tableTransition().tableId());
+                    log.debug("Flow Entry has transition to table Id {}", tableId);
+                    flows.add(flowEntry);
+                } else {
+                    //table has no transition so it means that it's an output rule if on the last table
+                    log.debug("Flow Entry has no transition to table, treating as last rule {}", flowEntry);
+                    flows.add(flowEntry);
+                    outputFlows.add(flowEntry);
+                    output = true;
+                }
+                //update the packet according to the actions of this flow rule.
+                packet = updatePacket(packet, flowEntry.treatment().allInstructions()).build();
+            }
+        }
+
+        //Creating a modifiable builder for the output packet
+        TrafficSelector.Builder builder = DefaultTrafficSelector.builder();
+        packet.criteria().forEach(builder::add);
+        //Adding all the flows to the trace
+        trace.addFlowsForDevice(in.deviceId(), flows);
+
+        log.debug("Flows traversed by {}", packet);
+        flows.forEach(entry -> {
+            log.debug("Flow {}", entry);
+        });
+
+        log.debug("Output Flows for {}", packet);
+        outputFlows.forEach(entry -> {
+            log.debug("Output Flow {}", entry);
+        });
+        List<PortNumber> outputPorts = new ArrayList<>();
+
+        //Decide Output for packet when flow rule contains an OUTPUT instruction
+        Set<Instruction> outputFlowEntries = outputFlows.stream().flatMap(flow -> {
+            return flow.treatment().allInstructions().stream();
+        })
+                .filter(instruction -> {
+                    return instruction.type().equals(Instruction.Type.OUTPUT);
+                }).collect(Collectors.toSet());
+        log.debug("Output instructions {}", outputFlowEntries);
+
+        if (outputFlowEntries.size() != 0) {
+            outputThroughFlows(trace, packet, in, builder, outputPorts, outputFlowEntries);
+
+        } else {
+            log.debug("Handling Groups");
+            //Analyze Groups
+            List<Group> groups = new ArrayList<>();
+
+            for (FlowEntry entry : flows) {
+                getGroupsFromInstructions(trace, groups, entry.treatment().allInstructions(),
+                        entry.deviceId(), builder, outputPorts);
+            }
+            packet = builder.build();
+            log.debug("Groups hit by packet {}", packet);
+            groups.forEach(group -> {
+                log.debug("Group {}", group);
+            });
+        }
+        log.debug("Output ports for packet {}", packet);
+        outputPorts.forEach(port -> {
+            log.debug("Port {}", port);
+        });
+        log.debug("Output Packet {}", packet);
+        return trace;
+    }
+
+    /**
+     * Method that saves the output if that si done via an OUTPUT treatment of a flow rule.
+     *
+     * @param trace             the trace
+     * @param packet            the packet coming in to this device
+     * @param in                the input connect point for this device
+     * @param builder           the updated packet0
+     * @param outputPorts       the list of output ports for this device
+     * @param outputFlowEntries the list of flow entries with OUTPUT treatment
+     */
+    private void outputThroughFlows(StaticPacketTrace trace, TrafficSelector packet, ConnectPoint in,
+                                    TrafficSelector.Builder builder, List<PortNumber> outputPorts,
+                                    Set<Instruction> outputFlowEntries) {
+        if (outputFlowEntries.size() > 1) {
+            log.warn("There cannot be more than one OUTPUT instruction for {}", packet);
+        } else {
+            OutputInstruction outputInstruction = (OutputInstruction) outputFlowEntries.iterator().next();
+            //FIXME using GroupsInDevice for output even if flows.
+            trace.addGroupOutputPath(in.deviceId(),
+                    new GroupsInDevice(ConnectPoint.deviceConnectPoint(in.deviceId()
+                            + "/" + outputInstruction.port()),
+                            ImmutableList.of(), builder.build()));
+            outputPorts.add(outputInstruction.port());
+        }
+    }
+
+    /**
+     * Handles table 27 in Ofpda which is a fixed table not visible to any controller that handles Mpls Labels.
+     *
+     * @param packet the incoming packet
+     * @return the updated packet
+     */
+    private TrafficSelector handleOfdpa27FixedTable(StaticPacketTrace trace, TrafficSelector packet) {
+        log.debug("Handling table 27 on OFDPA, removing mpls ETH Type and change mpls label");
+        Criterion mplsCriterion = packet.getCriterion(Criterion.Type.ETH_TYPE);
+        ImmutableList.Builder<Instruction> builder = ImmutableList.builder();
+
+        //If the pakcet comes in with the expected elements we update it as per OFDPA spec.
+        if (mplsCriterion != null && ((EthTypeCriterion) mplsCriterion).ethType()
+                .equals(EtherType.MPLS_UNICAST.ethType())) {
+            Instruction ethInstruction = Instructions.popMpls(((EthTypeCriterion) trace.getInitialPacket()
+                    .getCriterion(Criterion.Type.ETH_TYPE)).ethType());
+            //FIXME what do we use as L3_Unicast mpls Label ?
+            builder.add(ethInstruction);
+        }
+        packet = updatePacket(packet, builder.build()).build();
+        return packet;
+    }
+
+    /**
+     * Finds the flow entry with the minimun next table Id.
+     *
+     * @param deviceId  the device to search
+     * @param currentId the current id. the search will use this as minimum
+     * @return the flow entry with the minimum table Id after the given one.
+     */
+    private FlowEntry findNextTableIdEntry(DeviceId deviceId, int currentId) {
+
+        final Comparator<FlowEntry> comparator = Comparator.comparing((FlowEntry f) -> ((IndexTableId) f.table()).id());
+
+        return Lists.newArrayList(flowRuleService.getFlowEntries(deviceId).iterator())
+                .stream().filter(f -> ((IndexTableId) f.table()).id() > currentId).min(comparator).orElse(null);
+    }
+
+    /**
+     * Gets group information from instructions.
+     *
+     * @param trace           the trace we are building
+     * @param groupsForDevice the set of groups for this device
+     * @param instructions    the set of instructions we are searching for groups.
+     * @param deviceId        the device we are considering
+     * @param builder         the builder of the input packet
+     * @param outputPorts     the output ports for that packet
+     */
+    private void getGroupsFromInstructions(StaticPacketTrace trace, List<Group> groupsForDevice,
+                                           List<Instruction> instructions, DeviceId deviceId,
+                                           TrafficSelector.Builder builder, List<PortNumber> outputPorts) {
+        List<Instruction> groupInstructionlist = new ArrayList<>();
+        for (Instruction instruction : instructions) {
+            log.debug("Considering Instruction {}", instruction);
+            //if the instruction is not group we need to update the packet or add the output
+            //to the possible outputs for this packet
+            if (!instruction.type().equals(Instruction.Type.GROUP)) {
+                //if the instruction is not group we need to update the packet or add the output
+                //to the possible outputs for this packet
+                if (instruction.type().equals(Instruction.Type.OUTPUT)) {
+                    outputPorts.add(((OutputInstruction) instruction).port());
+                    trace.addGroupOutputPath(deviceId,
+                            new GroupsInDevice(ConnectPoint.deviceConnectPoint(deviceId + "/" +
+                                    ((OutputInstruction) instruction).port()),
+                                    groupsForDevice, builder.build()));
+                } else {
+                    builder = translateInstruction(builder, instruction);
+                }
+            } else {
+                //if the instuction is pointing to a group we need to get the group
+                groupInstructionlist.add(instruction);
+            }
+        }
+        //handle all the internal instructions pointing to a group.
+        for (Instruction instr : groupInstructionlist) {
+            GroupInstruction groupInstruction = (GroupInstruction) instr;
+            Group group = Lists.newArrayList(groupService.getGroups(deviceId)).stream().filter(groupInternal -> {
+                return groupInternal.id().equals(groupInstruction.groupId());
+            }).findAny().orElse(null);
+            if (group == null) {
+                trace.addResultMessage("Null group for Instruction " + instr);
+                break;
+            }
+            //add the group to the traversed groups
+            groupsForDevice.add(group);
+            //Cycle in each of the group's buckets and add them to the groups for this Device.
+            for (GroupBucket bucket : group.buckets().buckets()) {
+                getGroupsFromInstructions(trace, groupsForDevice, bucket.treatment().allInstructions(),
+                        deviceId, builder, outputPorts);
+            }
+        }
+    }
+
+    /**
+     * Applies all give instructions to the input packet.
+     *
+     * @param packet       the input packet
+     * @param instructions the set of instructions
+     * @return the packet with the applied instructions
+     */
+    private TrafficSelector.Builder updatePacket(TrafficSelector packet, List<Instruction> instructions) {
+        TrafficSelector.Builder newSelector = DefaultTrafficSelector.builder();
+        packet.criteria().forEach(newSelector::add);
+        instructions.forEach(instruction -> {
+            translateInstruction(newSelector, instruction);
+        });
+        return newSelector;
+    }
+
+    /**
+     * Applies an instruction to the packet in the form of a selector.
+     *
+     * @param newSelector the packet selector
+     * @param instruction the instruction to be translated
+     * @return the new selector with the applied instruction
+     */
+    private TrafficSelector.Builder translateInstruction(TrafficSelector.Builder newSelector, Instruction instruction) {
+        log.debug("Translating instruction {}", instruction);
+        //TODO add as required
+        Criterion criterion = null;
+        switch (instruction.type()) {
+            case L2MODIFICATION:
+                L2ModificationInstruction l2Instruction = (L2ModificationInstruction) instruction;
+                switch (l2Instruction.subtype()) {
+                    case VLAN_ID:
+                        L2ModificationInstruction.ModVlanIdInstruction vlanIdInstruction =
+                                (L2ModificationInstruction.ModVlanIdInstruction) instruction;
+                        VlanId id = vlanIdInstruction.vlanId();
+                        criterion = Criteria.matchVlanId(id);
+                        break;
+                    case VLAN_POP:
+                        criterion = Criteria.matchVlanId(VlanId.NONE);
+                        break;
+                    case MPLS_PUSH:
+                        L2ModificationInstruction.ModMplsHeaderInstruction mplsEthInstruction =
+                                (L2ModificationInstruction.ModMplsHeaderInstruction) instruction;
+                        criterion = Criteria.matchEthType(mplsEthInstruction.ethernetType().toShort());
+                        break;
+                    case MPLS_POP:
+                        L2ModificationInstruction.ModMplsHeaderInstruction mplsPopInstruction =
+                                (L2ModificationInstruction.ModMplsHeaderInstruction) instruction;
+                        criterion = Criteria.matchEthType(mplsPopInstruction.ethernetType().toShort());
+                        break;
+                    case MPLS_LABEL:
+                        L2ModificationInstruction.ModMplsLabelInstruction mplsLabelInstruction =
+                                (L2ModificationInstruction.ModMplsLabelInstruction) instruction;
+                        criterion = Criteria.matchMplsLabel(mplsLabelInstruction.label());
+                        break;
+                    case ETH_DST:
+                        L2ModificationInstruction.ModEtherInstruction modEtherDstInstruction =
+                                (L2ModificationInstruction.ModEtherInstruction) instruction;
+                        criterion = Criteria.matchEthDst(modEtherDstInstruction.mac());
+                        break;
+                    case ETH_SRC:
+                        L2ModificationInstruction.ModEtherInstruction modEtherSrcInstruction =
+                                (L2ModificationInstruction.ModEtherInstruction) instruction;
+                        criterion = Criteria.matchEthSrc(modEtherSrcInstruction.mac());
+                        break;
+                    default:
+                        log.debug("Unsupported L2 Instruction");
+                        break;
+                }
+                break;
+            default:
+                log.debug("Unsupported Instruction");
+                break;
+        }
+        if (criterion != null) {
+            log.debug("Adding criterion {}", criterion);
+            newSelector.add(criterion);
+        }
+        return newSelector;
+    }
+
+    /**
+     * Finds the rule in the device that mathces the input packet and has the highest priority.
+     *
+     * @param packet  the input packet
+     * @param in      the connect point the packet comes in from
+     * @param tableId the table to search
+     * @return the flow entry
+     */
+    private FlowEntry matchHighestPriority(TrafficSelector packet, ConnectPoint in, TableId tableId) {
+        //Computing the possible match rules.
+        final Comparator<FlowEntry> comparator = Comparator.comparing(FlowRule::priority);
+        return Lists.newArrayList(flowRuleService.getFlowEntries(in.deviceId()).iterator())
+                .stream()
+                .filter(flowEntry -> {
+                    return flowEntry.table().equals(tableId);
+                })
+                .filter(flowEntry -> {
+                    return match(packet, flowEntry);
+                }).max(comparator).orElse(null);
+    }
+
+    /**
+     * Matches the packet with the given flow entry.
+     *
+     * @param packet    the packet to match
+     * @param flowEntry the flow entry to match the packet against
+     * @return true if the packet matches the flow.
+     */
+    private boolean match(TrafficSelector packet, FlowEntry flowEntry) {
+        //TODO handle MAC matching
+        return flowEntry.selector().criteria().stream().allMatch(criterion -> {
+            Criterion.Type type = criterion.type();
+            //If the critrion has IP we need to do LPM to establish matching.
+            if (type.equals(Criterion.Type.IPV4_SRC) || type.equals(Criterion.Type.IPV4_DST) ||
+                    type.equals(Criterion.Type.IPV6_SRC) || type.equals(Criterion.Type.IPV6_DST)) {
+                IPCriterion ipCriterion = (IPCriterion) criterion;
+                IPCriterion matchCriterion = (IPCriterion) packet.getCriterion(ipCriterion.type());
+                //if the packet does not have an IPv4 or IPv6 criterion we return true
+                if (matchCriterion == null) {
+                    return true;
+                }
+                try {
+                    Subnet subnet = Subnet.createInstance(ipCriterion.ip().toString());
+                    return subnet.isInSubnet(matchCriterion.ip().address().toInetAddress());
+                } catch (UnknownHostException e) {
+                    return false;
+                }
+                //we check that the packet contains the criterion provided by the flow rule.
+            } else {
+                return packet.criteria().contains(criterion);
+            }
+        });
     }
 }
diff --git a/apps/t3/src/main/java/org/onosproject/t3/impl/TroubleshootUtils.java b/apps/t3/src/main/java/org/onosproject/t3/impl/TroubleshootUtils.java
new file mode 100644
index 0000000..f89a413
--- /dev/null
+++ b/apps/t3/src/main/java/org/onosproject/t3/impl/TroubleshootUtils.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.t3.impl;
+
+import com.google.common.collect.ImmutableMap;
+
+import java.util.Map;
+
+/**
+ * Utility class for the troubleshooting tool.
+ */
+final class TroubleshootUtils {
+
+    private TroubleshootUtils() {
+        //Banning construction
+    }
+
+    /**
+     * Map defining if a specific driver is for a HW switch.
+     */
+    //Done with builder() instead of of() for clarity
+    static Map<String, Boolean> hardwareOfdpaMap = ImmutableMap.<String, Boolean>builder()
+            .put("ofdpa", true)
+            .put("ofdpa3", true)
+            .put("qmx-ofdpa3", true)
+            .put("as7712-32x-premium", true)
+            .put("as5912-54x-premium", true)
+            .put("as5916-54x-premium", true)
+            .put("accton-ofdpa3", true)
+            .put("znyx-ofdpa", true)
+            .build();
+}
diff --git a/apps/t3/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/t3/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100644
index 0000000..7da87bc
--- /dev/null
+++ b/apps/t3/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,26 @@
+<!--
+  ~ Copyright 2017-present Open Networking Foundation
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.t3.cli.TroubleshootTraceCommand"/>
+        </command>
+    </command-bundle>
+
+</blueprint>
+
+
diff --git a/apps/t3/src/test/org/onosproject/t3/impl/T3TestObjects.java b/apps/t3/src/test/org/onosproject/t3/impl/T3TestObjects.java
new file mode 100644
index 0000000..8a3f6eb
--- /dev/null
+++ b/apps/t3/src/test/org/onosproject/t3/impl/T3TestObjects.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.t3.impl;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.EthType;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.core.GroupId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.group.DefaultGroup;
+import org.onosproject.net.group.DefaultGroupBucket;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.provider.ProviderId;
+
+/**
+ * Helper class for objects related to the Troubleshoot Manager Test.
+ */
+final class T3TestObjects {
+
+    private static final String HOST_ONE_MAC = "00:00:00:00:00:01";
+    private static final String HOST_TWO_MAC = "00:00:00:00:00:02";
+    private static final String HOST_ONE_VLAN = "None";
+    private static final String HOST_TWO_VLAN = "None";
+    private static final String HOST_ONE = HOST_ONE_MAC + "/" + HOST_ONE_VLAN;
+    private static final String HOST_TWO = HOST_TWO_MAC + "/" + HOST_TWO_VLAN;
+
+    //Single Flow Test
+    static final DeviceId SINGLE_FLOW_DEVICE = DeviceId.deviceId("SingleFlowDevice");
+    private static final TrafficSelector SINGLE_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchInPort(PortNumber.portNumber(1))
+            .matchIPSrc(IpPrefix.valueOf("127.0.0.1/32"))
+            .matchIPDst(IpPrefix.valueOf("127.0.0.2/32"))
+            .build();
+
+    private static final TrafficTreatment OUTPUT_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .setOutput(PortNumber.portNumber(2)).build();
+    private static final FlowRule SINGLE_FLOW = DefaultFlowEntry.builder().forDevice(SINGLE_FLOW_DEVICE)
+            .forTable(0)
+            .withPriority(100)
+            .withSelector(SINGLE_FLOW_SELECTOR)
+            .withTreatment(OUTPUT_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    static final FlowEntry SINGLE_FLOW_ENTRY = new DefaultFlowEntry(SINGLE_FLOW);
+
+    static final ConnectPoint SINGLE_FLOW_IN_CP = ConnectPoint.deviceConnectPoint(SINGLE_FLOW_DEVICE + "/" + 1);
+
+    static final ConnectPoint SINGLE_FLOW_OUT_CP = ConnectPoint.deviceConnectPoint(SINGLE_FLOW_DEVICE + "/" + 2);
+
+    //Dual Flow Test
+    static final DeviceId DUAL_FLOW_DEVICE = DeviceId.deviceId("DualFlowDevice");
+    private static final TrafficTreatment TRANSITION_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .setVlanId(VlanId.vlanId((short) 100))
+            .transition(10)
+            .build();
+    private static final TrafficSelector VLAN_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchVlanId(VlanId.vlanId((short) 100))
+            .build();
+    private static final FlowRule FIRST_FLOW = DefaultFlowEntry.builder().forDevice(DUAL_FLOW_DEVICE)
+            .forTable(0)
+            .withPriority(100)
+            .withSelector(SINGLE_FLOW_SELECTOR)
+            .withTreatment(TRANSITION_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    static final FlowEntry FIRST_FLOW_ENTRY = new DefaultFlowEntry(FIRST_FLOW);
+    private static final FlowRule SECOND_FLOW = DefaultFlowEntry.builder().forDevice(DUAL_FLOW_DEVICE)
+            .forTable(10)
+            .withPriority(100)
+            .withSelector(VLAN_FLOW_SELECTOR)
+            .withTreatment(OUTPUT_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    static final FlowEntry SECOND_FLOW_ENTRY = new DefaultFlowEntry(SECOND_FLOW);
+
+    static final ConnectPoint DUAL_FLOW_IN_CP = ConnectPoint.deviceConnectPoint(DUAL_FLOW_DEVICE + "/" + 1);
+
+    static final ConnectPoint DUAL_FLOW_OUT_CP = ConnectPoint.deviceConnectPoint(DUAL_FLOW_DEVICE + "/" + 2);
+
+    //Flow and Group Test
+    static final DeviceId GROUP_FLOW_DEVICE = DeviceId.deviceId("GroupFlowDevice");
+
+    private static final GroupId GROUP_ID = GroupId.valueOf(1);
+
+    private static final TrafficTreatment GROUP_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .group(GROUP_ID)
+            .build();
+    private static final FlowRule GROUP_FLOW = DefaultFlowEntry.builder().forDevice(GROUP_FLOW_DEVICE)
+            .forTable(0)
+            .withPriority(100)
+            .withSelector(SINGLE_FLOW_SELECTOR)
+            .withTreatment(GROUP_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    static final FlowEntry GROUP_FLOW_ENTRY = new DefaultFlowEntry(GROUP_FLOW);
+
+    private static final GroupBucket BUCKET = DefaultGroupBucket.createSelectGroupBucket(OUTPUT_FLOW_TREATMENT);
+
+    private static final GroupBuckets BUCKETS = new GroupBuckets(ImmutableList.of(BUCKET));
+
+    static final Group GROUP = new DefaultGroup(GROUP_ID, GROUP_FLOW_DEVICE, Group.Type.SELECT, BUCKETS);
+
+    static final ConnectPoint GROUP_FLOW_IN_CP = ConnectPoint.deviceConnectPoint(GROUP_FLOW_DEVICE + "/" + 1);
+
+    static final ConnectPoint GROUP_FLOW_OUT_CP = ConnectPoint.deviceConnectPoint(GROUP_FLOW_DEVICE + "/" + 2);
+
+    //topology
+
+    static final DeviceId TOPO_FLOW_DEVICE = DeviceId.deviceId("SingleFlowDevice1");
+
+    static final DeviceId TOPO_FLOW_2_DEVICE = DeviceId.deviceId("SingleFlowDevice2");
+
+    static final DeviceId TOPO_FLOW_3_DEVICE = DeviceId.deviceId("SingleFlowDevice3");
+
+    private static final TrafficSelector TOPO_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchInPort(PortNumber.portNumber(1))
+            .matchIPSrc(IpPrefix.valueOf("127.0.0.1/32"))
+            .matchIPDst(IpPrefix.valueOf("127.0.0.3/32"))
+            .build();
+
+    private static final FlowRule TOPO_SINGLE_FLOW = DefaultFlowEntry.builder().forDevice(TOPO_FLOW_DEVICE)
+            .forTable(0)
+            .withPriority(100)
+            .withSelector(TOPO_FLOW_SELECTOR)
+            .withTreatment(OUTPUT_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+
+    static final FlowEntry TOPO_SINGLE_FLOW_ENTRY = new DefaultFlowEntry(TOPO_SINGLE_FLOW);
+
+    static final ConnectPoint TOPO_FLOW_1_IN_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_DEVICE + "/" + 1);
+
+    static final ConnectPoint TOPO_FLOW_1_OUT_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_DEVICE + "/" + 2);
+
+    static final ConnectPoint TOPO_FLOW_2_IN_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_2_DEVICE + "/" + 1);
+
+    static final ConnectPoint TOPO_FLOW_2_OUT_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_2_DEVICE + "/" + 2);
+
+    static final ConnectPoint TOPO_FLOW_3_IN_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_3_DEVICE + "/" + 1);
+
+    static final ConnectPoint TOPO_FLOW_3_OUT_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_3_DEVICE + "/" + 2);
+
+
+    //Topology with Groups
+
+    static final DeviceId TOPO_GROUP_FLOW_DEVICE = DeviceId.deviceId("TopoGroupFlowDevice");
+
+    private static final TrafficSelector TOPO_SECOND_INPUT_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchInPort(PortNumber.portNumber(3))
+            .matchIPSrc(IpPrefix.valueOf("127.0.0.1/32"))
+            .matchIPDst(IpPrefix.valueOf("127.0.0.3/32"))
+            .build();
+
+    private static final FlowRule TOPO_SECOND_INPUT_FLOW = DefaultFlowEntry.builder().forDevice(TOPO_FLOW_3_DEVICE)
+            .forTable(0)
+            .withPriority(100)
+            .withSelector(TOPO_SECOND_INPUT_FLOW_SELECTOR)
+            .withTreatment(OUTPUT_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+
+    private static final TrafficTreatment OUTPUT_2_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .setOutput(PortNumber.portNumber(3)).build();
+
+
+    private static final GroupId TOPO_GROUP_ID = GroupId.valueOf(1);
+
+    private static final TrafficTreatment TOPO_GROUP_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .group(TOPO_GROUP_ID)
+            .build();
+    private static final FlowRule TOPO_GROUP_FLOW = DefaultFlowEntry.builder().forDevice(TOPO_GROUP_FLOW_DEVICE)
+            .forTable(0)
+            .withPriority(100)
+            .withSelector(TOPO_FLOW_SELECTOR)
+            .withTreatment(TOPO_GROUP_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    static final FlowEntry TOPO_GROUP_FLOW_ENTRY = new DefaultFlowEntry(TOPO_GROUP_FLOW);
+
+    private static final GroupBucket BUCKET_2 = DefaultGroupBucket.createSelectGroupBucket(OUTPUT_2_FLOW_TREATMENT);
+
+    private static final GroupBuckets BUCKETS_MULTIPLE = new GroupBuckets(ImmutableList.of(BUCKET, BUCKET_2));
+
+    static final Group TOPO_GROUP = new DefaultGroup(TOPO_GROUP_ID, TOPO_GROUP_FLOW_DEVICE, Group.Type.SELECT, BUCKETS_MULTIPLE);
+
+    static final FlowEntry TOPO_SECOND_INPUT_FLOW_ENTRY = new DefaultFlowEntry(TOPO_SECOND_INPUT_FLOW);
+
+    static final DeviceId TOPO_FLOW_4_DEVICE = DeviceId.deviceId("SingleFlowDevice4");
+
+    static final ConnectPoint TOPO_FLOW_IN_CP = ConnectPoint.deviceConnectPoint(TOPO_GROUP_FLOW_DEVICE + "/" + 1);
+
+    static final ConnectPoint TOPO_FLOW_OUT_CP_1 = ConnectPoint.deviceConnectPoint(TOPO_GROUP_FLOW_DEVICE + "/" + 2);
+
+    protected static final ConnectPoint TOPO_FLOW_OUT_CP_2 = ConnectPoint.deviceConnectPoint(TOPO_GROUP_FLOW_DEVICE + "/" + 3);
+
+    static final ConnectPoint TOPO_FLOW_4_IN_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_4_DEVICE + "/" + 1);
+
+    static final ConnectPoint TOPO_FLOW_3_IN_2_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_3_DEVICE + "/" + 3);
+
+    static final ConnectPoint TOPO_FLOW_4_OUT_CP = ConnectPoint.deviceConnectPoint(TOPO_FLOW_4_DEVICE + "/" + 2);
+
+
+    //hardware
+
+    static final DeviceId HARDWARE_DEVICE = DeviceId.deviceId("HardwareDevice");
+
+    static final ConnectPoint HARDWARE_DEVICE_IN_CP = ConnectPoint.deviceConnectPoint(HARDWARE_DEVICE + "/" + 1);
+
+    static final ConnectPoint HARDWARE_DEVICE_OUT_CP = ConnectPoint.deviceConnectPoint(HARDWARE_DEVICE + "/" + 2);
+
+    private static final TrafficSelector HARDWARE_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchInPort(PortNumber.portNumber(1))
+            .matchIPSrc(IpPrefix.valueOf("127.0.0.1/32"))
+            .matchIPDst(IpPrefix.valueOf("127.0.0.2/32"))
+            .build();
+
+    private static final TrafficTreatment HW_TRANSITION_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .pushMpls()
+            .transition(27)
+            .build();
+
+    private static final FlowRule HARDWARE_FLOW = DefaultFlowEntry.builder().forDevice(TOPO_FLOW_3_DEVICE)
+            .forTable(0)
+            .withPriority(100)
+            .withSelector(HARDWARE_FLOW_SELECTOR)
+            .withTreatment(HW_TRANSITION_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+
+    static final FlowEntry HARDWARE_FLOW_ENTRY = new DefaultFlowEntry(HARDWARE_FLOW);
+
+    private static final TrafficSelector HARDWARE_ETH_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchInPort(PortNumber.portNumber(1))
+            .matchIPSrc(IpPrefix.valueOf("127.0.0.1/32"))
+            .matchIPDst(IpPrefix.valueOf("127.0.0.2/32"))
+            .matchEthType(EthType.EtherType.IPV4.ethType().toShort())
+            .build();
+
+    private static final FlowRule HARDWARE_ETH_FLOW = DefaultFlowEntry.builder().forDevice(TOPO_FLOW_3_DEVICE)
+            .forTable(30)
+            .withPriority(100)
+            .withSelector(HARDWARE_ETH_FLOW_SELECTOR)
+            .withTreatment(OUTPUT_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+
+    static final FlowEntry HARDWARE_ETH_FLOW_ENTRY = new DefaultFlowEntry(HARDWARE_ETH_FLOW);
+
+
+
+
+    //helper elements
+
+    static final Host H1 = new DefaultHost(ProviderId.NONE, HostId.hostId(HOST_ONE), MacAddress.valueOf(100),
+            VlanId.NONE, new HostLocation(SINGLE_FLOW_DEVICE, PortNumber.portNumber(2), 0),
+            ImmutableSet.of(IpAddress.valueOf("127.0.0.2")));
+
+    static final Host H2 = new DefaultHost(ProviderId.NONE, HostId.hostId(HOST_TWO), MacAddress.valueOf(100),
+            VlanId.NONE, new HostLocation(TOPO_FLOW_3_DEVICE, PortNumber.portNumber(2), 0),
+            ImmutableSet.of(IpAddress.valueOf("127.0.0.3")));
+
+    static final TrafficSelector PACKET_OK = DefaultTrafficSelector.builder()
+            .matchInPort(PortNumber.portNumber(1))
+            .matchIPSrc(IpPrefix.valueOf("127.0.0.1/32"))
+            .matchIPDst(IpPrefix.valueOf("127.0.0.2/32"))
+            .build();
+
+    static final TrafficSelector PACKET_OK_TOPO = DefaultTrafficSelector.builder()
+            .matchInPort(PortNumber.portNumber(1))
+            .matchIPSrc(IpPrefix.valueOf("127.0.0.1/32"))
+            .matchIPDst(IpPrefix.valueOf("127.0.0.3/32"))
+            .build();
+
+    static final TrafficSelector PACKET_FAIL = DefaultTrafficSelector.builder()
+            .matchInPort(PortNumber.portNumber(1))
+            .matchIPSrc(IpPrefix.valueOf("127.0.0.1/32"))
+            .matchIPDst(IpPrefix.valueOf("127.0.0.99/32"))
+            .build();
+}
diff --git a/apps/t3/src/test/org/onosproject/t3/impl/TroubleshootManagerTest.java b/apps/t3/src/test/org/onosproject/t3/impl/TroubleshootManagerTest.java
new file mode 100644
index 0000000..0417faf
--- /dev/null
+++ b/apps/t3/src/test/org/onosproject/t3/impl/TroubleshootManagerTest.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.t3.impl;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.EthType;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.Link;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.driver.DefaultDriver;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverServiceAdapter;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRuleServiceAdapter;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupServiceAdapter;
+import org.onosproject.net.host.HostServiceAdapter;
+import org.onosproject.net.link.LinkServiceAdapter;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.t3.api.StaticPacketTrace;
+import org.slf4j.Logger;
+
+import java.util.HashMap;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.t3.impl.T3TestObjects.*;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Test Class for Troubleshoot Manager.
+ */
+public class TroubleshootManagerTest {
+
+    private static final Logger log = getLogger(TroubleshootManager.class);
+
+    private TroubleshootManager mngr;
+
+    @Before
+    public void setUp() throws Exception {
+        mngr = new TroubleshootManager();
+        mngr.flowRuleService = new TestFlowRuleService();
+        mngr.hostService = new TestHostService();
+        mngr.linkService = new TestLinkService();
+        mngr.driverService = new TestDriverService();
+        mngr.groupService = new TestGroupService();
+
+        assertNotNull("Manager should not be null", mngr);
+
+        assertNotNull("Flow rule Service should not be null", mngr.flowRuleService);
+        assertNotNull("Host Service should not be null", mngr.hostService);
+        assertNotNull("Group Service should not be null", mngr.groupService);
+        assertNotNull("Driver Service should not be null", mngr.driverService);
+        assertNotNull("Link Service should not be null", mngr.linkService);
+    }
+
+    /**
+     * Tests failure on device with no flows
+     */
+    @Test
+    public void noFlows() {
+        StaticPacketTrace traceFail = mngr.trace(PACKET_OK, ConnectPoint.deviceConnectPoint("test/1"));
+        assertNotNull("Trace should not be null", traceFail);
+        assertNull("Trace should have 0 output", traceFail.getGroupOuputs(SINGLE_FLOW_DEVICE));
+        log.info("trace {}", traceFail.resultMessage());
+    }
+
+    /**
+     * Test a single flow rule that has output port in it.
+     */
+    @Test
+    public void testSingleFlowRule() {
+
+        testSuccess(PACKET_OK, SINGLE_FLOW_IN_CP, SINGLE_FLOW_DEVICE, SINGLE_FLOW_OUT_CP, 1);
+
+        testFaliure(PACKET_FAIL, SINGLE_FLOW_IN_CP, SINGLE_FLOW_DEVICE);
+    }
+
+    /**
+     * Tests two flow rule the last one of which has output port in it.
+     */
+    @Test
+    public void testDualFlowRule() {
+
+        //Test Success
+
+        StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, DUAL_FLOW_IN_CP, DUAL_FLOW_DEVICE, DUAL_FLOW_OUT_CP, 1);
+
+        //Testing Vlan
+        Criterion criterion = traceSuccess.getGroupOuputs(DUAL_FLOW_DEVICE).get(0).
+                getFinalPacket().getCriterion(Criterion.Type.VLAN_VID);
+        assertNotNull("Packet Should have Vlan", criterion);
+
+        VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) criterion;
+
+        assertEquals("Vlan should be 100", VlanId.vlanId((short) 100), vlanIdCriterion.vlanId());
+
+        //Test Faliure
+        testFaliure(PACKET_FAIL, DUAL_FLOW_IN_CP, DUAL_FLOW_DEVICE);
+
+    }
+
+    /**
+     * Test a single flow rule that points to a group with output port in it.
+     */
+    @Test
+    public void flowAndGroup() throws Exception {
+
+        StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, GROUP_FLOW_IN_CP, GROUP_FLOW_DEVICE, GROUP_FLOW_OUT_CP, 1);
+
+        assertTrue("Wrong Output Group", traceSuccess.getGroupOuputs(GROUP_FLOW_DEVICE)
+                .get(0).getGroups().contains(GROUP));
+
+    }
+
+    /**
+     * Test path through a 3 device topology.
+     */
+    @Test
+    public void singlePathTopology() throws Exception {
+
+        StaticPacketTrace traceSuccess = testSuccess(PACKET_OK_TOPO, TOPO_FLOW_1_IN_CP,
+                TOPO_FLOW_3_DEVICE, TOPO_FLOW_3_OUT_CP, 1);
+
+        assertTrue("Incorrect path",
+                traceSuccess.getCompletePaths().get(0).contains(TOPO_FLOW_2_IN_CP));
+        assertTrue("Incorrect path",
+                traceSuccess.getCompletePaths().get(0).contains(TOPO_FLOW_2_OUT_CP));
+        assertTrue("Incorrect path",
+                traceSuccess.getCompletePaths().get(0).contains(TOPO_FLOW_3_IN_CP));
+
+    }
+
+    /**
+     * Test path through a 4 device topology with first device that has groups with multiple output buckets.
+     */
+    @Test
+    public void testGroupTopo() throws Exception {
+
+        StaticPacketTrace traceSuccess = testSuccess(PACKET_OK_TOPO, TOPO_FLOW_IN_CP,
+                TOPO_FLOW_3_DEVICE, TOPO_FLOW_3_OUT_CP, 2);
+
+        assertTrue("Incorrect groups",
+                traceSuccess.getGroupOuputs(TOPO_GROUP_FLOW_DEVICE).get(0).getGroups().contains(TOPO_GROUP));
+        assertTrue("Incorrect bucket",
+                traceSuccess.getGroupOuputs(TOPO_GROUP_FLOW_DEVICE).get(1).getGroups().contains(TOPO_GROUP));
+    }
+
+    /**
+     * Test HW support in a single device with 2 flow rules to check hit of static HW rules.
+     */
+    @Test
+    public void hardwareTest() throws Exception {
+
+        StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, HARDWARE_DEVICE_IN_CP,
+                HARDWARE_DEVICE, HARDWARE_DEVICE_OUT_CP, 1);
+
+        assertEquals("wrong ETH type", EthType.EtherType.IPV4.ethType(),
+                ((EthTypeCriterion) traceSuccess.getGroupOuputs(HARDWARE_DEVICE).get(0).getFinalPacket()
+                        .getCriterion(Criterion.Type.ETH_TYPE)).ethType());
+
+    }
+
+    private StaticPacketTrace testSuccess(TrafficSelector packet, ConnectPoint in, DeviceId deviceId, ConnectPoint out,
+                                          int paths) {
+        StaticPacketTrace traceSuccess = mngr.trace(packet, in);
+
+        log.info("trace {}", traceSuccess);
+
+        log.info("trace {}", traceSuccess.resultMessage());
+
+        assertNotNull("trace should not be null", traceSuccess);
+        assertEquals("Trace should have " + paths + " output", paths, traceSuccess.getGroupOuputs(deviceId).size());
+        assertEquals("Trace should only have " + paths + "output", paths, traceSuccess.getCompletePaths().size());
+        assertTrue("Trace should be successful",
+                traceSuccess.resultMessage().contains("Reached required destination Host"));
+        assertEquals("Incorrect Output CP", out,
+                traceSuccess.getGroupOuputs(deviceId).get(0).getOutput());
+
+        return traceSuccess;
+    }
+
+    private void testFaliure(TrafficSelector packet, ConnectPoint in, DeviceId deviceId) {
+        StaticPacketTrace traceFail = mngr.trace(packet, in);
+
+        log.info("trace {}", traceFail.resultMessage());
+
+        assertNotNull("Trace should not be null", traceFail);
+        assertNull("Trace should have 0 output", traceFail.getGroupOuputs(deviceId));
+    }
+
+    private class TestFlowRuleService extends FlowRuleServiceAdapter {
+        @Override
+        public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
+            if (deviceId.equals(SINGLE_FLOW_DEVICE)) {
+                return ImmutableList.of(SINGLE_FLOW_ENTRY);
+            } else if (deviceId.equals(DUAL_FLOW_DEVICE)) {
+                return ImmutableList.of(FIRST_FLOW_ENTRY, SECOND_FLOW_ENTRY);
+            } else if (deviceId.equals(GROUP_FLOW_DEVICE)) {
+                return ImmutableList.of(GROUP_FLOW_ENTRY);
+            } else if (deviceId.equals(TOPO_FLOW_DEVICE) ||
+                    deviceId.equals(TOPO_FLOW_2_DEVICE) ||
+                    deviceId.equals(TOPO_FLOW_3_DEVICE) ||
+                    deviceId.equals(TOPO_FLOW_4_DEVICE)) {
+                return ImmutableList.of(TOPO_SINGLE_FLOW_ENTRY, TOPO_SECOND_INPUT_FLOW_ENTRY);
+            } else if (deviceId.equals(TOPO_GROUP_FLOW_DEVICE)) {
+                return ImmutableList.of(TOPO_GROUP_FLOW_ENTRY);
+            } else if (deviceId.equals(HARDWARE_DEVICE)){
+                return ImmutableList.of(HARDWARE_ETH_FLOW_ENTRY, HARDWARE_FLOW_ENTRY);
+            }
+            return ImmutableList.of();
+        }
+    }
+
+    private class TestDriverService extends DriverServiceAdapter {
+        @Override
+        public Driver getDriver(DeviceId deviceId) {
+            if(deviceId.equals(HARDWARE_DEVICE)){
+                return new DefaultDriver("ofdpa", ImmutableList.of(),
+                        "test", "test", "test", new HashMap<>(), new HashMap<>());
+            }
+            return new DefaultDriver("NotHWDriver", ImmutableList.of(),
+                    "test", "test", "test", new HashMap<>(), new HashMap<>());
+        }
+    }
+
+    private class TestGroupService extends GroupServiceAdapter {
+        @Override
+        public Iterable<Group> getGroups(DeviceId deviceId) {
+            if (deviceId.equals(GROUP_FLOW_DEVICE)) {
+                return ImmutableList.of(GROUP);
+            } else if (deviceId.equals(TOPO_GROUP_FLOW_DEVICE)) {
+                return ImmutableList.of(TOPO_GROUP);
+            }
+            return ImmutableList.of();
+        }
+    }
+
+    private class TestHostService extends HostServiceAdapter {
+        @Override
+        public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
+            if (connectPoint.equals(TOPO_FLOW_3_OUT_CP)) {
+                return ImmutableSet.of(H2);
+            }
+            return ImmutableSet.of(H1);
+        }
+
+        @Override
+        public Set<Host> getHostsByMac(MacAddress mac) {
+            if (mac.equals(H1.mac())) {
+                return ImmutableSet.of(H1);
+            } else if (mac.equals(H2.mac())) {
+                return ImmutableSet.of(H2);
+            }
+            return ImmutableSet.of();
+        }
+
+        @Override
+        public Set<Host> getHostsByIp(IpAddress ip) {
+            if ((H1.ipAddresses().contains(ip))) {
+                return ImmutableSet.of(H1);
+            } else if ((H2.ipAddresses().contains(ip))) {
+                return ImmutableSet.of(H2);
+            }
+            return ImmutableSet.of();
+        }
+    }
+
+    private class TestLinkService extends LinkServiceAdapter {
+        @Override
+        public Set<Link> getEgressLinks(ConnectPoint connectPoint) {
+            if (connectPoint.equals(TOPO_FLOW_1_OUT_CP)
+                    || connectPoint.equals(TOPO_FLOW_OUT_CP_1)) {
+                return ImmutableSet.of(DefaultLink.builder()
+                        .providerId(ProviderId.NONE)
+                        .type(Link.Type.DIRECT)
+                        .src(connectPoint)
+                        .dst(TOPO_FLOW_2_IN_CP)
+                        .build());
+            } else if (connectPoint.equals(TOPO_FLOW_2_OUT_CP)) {
+                return ImmutableSet.of(DefaultLink.builder()
+                        .providerId(ProviderId.NONE)
+                        .type(Link.Type.DIRECT)
+                        .src(TOPO_FLOW_2_OUT_CP)
+                        .dst(TOPO_FLOW_3_IN_CP)
+                        .build());
+            } else if (connectPoint.equals(TOPO_FLOW_OUT_CP_2)) {
+                return ImmutableSet.of(DefaultLink.builder()
+                        .providerId(ProviderId.NONE)
+                        .type(Link.Type.DIRECT)
+                        .src(TOPO_FLOW_OUT_CP_2)
+                        .dst(TOPO_FLOW_4_IN_CP)
+                        .build());
+            } else if (connectPoint.equals(TOPO_FLOW_4_OUT_CP)) {
+                return ImmutableSet.of(DefaultLink.builder()
+                        .providerId(ProviderId.NONE)
+                        .type(Link.Type.DIRECT)
+                        .src(TOPO_FLOW_4_OUT_CP)
+                        .dst(TOPO_FLOW_3_IN_2_CP)
+                        .build());
+            }
+            return ImmutableSet.of();
+        }
+    }
+}
\ No newline at end of file
