diff --git a/core/api/src/test/java/org/onosproject/core/DefaultApplicationTest.java b/core/api/src/test/java/org/onosproject/core/DefaultApplicationTest.java
index c768359..af3f359 100644
--- a/core/api/src/test/java/org/onosproject/core/DefaultApplicationTest.java
+++ b/core/api/src/test/java/org/onosproject/core/DefaultApplicationTest.java
@@ -28,10 +28,7 @@
 import java.util.Optional;
 import java.util.Set;
 
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
 import static org.onosproject.app.DefaultApplicationDescriptionTest.*;
 
 /**
@@ -48,6 +45,7 @@
                                                  PERMS, Optional.of(FURL), FEATURES, APPS);
         assertEquals("incorrect id", APP_ID, app.id());
         assertEquals("incorrect version", VER, app.version());
+        assertEquals("incorrect title", TITLE, app.title());
         assertEquals("incorrect description", DESC, app.description());
         assertEquals("incorrect origin", ORIGIN, app.origin());
         assertEquals("incorrect category", CATEGORY, app.category());
diff --git a/core/common/src/test/java/org/onosproject/utils/ComparatorsTest.java b/core/common/src/test/java/org/onosproject/utils/ComparatorsTest.java
new file mode 100644
index 0000000..6ab8230
--- /dev/null
+++ b/core/common/src/test/java/org/onosproject/utils/ComparatorsTest.java
@@ -0,0 +1,319 @@
+package org.onosproject.utils;
+
+import com.google.common.collect.ImmutableList;
+import org.junit.Test;
+import org.onlab.packet.ChassisId;
+import org.onlab.packet.Ip4Address;
+
+import org.onosproject.cluster.ControllerNode;
+import org.onosproject.cluster.DefaultControllerNode;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.core.*;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.virtual.*;
+import org.onosproject.net.*;
+
+import org.onosproject.net.flow.*;
+import org.onosproject.net.group.*;
+import org.onosproject.net.intent.IntentTestsMocks;
+import org.onosproject.net.key.DeviceKey;
+import org.onosproject.net.key.DeviceKeyId;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.region.DefaultRegion;
+import org.onosproject.net.region.Region;
+import org.onosproject.net.region.RegionId;
+import org.onosproject.net.statistic.DefaultLoad;
+import org.onosproject.net.statistic.FlowEntryWithLoad;
+import org.onosproject.net.statistic.Load;
+import org.onosproject.net.topology.*;
+import org.onosproject.ui.model.topo.UiTopoLayout;
+import org.onosproject.ui.model.topo.UiTopoLayoutId;
+import org.onosproject.net.group.DefaultGroupTest;
+
+
+import java.util.Optional;
+
+
+import static org.junit.Assert.*;
+
+import static org.onosproject.app.DefaultApplicationDescriptionTest.*;
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.NetTestTools.APP_ID;
+import static org.onosproject.net.NetTestTools.did;
+import static org.onosproject.net.topology.ClusterId.clusterId;
+import static org.onosproject.utils.Comparators.APP_COMPARATOR;
+import static org.onosproject.utils.Comparators.APP_ID_COMPARATOR;
+import static org.onosproject.utils.Comparators.CLUSTER_COMPARATOR;
+import static org.onosproject.utils.Comparators.DEVICE_KEY_COMPARATOR;
+import static org.onosproject.utils.Comparators.ELEMENT_COMPARATOR;
+import static org.onosproject.utils.Comparators.ELEMENT_ID_COMPARATOR;
+import static org.onosproject.utils.Comparators.FLOWENTRY_WITHLOAD_COMPARATOR;
+import static org.onosproject.utils.Comparators.FLOW_RULE_COMPARATOR;
+import static org.onosproject.utils.Comparators.GROUP_COMPARATOR;
+import static org.onosproject.utils.Comparators.INTERFACES_COMPARATOR;
+import static org.onosproject.utils.Comparators.LAYOUT_COMPARATOR;
+import static org.onosproject.utils.Comparators.NODE_COMPARATOR;
+import static org.onosproject.utils.Comparators.PORT_COMPARATOR;
+import static org.onosproject.utils.Comparators.REGION_COMPARATOR;
+import static org.onosproject.utils.Comparators.TENANT_ID_COMPARATOR;
+import static org.onosproject.utils.Comparators.VIRTUAL_DEVICE_COMPARATOR;
+import static org.onosproject.utils.Comparators.VIRTUAL_NETWORK_COMPARATOR;
+import static org.onosproject.utils.Comparators.VIRTUAL_PORT_COMPARATOR;
+
+
+public class ComparatorsTest {
+    private final ProviderId PID = new ProviderId("of", "foo");
+    private final DeviceId DID = deviceId("of:foo");
+    private final String MFR = "whitebox";
+    private final String HW = "1.1.x";
+    private final String HW1 = "2.2.x";
+    private final String SW = "3.9.1";
+    private final String SW1 = "4.0.0";
+    private final String SN = "43311-12345";
+    private final ChassisId CID = new ChassisId();
+    private final ConnectPoint cp =
+            new ConnectPoint(DeviceId.deviceId("of:00001"), PortNumber.portNumber(100));
+    private final GroupBucket testBucket =
+            DefaultGroupBucket.createSelectGroupBucket(
+                    DefaultTrafficTreatment.emptyTreatment());
+    private final GroupBuckets groupBuckets =
+            new GroupBuckets(ImmutableList.of(testBucket));
+    private final GroupDescription groupDesc1 =
+            new DefaultGroupDescription(did("1"),
+                    GroupDescription.Type.ALL,
+                    groupBuckets);
+    private final DefaultFlowEntry fEntry = new DefaultFlowEntry(fRule(10, 10),
+            FlowEntry.FlowEntryState.ADDED, 5, 5, 5);
+    Ip4Address ipAddress;
+
+    @Test
+    public void testAppIdComparator() {
+        assertEquals(0, APP_ID_COMPARATOR.compare(appID(1, "a"), appID(1, "a")));
+        assertTrue(APP_ID_COMPARATOR.compare(appID(2, "a"), appID(0, "a")) > 0);
+        assertTrue(APP_ID_COMPARATOR.compare(appID(1, "b"), appID(3, "x")) < 0);
+    }
+
+    private ApplicationId appID(int id, String name) {
+        return new DefaultApplicationId(id, name);
+    }
+
+    @Test
+    public void testAppComparator() {
+        assertEquals(0, APP_COMPARATOR.compare(app(1, "foo"), app(1, "foo")));
+        assertEquals(0, (APP_COMPARATOR.compare(app(2, "foo"), app(2, "bar"))));
+        assertNotEquals(0, APP_COMPARATOR.compare(app(1, "foo"), app(2, "foo")));
+        assertNotEquals(0, APP_COMPARATOR.compare(app(1, "bar"), app(2, "foo")));
+    }
+
+    private Application app(int id, String name) {
+        return new DefaultApplication(new DefaultApplicationId(id, name), VER, TITLE, DESC, ORIGIN,
+                CATEGORY, URL, README, ICON, ROLE,
+                PERMS, Optional.of(FURL), FEATURES, APPS);
+    }
+
+    @Test
+    public void testElementIdComparator() {
+        ElementId elementid1 = new ElementId() {
+        };
+        ElementId elementid2 = elementid1;
+        ElementId elementid3 = new ElementId() {
+        };
+        while (elementid1 == elementid3) {
+            elementid3 = new ElementId() {
+            };
+        }
+        assertTrue(0 == ELEMENT_ID_COMPARATOR.compare(elementid1, elementid2));
+        assertFalse(0 == ELEMENT_ID_COMPARATOR.compare(elementid3, elementid1));
+    }
+
+    @Test
+    public void testFlowRuleComparator() {
+        assertEquals(0, FLOW_RULE_COMPARATOR.compare(fRule(100, 10), fRule(100, 10)));
+        assertEquals(-8, FLOW_RULE_COMPARATOR.compare(fRule(100, 10), fRule(100, 2)));
+        assertEquals(90, FLOW_RULE_COMPARATOR.compare(fRule(100, 10), fRule(10, 10)));
+        assertEquals(20, FLOW_RULE_COMPARATOR.compare(fRule(40, 10), fRule(20, 2)));
+
+    }
+
+    private FlowRule fRule(int tableID, int priority) {
+        return DefaultFlowRule.builder()
+                .forDevice(did("id" + Integer.toString(10)))
+                .withPriority(priority)
+                .forTable(tableID)
+                .fromApp(APP_ID)
+                .makeTemporary(44)
+                .build();
+    }
+
+    @Test
+    public void testFlowEntryWithLoad() {
+        //Rate = (current-previous)/interval
+        assertEquals(0, FLOWENTRY_WITHLOAD_COMPARATOR.compare(FWLoad(20, 10, 1), FWLoad(20, 10, 1)));
+        assertEquals(0, FLOWENTRY_WITHLOAD_COMPARATOR.compare(FWLoad(50, 30, 2), FWLoad(100, 50, 5)));
+        assertEquals(-1, FLOWENTRY_WITHLOAD_COMPARATOR.compare(FWLoad(200, 100, 4), FWLoad(300, 200, 10)));
+    }
+
+    private FlowEntryWithLoad FWLoad(long current, long previous, long interval) {
+        return new FlowEntryWithLoad(cp, fEntry, new DefaultLoad(current, previous, interval));
+    }
+
+    @Test
+    public void testElementComparator() {
+        assertEquals(0, ELEMENT_COMPARATOR.compare(element("of", "foo", "of:foo"), element("of", "foo", "of:foo")));
+        assertEquals(0, ELEMENT_COMPARATOR.compare(element("of", "bar", "of:bar"), element("of", "foo", "of:bar")));
+        assertNotEquals(0, ELEMENT_COMPARATOR.compare(element("of", "foo", "of:foo"), element("of", "foo", "of:bar")));
+    }
+
+    private Element element(String scheme, String provID, String devID) {
+        return new DefaultDevice((new ProviderId(scheme, provID)), deviceId(devID), null, MFR, HW1, SW1, SN, CID);
+    }
+
+    @Test
+    public void testGroupComparator() {
+        assertEquals(0, GROUP_COMPARATOR.compare(group(10), group(10)));
+        assertEquals(-1, GROUP_COMPARATOR.compare(group(25), group(100)));
+        assertEquals(1, GROUP_COMPARATOR.compare(group(20), group(10)));
+    }
+
+    private Group group(int id) {
+        return new DefaultGroup(new GroupId(id), groupDesc1);
+    }
+
+    @Test
+    public void testPortComparator() {
+        assertEquals(0, PORT_COMPARATOR.compare(portTest(100), portTest(100)));
+        assertNotEquals(0, PORT_COMPARATOR.compare(portTest(100), portTest(200)));
+    }
+
+    private Port portTest(long portNumber) {
+        return new DefaultPort(null, PortNumber.portNumber(portNumber), true, Port.Type.COPPER, 100);
+    }
+
+    @Test
+    public void testTopologyClusterTest() {
+        assertEquals(0, CLUSTER_COMPARATOR.compare(cluster(3, 2, 1, "of:1"), cluster(3, 2, 1, "of:1")));
+        assertNotEquals(0, CLUSTER_COMPARATOR.compare(cluster(5, 2, 1, "of:1"), cluster(3, 2, 1, "of:1")));
+    }
+
+    private TopologyCluster cluster(int id, int dc, int lc, String root) {
+        return new DefaultTopologyCluster(clusterId(id), dc, lc,
+                new DefaultTopologyVertex(deviceId(root)));
+    }
+
+    @Test
+    public void testControllerNode() {
+        assertEquals(0, NODE_COMPARATOR.compare(node("testId"), node("testId")));
+        assertTrue(NODE_COMPARATOR.compare(node("abc"), node("xyz")) < 0);
+        assertTrue(NODE_COMPARATOR.compare(node("xyz"), node("abc")) > 0);
+    }
+
+    private ControllerNode node(String id) {
+        return new DefaultControllerNode(NodeId.nodeId(id), ipAddress, 9876);
+    }
+
+    @Test
+    public void testInterfaceComparator() {
+        assertEquals(0, INTERFACES_COMPARATOR.compare(intface("of:0000000000000001", 100), intface("of:0000000000000001", 100)));
+        assertTrue(INTERFACES_COMPARATOR.compare(intface("of:0000000000000001", 2), intface("of:0000000000000001", 100)) < 0);
+        assertTrue(INTERFACES_COMPARATOR.compare(intface("of:0000000000000001", 2), intface("of:0000000000000002", 2)) < 0);
+    }
+
+    private Interface intface(String deviceID, long port) {
+        return new Interface("testInterface", connectPoint1(deviceID, port), null, null, null);
+    }
+
+    final ConnectPoint connectPoint1(String deviceID, long portNumber) {
+        return new ConnectPoint(DeviceId.deviceId(deviceID), PortNumber.portNumber(portNumber));
+    }
+
+    @Test
+    public void testDeviceKeyComparator() {
+        assertEquals(0, DEVICE_KEY_COMPARATOR.compare(testDK("ID1", "label", "name"), testDK("ID1", "label", "name")));
+        assertEquals(0, DEVICE_KEY_COMPARATOR.compare(testDK("ID2", "label", "name"), testDK("ID2", "label", "name")));
+        assertNotEquals(0, DEVICE_KEY_COMPARATOR.compare(testDK("ID1", "label", "name"), testDK("ID2", "label", "name")));
+    }
+
+    private DeviceKey testDK(String ID, String testLabel, String testName) {
+        return DeviceKey.createDeviceKeyUsingCommunityName(DeviceKeyId.deviceKeyId(ID), testLabel, testName);
+    }
+
+    @Test
+    public void testRegionComparator() {
+        assertEquals(0, REGION_COMPARATOR.compare(region("id1"), region("id1")));
+        assertNotEquals(0, REGION_COMPARATOR.compare(region("id1"), region("id2")));
+    }
+
+    private Region region(String id) {
+        return new DefaultRegion(RegionId.regionId(id), "name", Region.Type.METRO, DefaultAnnotations.EMPTY, null);
+    }
+
+    @Test
+    public void testTopographicLayoutComparator() {
+        assertEquals(0, LAYOUT_COMPARATOR.compare(layout("test"), layout("test")));
+        assertNotEquals(0, LAYOUT_COMPARATOR.compare(layout("same"), layout("different")));
+    }
+
+    private UiTopoLayout layout(String id) {
+        return new UiTopoLayout(UiTopoLayoutId.layoutId(id));
+    }
+
+    @Test
+    public void testTenantIdComparator() {
+        assertEquals(0, TENANT_ID_COMPARATOR.compare(id("1"), id("1")));
+        assertEquals(0, TENANT_ID_COMPARATOR.compare(id("tenant1"), id("tenant1")));
+        assertNotEquals(0, TENANT_ID_COMPARATOR.compare(id("tenant1"), id("tenant2")));
+        assertTrue(TENANT_ID_COMPARATOR.compare(id("1"), id("9")) < 0);
+        assertTrue(TENANT_ID_COMPARATOR.compare(id("Tenant5"), id("Tenant0")) > 0);
+    }
+
+    private TenantId id(String id) {
+        return TenantId.tenantId(id);
+    }
+
+    @Test
+    public void testVirtualNetworkComparator() {
+        assertNotEquals(0, VIRTUAL_NETWORK_COMPARATOR.compare(network(10, "tenantID"), network(10, "tenantID1")));
+        assertNotEquals(0, VIRTUAL_NETWORK_COMPARATOR.compare(network(10, "tenantID"), network(15, "tenantID1")));
+        assertEquals(0, VIRTUAL_NETWORK_COMPARATOR.compare(network(15, "tenantID1"), network(10, "tenantID1")));
+        assertNotEquals(0, VIRTUAL_NETWORK_COMPARATOR.compare(network(15, "tenantID"), network(10, "tenantID1")));
+    }
+
+    private VirtualNetwork network(int networkID, String tenantID) {
+        return new DefaultVirtualNetwork(NetworkId.networkId(networkID), TenantId.tenantId(tenantID));
+    }
+
+    @Test
+    public void testVirtualDeviceComparator() {
+        assertEquals(0, VIRTUAL_DEVICE_COMPARATOR.compare(VD(0, "of:foo"), VD(0, "of:foo")));
+        assertEquals(0, VIRTUAL_DEVICE_COMPARATOR.compare(VD(3, "of:foo"), VD(0, "of:foo")));
+        assertNotEquals(0, VIRTUAL_DEVICE_COMPARATOR.compare(VD(0, "of:bar"), VD(0, "of:foo")));
+        assertNotEquals(0, VIRTUAL_DEVICE_COMPARATOR.compare(VD(3, "of:bar"), VD(0, "of:foo")));
+    }
+
+    private VirtualDevice VD(int netID, String devID) {
+        return new DefaultVirtualDevice(NetworkId.networkId(netID), DeviceId.deviceId(devID));
+    }
+
+    @Test
+    public void testVirtualPortComparator() {
+        assertEquals(0, VIRTUAL_PORT_COMPARATOR.compare(vPort(2), vPort(2)));
+        assertEquals(4, VIRTUAL_PORT_COMPARATOR.compare(vPort(900), vPort(5)));
+        assertEquals(-8, VIRTUAL_PORT_COMPARATOR.compare(vPort(0), vPort(8)));
+    }
+
+    private VirtualPort vPort(int portNumber) {
+        return new DefaultVirtualPort(NetworkId.networkId(20), new DefaultDevice(PID, DID, null, MFR, HW, SW, SN, CID),
+                PortNumber.portNumber(portNumber), new ConnectPoint(DID, PortNumber.portNumber(900)));
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
