diff --git a/apps/routing/common/src/test/java/org/onosproject/routing/bgp/AsPathTest.java b/apps/routing/common/src/test/java/org/onosproject/routing/bgp/AsPathTest.java
new file mode 100644
index 0000000..8c567e0
--- /dev/null
+++ b/apps/routing/common/src/test/java/org/onosproject/routing/bgp/AsPathTest.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.routing.bgp;
+
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+import java.util.ArrayList;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit tests for the BgpRouteEntry.AsPath class.
+ */
+public class AsPathTest {
+    /**
+     * Generates Path Segments.
+     *
+     * @return the generated Path Segments
+     */
+    private ArrayList<BgpRouteEntry.PathSegment> generatePathSegments() {
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        byte pathSegmentType;
+        ArrayList<Long> segmentAsNumbers;
+        BgpRouteEntry.PathSegment pathSegment;
+
+        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE;
+        segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add(1L);
+        segmentAsNumbers.add(2L);
+        segmentAsNumbers.add(3L);
+        pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+        pathSegments.add(pathSegment);
+        //
+        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SET;
+        segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add(4L);
+        segmentAsNumbers.add(5L);
+        segmentAsNumbers.add(6L);
+        pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+        pathSegments.add(pathSegment);
+        //
+        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add(7L);
+        segmentAsNumbers.add(8L);
+        segmentAsNumbers.add(9L);
+        pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+        pathSegments.add(pathSegment);
+        //
+        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SET;
+        segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add(10L);
+        segmentAsNumbers.add(11L);
+        segmentAsNumbers.add(12L);
+        pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+        pathSegments.add(pathSegment);
+
+        return pathSegments;
+    }
+
+    /**
+     * Generates an AS Path.
+     *
+     * @return a generated AS Path
+     */
+    private BgpRouteEntry.AsPath generateAsPath() {
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments =
+            generatePathSegments();
+        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
+
+        return asPath;
+    }
+
+    /**
+     * Tests valid class constructor.
+     */
+    @Test
+    public void testConstructor() {
+        BgpRouteEntry.AsPath asPath = generateAsPath();
+
+        String expectedString =
+            "AsPath{pathSegments=[" +
+            "PathSegment{type=AS_CONFED_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " +
+            "PathSegment{type=AS_CONFED_SET, segmentAsNumbers=[4, 5, 6]}, " +
+            "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[7, 8, 9]}, " +
+            "PathSegment{type=AS_SET, segmentAsNumbers=[10, 11, 12]}]}";
+        assertThat(asPath.toString(), is(expectedString));
+    }
+
+    /**
+     * Tests invalid class constructor for null Path Segments.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testInvalidConstructorNullPathSegments() {
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = null;
+        new BgpRouteEntry.AsPath(pathSegments);
+    }
+
+    /**
+     * Tests getting the fields of an AS Path.
+     */
+    @Test
+    public void testGetFields() {
+        // Create the fields to compare against
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments =
+            generatePathSegments();
+
+        // Generate the entry to test
+        BgpRouteEntry.AsPath asPath = generateAsPath();
+
+        assertThat(asPath.getPathSegments(), is(pathSegments));
+    }
+
+    /**
+     * Tests getting the AS Path Length.
+     */
+    @Test
+    public void testGetAsPathLength() {
+        //
+        // NOTE:
+        //  - AS_CONFED_SEQUENCE and AS_CONFED_SET are excluded
+        //  - AS_SET counts as a single hop
+        //
+        BgpRouteEntry.AsPath asPath = generateAsPath();
+        assertThat(asPath.getAsPathLength(), is(4));
+
+        // Create an empty AS Path
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        asPath = new BgpRouteEntry.AsPath(pathSegments);
+        assertThat(asPath.getAsPathLength(), is(0));
+    }
+
+    /**
+     * Tests equality of {@link BgpRouteEntry.AsPath}.
+     */
+    @Test
+    public void testEquality() {
+        BgpRouteEntry.AsPath asPath1 = generateAsPath();
+        BgpRouteEntry.AsPath asPath2 = generateAsPath();
+
+        assertThat(asPath1, is(asPath2));
+    }
+
+    /**
+     * Tests non-equality of {@link BgpRouteEntry.AsPath}.
+     */
+    @Test
+    public void testNonEquality() {
+        BgpRouteEntry.AsPath asPath1 = generateAsPath();
+
+        // Setup AS Path 2
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        byte pathSegmentType;
+        ArrayList<Long> segmentAsNumbers;
+        BgpRouteEntry.PathSegment pathSegment;
+
+        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE;
+        segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add(1L);
+        segmentAsNumbers.add(2L);
+        segmentAsNumbers.add(3L);
+        pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+        pathSegments.add(pathSegment);
+        //
+        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SET;
+        segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add(4L);
+        segmentAsNumbers.add(5L);
+        segmentAsNumbers.add(6L);
+        pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+        pathSegments.add(pathSegment);
+        //
+        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add(7L);
+        segmentAsNumbers.add(8L);
+        segmentAsNumbers.add(9L);
+        pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+        pathSegments.add(pathSegment);
+        //
+        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SET;
+        segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add(10L);
+        segmentAsNumbers.add(111L);                       // Different
+        segmentAsNumbers.add(12L);
+        pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+        pathSegments.add(pathSegment);
+        //
+        BgpRouteEntry.AsPath asPath2 = new BgpRouteEntry.AsPath(pathSegments);
+
+        assertThat(asPath1, Matchers.is(Matchers.not(asPath2)));
+    }
+
+    /**
+     * Tests object string representation.
+     */
+    @Test
+    public void testToString() {
+        BgpRouteEntry.AsPath asPath = generateAsPath();
+
+        String expectedString =
+            "AsPath{pathSegments=[" +
+            "PathSegment{type=AS_CONFED_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " +
+            "PathSegment{type=AS_CONFED_SET, segmentAsNumbers=[4, 5, 6]}, " +
+            "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[7, 8, 9]}, " +
+            "PathSegment{type=AS_SET, segmentAsNumbers=[10, 11, 12]}]}";
+        assertThat(asPath.toString(), is(expectedString));
+    }
+}
diff --git a/apps/routing/common/src/test/java/org/onosproject/routing/bgp/BgpRouteEntryTest.java b/apps/routing/common/src/test/java/org/onosproject/routing/bgp/BgpRouteEntryTest.java
new file mode 100644
index 0000000..5a05792
--- /dev/null
+++ b/apps/routing/common/src/test/java/org/onosproject/routing/bgp/BgpRouteEntryTest.java
@@ -0,0 +1,520 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.routing.bgp;
+
+import org.easymock.EasyMock;
+import org.hamcrest.Matchers;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+
+import java.util.ArrayList;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit tests for the BgpRouteEntry class.
+ */
+public class BgpRouteEntryTest {
+    private BgpSession bgpSession;
+    private static final Ip4Address BGP_SESSION_BGP_ID =
+        Ip4Address.valueOf("10.0.0.1");
+    private static final Ip4Address BGP_SESSION_IP_ADDRESS =
+        Ip4Address.valueOf("20.0.0.1");
+
+    private BgpSession bgpSession2;
+    private static final Ip4Address BGP_SESSION_BGP_ID2 =
+        Ip4Address.valueOf("10.0.0.2");
+    private static final Ip4Address BGP_SESSION_IP_ADDRESS2 =
+        Ip4Address.valueOf("20.0.0.1");
+
+    private BgpSession bgpSession3;
+    private static final Ip4Address BGP_SESSION_BGP_ID3 =
+        Ip4Address.valueOf("10.0.0.1");
+    private static final Ip4Address BGP_SESSION_IP_ADDRESS3 =
+        Ip4Address.valueOf("20.0.0.2");
+
+    private final BgpSessionInfo localInfo = new BgpSessionInfo();
+    private final BgpSessionInfo remoteInfo = new BgpSessionInfo();
+
+    private final BgpSessionInfo localInfo2 = new BgpSessionInfo();
+    private final BgpSessionInfo remoteInfo2 = new BgpSessionInfo();
+
+    private final BgpSessionInfo localInfo3 = new BgpSessionInfo();
+    private final BgpSessionInfo remoteInfo3 = new BgpSessionInfo();
+
+    @Before
+    public void setUp() throws Exception {
+        // Mock objects for testing
+        bgpSession = EasyMock.createMock(BgpSession.class);
+        bgpSession2 = EasyMock.createMock(BgpSession.class);
+        bgpSession3 = EasyMock.createMock(BgpSession.class);
+
+        // Setup the BGP Sessions
+        remoteInfo.setIp4Address(BGP_SESSION_IP_ADDRESS);
+        remoteInfo2.setIp4Address(BGP_SESSION_IP_ADDRESS2);
+        remoteInfo3.setIp4Address(BGP_SESSION_IP_ADDRESS3);
+        remoteInfo.setBgpId(BGP_SESSION_BGP_ID);
+        remoteInfo2.setBgpId(BGP_SESSION_BGP_ID2);
+        remoteInfo3.setBgpId(BGP_SESSION_BGP_ID3);
+
+        EasyMock.expect(bgpSession.localInfo()).andReturn(localInfo).anyTimes();
+        EasyMock.expect(bgpSession.remoteInfo()).andReturn(remoteInfo).anyTimes();
+        EasyMock.expect(bgpSession2.localInfo()).andReturn(localInfo2).anyTimes();
+        EasyMock.expect(bgpSession2.remoteInfo()).andReturn(remoteInfo2).anyTimes();
+        EasyMock.expect(bgpSession3.localInfo()).andReturn(localInfo3).anyTimes();
+        EasyMock.expect(bgpSession3.remoteInfo()).andReturn(remoteInfo3).anyTimes();
+
+        EasyMock.replay(bgpSession);
+        EasyMock.replay(bgpSession2);
+        EasyMock.replay(bgpSession3);
+    }
+
+    /**
+     * Generates a BGP Route Entry.
+     *
+     * @return a generated BGP Route Entry
+     */
+    private BgpRouteEntry generateBgpRouteEntry() {
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        byte origin = BgpConstants.Update.Origin.IGP;
+        // Setup the AS Path
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
+        segmentAsNumbers1.add(1L);
+        segmentAsNumbers1.add(2L);
+        segmentAsNumbers1.add(3L);
+        BgpRouteEntry.PathSegment pathSegment1 =
+            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
+        pathSegments.add(pathSegment1);
+        //
+        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
+        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
+        segmentAsNumbers2.add(4L);
+        segmentAsNumbers2.add(5L);
+        segmentAsNumbers2.add(6L);
+        BgpRouteEntry.PathSegment pathSegment2 =
+            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
+        pathSegments.add(pathSegment2);
+        //
+        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
+        //
+        long localPref = 100;
+        long multiExitDisc = 20;
+
+        BgpRouteEntry bgpRouteEntry =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry.setMultiExitDisc(multiExitDisc);
+
+        return bgpRouteEntry;
+    }
+
+    /**
+     * Tests valid class constructor.
+     */
+    @Test
+    public void testConstructor() {
+        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
+
+        String expectedString =
+            "BgpRouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8, " +
+            "bgpId=10.0.0.1, origin=IGP, asPath=AsPath{pathSegments=" +
+            "[PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " +
+            "PathSegment{type=AS_SET, segmentAsNumbers=[4, 5, 6]}]}, " +
+            "localPref=100, multiExitDisc=20}";
+        assertThat(bgpRouteEntry.toString(), is(expectedString));
+    }
+
+    /**
+     * Tests invalid class constructor for null BGP Session.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testInvalidConstructorNullBgpSession() {
+        BgpSession bgpSessionNull = null;
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        byte origin = BgpConstants.Update.Origin.IGP;
+        // Setup the AS Path
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
+        //
+        long localPref = 100;
+
+        new BgpRouteEntry(bgpSessionNull, prefix, nextHop, origin, asPath,
+                    localPref);
+    }
+
+    /**
+     * Tests invalid class constructor for null AS Path.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testInvalidConstructorNullAsPath() {
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        byte origin = BgpConstants.Update.Origin.IGP;
+        BgpRouteEntry.AsPath asPath = null;
+        long localPref = 100;
+
+        new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                    localPref);
+    }
+
+    /**
+     * Tests getting the fields of a BGP route entry.
+     */
+    @Test
+    public void testGetFields() {
+        // Create the fields to compare against
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        byte origin = BgpConstants.Update.Origin.IGP;
+        // Setup the AS Path
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
+        segmentAsNumbers1.add(1L);
+        segmentAsNumbers1.add(2L);
+        segmentAsNumbers1.add(3L);
+        BgpRouteEntry.PathSegment pathSegment1 =
+            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
+        pathSegments.add(pathSegment1);
+        //
+        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
+        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
+        segmentAsNumbers2.add(4L);
+        segmentAsNumbers2.add(5L);
+        segmentAsNumbers2.add(6L);
+        BgpRouteEntry.PathSegment pathSegment2 =
+            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
+        pathSegments.add(pathSegment2);
+        //
+        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
+        //
+        long localPref = 100;
+        long multiExitDisc = 20;
+
+        // Generate the entry to test
+        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
+
+        assertThat(bgpRouteEntry.prefix(), is(prefix));
+        assertThat(bgpRouteEntry.nextHop(), is(nextHop));
+        assertThat(bgpRouteEntry.getBgpSession(), is(bgpSession));
+        assertThat(bgpRouteEntry.getOrigin(), is(origin));
+        assertThat(bgpRouteEntry.getAsPath(), is(asPath));
+        assertThat(bgpRouteEntry.getLocalPref(), is(localPref));
+        assertThat(bgpRouteEntry.getMultiExitDisc(), is(multiExitDisc));
+    }
+
+    /**
+     * Tests whether a BGP route entry is a local route.
+     */
+    @Test
+    public void testIsLocalRoute() {
+        //
+        // Test non-local route
+        //
+        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
+        assertThat(bgpRouteEntry.isLocalRoute(), is(false));
+
+        //
+        // Test local route with AS Path that begins with AS_SET
+        //
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        byte origin = BgpConstants.Update.Origin.IGP;
+        // Setup the AS Path
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SET;
+        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
+        segmentAsNumbers1.add(1L);
+        segmentAsNumbers1.add(2L);
+        segmentAsNumbers1.add(3L);
+        BgpRouteEntry.PathSegment pathSegment1 =
+            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
+        pathSegments.add(pathSegment1);
+        //
+        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
+        segmentAsNumbers2.add(4L);
+        segmentAsNumbers2.add(5L);
+        segmentAsNumbers2.add(6L);
+        BgpRouteEntry.PathSegment pathSegment2 =
+            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
+        pathSegments.add(pathSegment2);
+        //
+        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
+        //
+        long localPref = 100;
+        long multiExitDisc = 20;
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry.setMultiExitDisc(multiExitDisc);
+        assertThat(bgpRouteEntry.isLocalRoute(), is(true));
+
+        //
+        // Test local route with empty AS Path
+        //
+        pathSegments = new ArrayList<>();
+        asPath = new BgpRouteEntry.AsPath(pathSegments);
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry.setMultiExitDisc(multiExitDisc);
+        assertThat(bgpRouteEntry.isLocalRoute(), is(true));
+    }
+
+    /**
+     * Tests getting the BGP Neighbor AS number for a route.
+     */
+    @Test
+    public void testGetNeighborAs() {
+        //
+        // Get neighbor AS for non-local route
+        //
+        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
+        assertThat(bgpRouteEntry.getNeighborAs(), is(1L));
+
+        //
+        // Get neighbor AS for a local route
+        //
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        byte origin = BgpConstants.Update.Origin.IGP;
+        // Setup the AS Path
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
+        //
+        long localPref = 100;
+        long multiExitDisc = 20;
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry.setMultiExitDisc(multiExitDisc);
+        assertThat(bgpRouteEntry.getNeighborAs(), is(BgpConstants.BGP_AS_0));
+    }
+
+    /**
+     * Tests whether a BGP route entry has AS Path loop.
+     */
+    @Test
+    public void testHasAsPathLoop() {
+        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
+
+        // Test for loops: test each AS number in the interval [1, 6]
+        for (int i = 1; i <= 6; i++) {
+            assertThat(bgpRouteEntry.hasAsPathLoop(i), is(true));
+        }
+
+        // Test for non-loops
+        assertThat(bgpRouteEntry.hasAsPathLoop(500), is(false));
+    }
+
+    /**
+     * Tests the BGP Decision Process comparison of BGP routes.
+     */
+    @Test
+    public void testBgpDecisionProcessComparison() {
+        BgpRouteEntry bgpRouteEntry1 = generateBgpRouteEntry();
+        BgpRouteEntry bgpRouteEntry2 = generateBgpRouteEntry();
+
+        //
+        // Compare two routes that are same
+        //
+        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
+        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(true));
+
+        //
+        // Compare two routes with different LOCAL_PREF
+        //
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        byte origin = BgpConstants.Update.Origin.IGP;
+        // Setup the AS Path
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
+        segmentAsNumbers1.add(1L);
+        segmentAsNumbers1.add(2L);
+        segmentAsNumbers1.add(3L);
+        BgpRouteEntry.PathSegment pathSegment1 =
+            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
+        pathSegments.add(pathSegment1);
+        //
+        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
+        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
+        segmentAsNumbers2.add(4L);
+        segmentAsNumbers2.add(5L);
+        segmentAsNumbers2.add(6L);
+        BgpRouteEntry.PathSegment pathSegment2 =
+            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
+        pathSegments.add(pathSegment2);
+        //
+        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
+        //
+        long localPref = 50;                                    // Different
+        long multiExitDisc = 20;
+        bgpRouteEntry2 =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
+        //
+        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
+        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
+        localPref = bgpRouteEntry1.getLocalPref();              // Restore
+
+        //
+        // Compare two routes with different AS_PATH length
+        //
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments2 = new ArrayList<>();
+        pathSegments2.add(pathSegment1);
+        // Different AS Path
+        BgpRouteEntry.AsPath asPath2 = new BgpRouteEntry.AsPath(pathSegments2);
+        bgpRouteEntry2 =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath2,
+                              localPref);
+        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
+        //
+        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(false));
+        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(true));
+
+        //
+        // Compare two routes with different ORIGIN
+        //
+        origin = BgpConstants.Update.Origin.EGP;                // Different
+        bgpRouteEntry2 =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
+        //
+        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
+        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
+        origin = bgpRouteEntry1.getOrigin();                    // Restore
+
+        //
+        // Compare two routes with different MULTI_EXIT_DISC
+        //
+        multiExitDisc = 10;                                     // Different
+        bgpRouteEntry2 =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
+        //
+        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
+        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
+        multiExitDisc = bgpRouteEntry1.getMultiExitDisc();      // Restore
+
+        //
+        // Compare two routes with different BGP ID
+        //
+        bgpRouteEntry2 =
+            new BgpRouteEntry(bgpSession2, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
+        //
+        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
+        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
+
+        //
+        // Compare two routes with different BGP address
+        //
+        bgpRouteEntry2 =
+            new BgpRouteEntry(bgpSession3, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
+        //
+        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
+        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
+    }
+
+    /**
+     * Tests equality of {@link BgpRouteEntry}.
+     */
+    @Test
+    public void testEquality() {
+        BgpRouteEntry bgpRouteEntry1 = generateBgpRouteEntry();
+        BgpRouteEntry bgpRouteEntry2 = generateBgpRouteEntry();
+
+        assertThat(bgpRouteEntry1, is(bgpRouteEntry2));
+    }
+
+    /**
+     * Tests non-equality of {@link BgpRouteEntry}.
+     */
+    @Test
+    public void testNonEquality() {
+        BgpRouteEntry bgpRouteEntry1 = generateBgpRouteEntry();
+
+        // Setup BGP Route 2
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        byte origin = BgpConstants.Update.Origin.IGP;
+        // Setup the AS Path
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
+        segmentAsNumbers1.add(1L);
+        segmentAsNumbers1.add(2L);
+        segmentAsNumbers1.add(3L);
+        BgpRouteEntry.PathSegment pathSegment1 =
+            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
+        pathSegments.add(pathSegment1);
+        //
+        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
+        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
+        segmentAsNumbers2.add(4L);
+        segmentAsNumbers2.add(5L);
+        segmentAsNumbers2.add(6L);
+        BgpRouteEntry.PathSegment pathSegment2 =
+            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
+        pathSegments.add(pathSegment2);
+        //
+        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
+        //
+        long localPref = 500;                                   // Different
+        long multiExitDisc = 20;
+        BgpRouteEntry bgpRouteEntry2 =
+            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
+                              localPref);
+        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
+
+        assertThat(bgpRouteEntry1, Matchers.is(Matchers.not(bgpRouteEntry2)));
+    }
+
+    /**
+     * Tests object string representation.
+     */
+    @Test
+    public void testToString() {
+        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
+
+        String expectedString =
+            "BgpRouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8, " +
+            "bgpId=10.0.0.1, origin=IGP, asPath=AsPath{pathSegments=" +
+            "[PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " +
+            "PathSegment{type=AS_SET, segmentAsNumbers=[4, 5, 6]}]}, " +
+            "localPref=100, multiExitDisc=20}";
+        assertThat(bgpRouteEntry.toString(), is(expectedString));
+    }
+}
diff --git a/apps/routing/common/src/test/java/org/onosproject/routing/bgp/BgpSessionManagerTest.java b/apps/routing/common/src/test/java/org/onosproject/routing/bgp/BgpSessionManagerTest.java
new file mode 100644
index 0000000..9f9ad3c
--- /dev/null
+++ b/apps/routing/common/src/test/java/org/onosproject/routing/bgp/BgpSessionManagerTest.java
@@ -0,0 +1,884 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.routing.bgp;
+
+import com.google.common.net.InetAddresses;
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+import org.jboss.netty.bootstrap.ClientBootstrap;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelFactory;
+import org.jboss.netty.channel.ChannelPipeline;
+import org.jboss.netty.channel.ChannelPipelineFactory;
+import org.jboss.netty.channel.Channels;
+import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.junit.TestUtils.TestUtilsException;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onosproject.incubator.net.routing.RouteAdminService;
+import org.osgi.service.component.ComponentContext;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.LinkedList;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit tests for the BgpSessionManager class.
+ */
+public class BgpSessionManagerTest {
+    private static final Ip4Address IP_LOOPBACK_ID =
+        Ip4Address.valueOf("127.0.0.1");
+    private static final Ip4Address BGP_PEER1_ID =
+        Ip4Address.valueOf("10.0.0.1");
+    private static final Ip4Address BGP_PEER2_ID =
+        Ip4Address.valueOf("10.0.0.2");
+    private static final Ip4Address BGP_PEER3_ID =
+        Ip4Address.valueOf("10.0.0.3");
+    private static final Ip4Address NEXT_HOP1_ROUTER =
+        Ip4Address.valueOf("10.20.30.41");
+    private static final Ip4Address NEXT_HOP2_ROUTER =
+        Ip4Address.valueOf("10.20.30.42");
+    private static final Ip4Address NEXT_HOP3_ROUTER =
+        Ip4Address.valueOf("10.20.30.43");
+
+    private static final long DEFAULT_LOCAL_PREF = 10;
+    private static final long BETTER_LOCAL_PREF = 20;
+    private static final long DEFAULT_MULTI_EXIT_DISC = 20;
+    private static final long BETTER_MULTI_EXIT_DISC = 30;
+
+    BgpRouteEntry.AsPath asPathShort;
+    BgpRouteEntry.AsPath asPathLong;
+
+    // Timeout waiting for a message to be received
+    private static final int MESSAGE_TIMEOUT_MS = 5000; // 5s
+
+    private RouteAdminService routeService;
+
+    // The BGP Session Manager to test
+    private BgpSessionManager bgpSessionManager;
+
+    // Remote Peer state
+    private final Collection<TestBgpPeer> peers = new LinkedList<>();
+    TestBgpPeer peer1;
+    TestBgpPeer peer2;
+    TestBgpPeer peer3;
+
+    // Local BGP per-peer session state
+    BgpSession bgpSession1;
+    BgpSession bgpSession2;
+    BgpSession bgpSession3;
+
+    // The socket that the remote peers should connect to
+    private InetSocketAddress connectToSocket;
+
+    /**
+     * A class to capture the state for a BGP peer.
+     */
+    private final class TestBgpPeer {
+        private final Ip4Address peerId;
+        private ClientBootstrap peerBootstrap;
+        private TestBgpPeerChannelHandler peerChannelHandler;
+        private TestBgpPeerFrameDecoder peerFrameDecoder =
+            new TestBgpPeerFrameDecoder();
+
+        /**
+         * Constructor.
+         *
+         * @param peerId the peer ID
+         */
+        private TestBgpPeer(Ip4Address peerId) {
+            this.peerId = peerId;
+            peerChannelHandler = new TestBgpPeerChannelHandler(peerId);
+        }
+
+        /**
+         * Starts up the BGP peer and connects it to the tested BgpSessionManager
+         * instance.
+         *
+         * @param connectToSocket the socket to connect to
+         */
+        private void connect(InetSocketAddress connectToSocket)
+            throws InterruptedException {
+            //
+            // Setup the BGP Peer, i.e., the "remote" BGP router that will
+            // initiate the BGP connection, send BGP UPDATE messages, etc.
+            //
+            ChannelFactory channelFactory =
+                new NioClientSocketChannelFactory(
+                        Executors.newCachedThreadPool(),
+                        Executors.newCachedThreadPool());
+            ChannelPipelineFactory pipelineFactory = () -> {
+                // Setup the transmitting pipeline
+                ChannelPipeline pipeline = Channels.pipeline();
+                pipeline.addLast("TestBgpPeerFrameDecoder",
+                        peerFrameDecoder);
+                pipeline.addLast("TestBgpPeerChannelHandler",
+                        peerChannelHandler);
+                return pipeline;
+            };
+
+            peerBootstrap = new ClientBootstrap(channelFactory);
+            peerBootstrap.setOption("child.keepAlive", true);
+            peerBootstrap.setOption("child.tcpNoDelay", true);
+            peerBootstrap.setPipelineFactory(pipelineFactory);
+            peerBootstrap.connect(connectToSocket);
+
+            boolean result;
+            // Wait until the OPEN message is received
+            result = peerFrameDecoder.receivedOpenMessageLatch.await(
+                MESSAGE_TIMEOUT_MS,
+                TimeUnit.MILLISECONDS);
+            assertThat(result, is(true));
+            // Wait until the KEEPALIVE message is received
+            result = peerFrameDecoder.receivedKeepaliveMessageLatch.await(
+                MESSAGE_TIMEOUT_MS,
+                TimeUnit.MILLISECONDS);
+            assertThat(result, is(true));
+
+            for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
+                if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER1_ID)) {
+                    bgpSession1 = bgpSession;
+                }
+                if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER2_ID)) {
+                    bgpSession2 = bgpSession;
+                }
+                if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER3_ID)) {
+                    bgpSession3 = bgpSession;
+                }
+            }
+        }
+    }
+
+    /**
+     * Class that implements a matcher for BgpRouteEntry by considering
+     * the BGP peer the entry was received from.
+     */
+    private static final class BgpRouteEntryAndPeerMatcher
+        extends TypeSafeMatcher<Collection<BgpRouteEntry>> {
+        private final BgpRouteEntry bgpRouteEntry;
+
+        private BgpRouteEntryAndPeerMatcher(BgpRouteEntry bgpRouteEntry) {
+            this.bgpRouteEntry = bgpRouteEntry;
+        }
+
+        @Override
+        public boolean matchesSafely(Collection<BgpRouteEntry> entries) {
+            for (BgpRouteEntry entry : entries) {
+                if (bgpRouteEntry.equals(entry) &&
+                    bgpRouteEntry.getBgpSession() == entry.getBgpSession()) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText("BGP route entry lookup for entry \"").
+                appendText(bgpRouteEntry.toString()).
+                appendText("\"");
+        }
+    }
+
+    /**
+     * A helper method used for testing whether a collection of
+     * BGP route entries contains an entry from a specific BGP peer.
+     *
+     * @param bgpRouteEntry the BGP route entry to test
+     * @return an instance of BgpRouteEntryAndPeerMatcher that implements
+     * the matching logic
+     */
+    private static BgpRouteEntryAndPeerMatcher hasBgpRouteEntry(
+        BgpRouteEntry bgpRouteEntry) {
+        return new BgpRouteEntryAndPeerMatcher(bgpRouteEntry);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void getDictionaryMock(ComponentContext componentContext) {
+        Dictionary dictionary = createMock(Dictionary.class);
+        expect(dictionary.get("bgpPort")).andReturn("0");
+        replay(dictionary);
+        expect(componentContext.getProperties()).andReturn(dictionary);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        peer1 = new TestBgpPeer(BGP_PEER1_ID);
+        peer2 = new TestBgpPeer(BGP_PEER2_ID);
+        peer3 = new TestBgpPeer(BGP_PEER3_ID);
+        peers.clear();
+        peers.add(peer1);
+        peers.add(peer2);
+        peers.add(peer3);
+
+        //
+        // Setup the BGP Session Manager to test, and start listening for BGP
+        // connections.
+        //
+        bgpSessionManager = new BgpSessionManager();
+
+        routeService = createNiceMock(RouteAdminService.class);
+        replay(routeService);
+        bgpSessionManager.routeService = routeService;
+
+        // NOTE: We use port 0 to bind on any available port
+        ComponentContext componentContext = createMock(ComponentContext.class);
+        getDictionaryMock(componentContext);
+        replay(componentContext);
+        bgpSessionManager.activate(componentContext);
+
+        // Get the port number the BGP Session Manager is listening on
+        Channel serverChannel = TestUtils.getField(bgpSessionManager,
+                                                   "serverChannel");
+        SocketAddress socketAddress = serverChannel.getLocalAddress();
+        InetSocketAddress inetSocketAddress =
+            (InetSocketAddress) socketAddress;
+        InetAddress connectToAddress = InetAddresses.forString("127.0.0.1");
+        connectToSocket = new InetSocketAddress(connectToAddress,
+                                                inetSocketAddress.getPort());
+
+        //
+        // Setup the AS Paths
+        //
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
+        segmentAsNumbers1.add(65010L);
+        segmentAsNumbers1.add(65020L);
+        segmentAsNumbers1.add(65030L);
+        BgpRouteEntry.PathSegment pathSegment1 =
+            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
+        pathSegments.add(pathSegment1);
+        asPathShort = new BgpRouteEntry.AsPath(new ArrayList<>(pathSegments));
+        //
+        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
+        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
+        segmentAsNumbers2.add(65041L);
+        segmentAsNumbers2.add(65042L);
+        segmentAsNumbers2.add(65043L);
+        BgpRouteEntry.PathSegment pathSegment2 =
+            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
+        pathSegments.add(pathSegment2);
+        //
+        asPathLong = new BgpRouteEntry.AsPath(pathSegments);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        bgpSessionManager.stop();
+        bgpSessionManager = null;
+    }
+
+    /**
+     * Gets BGP RIB-IN routes by waiting until they are received.
+     * <p>
+     * NOTE: We keep checking once every 10ms the number of received routes,
+     * up to 5 seconds.
+     * </p>
+     *
+     * @param bgpSession the BGP session that is expected to receive the
+     * routes
+     * @param expectedRoutes the expected number of routes
+     * @return the BGP RIB-IN routes as received within the expected
+     * time interval
+     */
+    private Collection<BgpRouteEntry> waitForBgpRibIn(BgpSession bgpSession,
+                                                      long expectedRoutes)
+        throws InterruptedException {
+        Collection<BgpRouteEntry> bgpRibIn = bgpSession.getBgpRibIn4();
+
+        final int maxChecks = 500;              // Max wait of 5 seconds
+        for (int i = 0; i < maxChecks; i++) {
+            if (bgpRibIn.size() == expectedRoutes) {
+                break;
+            }
+            Thread.sleep(10);
+            bgpRibIn = bgpSession.getBgpRibIn4();
+        }
+
+        return bgpRibIn;
+    }
+
+    /**
+     * Gets BGP merged routes by waiting until they are received.
+     * <p>
+     * NOTE: We keep checking once every 10ms the number of received routes,
+     * up to 5 seconds.
+     * </p>
+     *
+     * @param expectedRoutes the expected number of routes
+     * @return the BGP Session Manager routes as received within the expected
+     * time interval
+     */
+    private Collection<BgpRouteEntry> waitForBgpRoutes(long expectedRoutes)
+        throws InterruptedException {
+        Collection<BgpRouteEntry> bgpRoutes =
+            bgpSessionManager.getBgpRoutes4();
+
+        final int maxChecks = 500;              // Max wait of 5 seconds
+        for (int i = 0; i < maxChecks; i++) {
+            if (bgpRoutes.size() == expectedRoutes) {
+                break;
+            }
+            Thread.sleep(10);
+            bgpRoutes = bgpSessionManager.getBgpRoutes4();
+        }
+
+        return bgpRoutes;
+    }
+
+    /**
+     * Gets a merged BGP route by waiting until it is received.
+     * <p>
+     * NOTE: We keep checking once every 10ms whether the route is received,
+     * up to 5 seconds.
+     * </p>
+     *
+     * @param expectedRoute the expected route
+     * @return the merged BGP route if received within the expected time
+     * interval, otherwise null
+     */
+    private BgpRouteEntry waitForBgpRoute(BgpRouteEntry expectedRoute)
+        throws InterruptedException {
+        Collection<BgpRouteEntry> bgpRoutes =
+            bgpSessionManager.getBgpRoutes4();
+
+        final int maxChecks = 500;              // Max wait of 5 seconds
+        for (int i = 0; i < maxChecks; i++) {
+            for (BgpRouteEntry bgpRouteEntry : bgpRoutes) {
+                if (bgpRouteEntry.equals(expectedRoute) &&
+                    bgpRouteEntry.getBgpSession() ==
+                    expectedRoute.getBgpSession()) {
+                    return bgpRouteEntry;
+                }
+            }
+            Thread.sleep(10);
+            bgpRoutes = bgpSessionManager.getBgpRoutes4();
+        }
+
+        return null;
+    }
+
+    /**
+     * Tests that the BGP OPEN messages have been exchanged, followed by
+     * KEEPALIVE.
+     * <p>
+     * The BGP Peer opens the sessions and transmits OPEN Message, eventually
+     * followed by KEEPALIVE. The tested BGP listener should respond by
+     * OPEN Message, followed by KEEPALIVE.
+     * </p>
+     *
+     * @throws TestUtilsException TestUtils error
+     */
+    @Test
+    public void testExchangedBgpOpenMessages()
+            throws InterruptedException, TestUtilsException {
+        // Initiate the connections
+        peer1.connect(connectToSocket);
+        peer2.connect(connectToSocket);
+        peer3.connect(connectToSocket);
+
+        //
+        // Test the fields from the BGP OPEN message:
+        // BGP version, AS number, BGP ID
+        //
+        for (TestBgpPeer peer : peers) {
+            assertThat(peer.peerFrameDecoder.remoteInfo.bgpVersion(),
+                       is(BgpConstants.BGP_VERSION));
+            assertThat(peer.peerFrameDecoder.remoteInfo.bgpId(),
+                       is(IP_LOOPBACK_ID));
+            assertThat(peer.peerFrameDecoder.remoteInfo.asNumber(),
+                       is(TestBgpPeerChannelHandler.PEER_AS));
+        }
+
+        //
+        // Test that the BgpSession instances have been created
+        //
+        assertThat(bgpSessionManager.getMyBgpId(), is(IP_LOOPBACK_ID));
+        assertThat(bgpSessionManager.getBgpSessions(), hasSize(3));
+        assertThat(bgpSession1, notNullValue());
+        assertThat(bgpSession2, notNullValue());
+        assertThat(bgpSession3, notNullValue());
+        for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
+            long sessionAs = bgpSession.localInfo().asNumber();
+            assertThat(sessionAs, is(TestBgpPeerChannelHandler.PEER_AS));
+        }
+    }
+
+
+    /**
+     * Tests that the BGP OPEN with Capability messages have been exchanged,
+     * followed by KEEPALIVE.
+     * <p>
+     * The BGP Peer opens the sessions and transmits OPEN Message, eventually
+     * followed by KEEPALIVE. The tested BGP listener should respond by
+     * OPEN Message, followed by KEEPALIVE.
+     * </p>
+     *
+     * @throws TestUtilsException TestUtils error
+     */
+    @Test
+    public void testExchangedBgpOpenCapabilityMessages()
+            throws InterruptedException, TestUtilsException {
+        //
+        // Setup the BGP Capabilities for all peers
+        //
+        for (TestBgpPeer peer : peers) {
+            peer.peerChannelHandler.localInfo.setIpv4Unicast();
+            peer.peerChannelHandler.localInfo.setIpv4Multicast();
+            peer.peerChannelHandler.localInfo.setIpv6Unicast();
+            peer.peerChannelHandler.localInfo.setIpv6Multicast();
+            peer.peerChannelHandler.localInfo.setAs4OctetCapability();
+            peer.peerChannelHandler.localInfo.setAs4Number(
+                TestBgpPeerChannelHandler.PEER_AS4);
+        }
+
+        // Initiate the connections
+        peer1.connect(connectToSocket);
+        peer2.connect(connectToSocket);
+        peer3.connect(connectToSocket);
+
+        //
+        // Test the fields from the BGP OPEN message:
+        // BGP version, BGP ID
+        //
+        for (TestBgpPeer peer : peers) {
+            assertThat(peer.peerFrameDecoder.remoteInfo.bgpVersion(),
+                       is(BgpConstants.BGP_VERSION));
+            assertThat(peer.peerFrameDecoder.remoteInfo.bgpId(),
+                       is(IP_LOOPBACK_ID));
+        }
+
+        //
+        // Test that the BgpSession instances have been created,
+        // and contain the appropriate BGP session information.
+        //
+        assertThat(bgpSessionManager.getMyBgpId(), is(IP_LOOPBACK_ID));
+        assertThat(bgpSessionManager.getBgpSessions(), hasSize(3));
+        assertThat(bgpSession1, notNullValue());
+        assertThat(bgpSession2, notNullValue());
+        assertThat(bgpSession3, notNullValue());
+        for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
+            BgpSessionInfo localInfo = bgpSession.localInfo();
+            assertThat(localInfo.ipv4Unicast(), is(true));
+            assertThat(localInfo.ipv4Multicast(), is(true));
+            assertThat(localInfo.ipv6Unicast(), is(true));
+            assertThat(localInfo.ipv6Multicast(), is(true));
+            assertThat(localInfo.as4OctetCapability(), is(true));
+            assertThat(localInfo.asNumber(),
+                       is(TestBgpPeerChannelHandler.PEER_AS4));
+            assertThat(localInfo.as4Number(),
+                       is(TestBgpPeerChannelHandler.PEER_AS4));
+        }
+    }
+
+    /**
+     * Tests that the BGP UPDATE messages have been received and processed.
+     */
+    @Test
+    public void testProcessedBgpUpdateMessages() throws InterruptedException {
+        ChannelBuffer message;
+        BgpRouteEntry bgpRouteEntry;
+        Collection<BgpRouteEntry> bgpRibIn1;
+        Collection<BgpRouteEntry> bgpRibIn2;
+        Collection<BgpRouteEntry> bgpRibIn3;
+        Collection<BgpRouteEntry> bgpRoutes;
+
+        // Initiate the connections
+        peer1.connect(connectToSocket);
+        peer2.connect(connectToSocket);
+        peer3.connect(connectToSocket);
+
+        // Prepare routes to add/delete
+        Collection<Ip4Prefix> addedRoutes = new LinkedList<>();
+        Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>();
+
+        //
+        // Add and delete some routes
+        //
+        addedRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0"));
+        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+        addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
+        addedRoutes.add(Ip4Prefix.valueOf("40.0.0.0/24"));
+        addedRoutes.add(Ip4Prefix.valueOf("50.0.0.0/32"));
+        withdrawnRoutes.add(Ip4Prefix.valueOf("60.0.0.0/8"));
+        withdrawnRoutes.add(Ip4Prefix.valueOf("70.0.0.0/16"));
+        withdrawnRoutes.add(Ip4Prefix.valueOf("80.0.0.0/24"));
+        withdrawnRoutes.add(Ip4Prefix.valueOf("90.0.0.0/32"));
+
+        // Write the routes
+        message = peer1.peerChannelHandler.prepareBgpUpdate(
+                        NEXT_HOP1_ROUTER,
+                        DEFAULT_LOCAL_PREF,
+                        DEFAULT_MULTI_EXIT_DISC,
+                        asPathLong,
+                        addedRoutes,
+                        withdrawnRoutes);
+        peer1.peerChannelHandler.savedCtx.getChannel().write(message);
+        //
+        // Check that the routes have been received, processed and stored
+        //
+        bgpRibIn1 = waitForBgpRibIn(bgpSession1, 5);
+        assertThat(bgpRibIn1, hasSize(5));
+        bgpRoutes = waitForBgpRoutes(5);
+        assertThat(bgpRoutes, hasSize(5));
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("0.0.0.0/0"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              DEFAULT_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("20.0.0.0/8"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              DEFAULT_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("30.0.0.0/16"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              DEFAULT_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("40.0.0.0/24"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              DEFAULT_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("50.0.0.0/32"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              DEFAULT_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+
+        //
+        // Delete some routes
+        //
+        addedRoutes = new LinkedList<>();
+        withdrawnRoutes = new LinkedList<>();
+        withdrawnRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0"));
+        withdrawnRoutes.add(Ip4Prefix.valueOf("50.0.0.0/32"));
+        // Write the routes
+        message = peer1.peerChannelHandler.prepareBgpUpdate(
+                        NEXT_HOP1_ROUTER,
+                        DEFAULT_LOCAL_PREF,
+                        DEFAULT_MULTI_EXIT_DISC,
+                        asPathLong,
+                        addedRoutes,
+                        withdrawnRoutes);
+        peer1.peerChannelHandler.savedCtx.getChannel().write(message);
+        //
+        // Check that the routes have been received, processed and stored
+        //
+        bgpRibIn1 = waitForBgpRibIn(bgpSession1, 3);
+        assertThat(bgpRibIn1, hasSize(3));
+        bgpRoutes = waitForBgpRoutes(3);
+        assertThat(bgpRoutes, hasSize(3));
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("20.0.0.0/8"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              DEFAULT_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("30.0.0.0/16"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              DEFAULT_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("40.0.0.0/24"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              DEFAULT_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+
+
+        // Close the channels and test there are no routes
+        peer1.peerChannelHandler.closeChannel();
+        peer2.peerChannelHandler.closeChannel();
+        peer3.peerChannelHandler.closeChannel();
+        bgpRoutes = waitForBgpRoutes(0);
+        assertThat(bgpRoutes, hasSize(0));
+    }
+
+    /**
+     * Tests the BGP route preference.
+     */
+    @Test
+    public void testBgpRoutePreference() throws InterruptedException {
+        ChannelBuffer message;
+        BgpRouteEntry bgpRouteEntry;
+        Collection<BgpRouteEntry> bgpRibIn1;
+        Collection<BgpRouteEntry> bgpRibIn2;
+        Collection<BgpRouteEntry> bgpRibIn3;
+        Collection<BgpRouteEntry> bgpRoutes;
+        Collection<Ip4Prefix> addedRoutes = new LinkedList<>();
+        Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>();
+
+        // Initiate the connections
+        peer1.connect(connectToSocket);
+        peer2.connect(connectToSocket);
+        peer3.connect(connectToSocket);
+
+        //
+        // Setup the initial set of routes to Peer1
+        //
+        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+        addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
+        // Write the routes
+        message = peer1.peerChannelHandler.prepareBgpUpdate(
+                        NEXT_HOP1_ROUTER,
+                        DEFAULT_LOCAL_PREF,
+                        DEFAULT_MULTI_EXIT_DISC,
+                        asPathLong,
+                        addedRoutes,
+                        withdrawnRoutes);
+        peer1.peerChannelHandler.savedCtx.getChannel().write(message);
+        bgpRoutes = waitForBgpRoutes(2);
+        assertThat(bgpRoutes, hasSize(2));
+
+        //
+        // Add a route entry to Peer2 with a better LOCAL_PREF
+        //
+        addedRoutes = new LinkedList<>();
+        withdrawnRoutes = new LinkedList<>();
+        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+        // Write the routes
+        message = peer2.peerChannelHandler.prepareBgpUpdate(
+                        NEXT_HOP2_ROUTER,
+                        BETTER_LOCAL_PREF,
+                        DEFAULT_MULTI_EXIT_DISC,
+                        asPathLong,
+                        addedRoutes,
+                        withdrawnRoutes);
+        peer2.peerChannelHandler.savedCtx.getChannel().write(message);
+        //
+        // Check that the routes have been received, processed and stored
+        //
+        bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1);
+        assertThat(bgpRibIn2, hasSize(1));
+        bgpRoutes = waitForBgpRoutes(2);
+        assertThat(bgpRoutes, hasSize(2));
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession2,
+                              Ip4Prefix.valueOf("20.0.0.0/8"),
+                              NEXT_HOP2_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathLong,
+                              BETTER_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+
+        //
+        // Add a route entry to Peer3 with a shorter AS path
+        //
+        addedRoutes = new LinkedList<>();
+        withdrawnRoutes = new LinkedList<>();
+        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+        // Write the routes
+        message = peer3.peerChannelHandler.prepareBgpUpdate(
+                        NEXT_HOP3_ROUTER,
+                        BETTER_LOCAL_PREF,
+                        DEFAULT_MULTI_EXIT_DISC,
+                        asPathShort,
+                        addedRoutes,
+                        withdrawnRoutes);
+        peer3.peerChannelHandler.savedCtx.getChannel().write(message);
+        //
+        // Check that the routes have been received, processed and stored
+        //
+        bgpRibIn3 = waitForBgpRibIn(bgpSession3, 1);
+        assertThat(bgpRibIn3, hasSize(1));
+        bgpRoutes = waitForBgpRoutes(2);
+        assertThat(bgpRoutes, hasSize(2));
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession3,
+                              Ip4Prefix.valueOf("20.0.0.0/8"),
+                              NEXT_HOP3_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathShort,
+                              BETTER_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn3, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+
+        //
+        // Cleanup in preparation for next test: delete old route entry from
+        // Peer2
+        //
+        addedRoutes = new LinkedList<>();
+        withdrawnRoutes = new LinkedList<>();
+        withdrawnRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+        // Write the routes
+        message = peer2.peerChannelHandler.prepareBgpUpdate(
+                        NEXT_HOP2_ROUTER,
+                        BETTER_LOCAL_PREF,
+                        BETTER_MULTI_EXIT_DISC,
+                        asPathShort,
+                        addedRoutes,
+                        withdrawnRoutes);
+        peer2.peerChannelHandler.savedCtx.getChannel().write(message);
+        //
+        // Check that the routes have been received, processed and stored
+        //
+        bgpRibIn2 = waitForBgpRibIn(bgpSession2, 0);
+        assertThat(bgpRibIn2, hasSize(0));
+
+        //
+        // Add a route entry to Peer2 with a better MED
+        //
+        addedRoutes = new LinkedList<>();
+        withdrawnRoutes = new LinkedList<>();
+        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+        // Write the routes
+        message = peer2.peerChannelHandler.prepareBgpUpdate(
+                        NEXT_HOP2_ROUTER,
+                        BETTER_LOCAL_PREF,
+                        BETTER_MULTI_EXIT_DISC,
+                        asPathShort,
+                        addedRoutes,
+                        withdrawnRoutes);
+        peer2.peerChannelHandler.savedCtx.getChannel().write(message);
+        //
+        // Check that the routes have been received, processed and stored
+        //
+        bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1);
+        assertThat(bgpRibIn2, hasSize(1));
+        bgpRoutes = waitForBgpRoutes(2);
+        assertThat(bgpRoutes, hasSize(2));
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession2,
+                              Ip4Prefix.valueOf("20.0.0.0/8"),
+                              NEXT_HOP2_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathShort,
+                              BETTER_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+
+        //
+        // Add a route entry to Peer1 with a better (lower) BGP ID
+        //
+        addedRoutes = new LinkedList<>();
+        withdrawnRoutes = new LinkedList<>();
+        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+        withdrawnRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
+        // Write the routes
+        message = peer1.peerChannelHandler.prepareBgpUpdate(
+                        NEXT_HOP1_ROUTER,
+                        BETTER_LOCAL_PREF,
+                        BETTER_MULTI_EXIT_DISC,
+                        asPathShort,
+                        addedRoutes,
+                        withdrawnRoutes);
+        peer1.peerChannelHandler.savedCtx.getChannel().write(message);
+        //
+        // Check that the routes have been received, processed and stored
+        //
+        bgpRibIn1 = waitForBgpRibIn(bgpSession1, 1);
+        assertThat(bgpRibIn1, hasSize(1));
+        bgpRoutes = waitForBgpRoutes(1);
+        assertThat(bgpRoutes, hasSize(1));
+        //
+        bgpRouteEntry =
+            new BgpRouteEntry(bgpSession1,
+                              Ip4Prefix.valueOf("20.0.0.0/8"),
+                              NEXT_HOP1_ROUTER,
+                              (byte) BgpConstants.Update.Origin.IGP,
+                              asPathShort,
+                              BETTER_LOCAL_PREF);
+        bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC);
+        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
+
+
+        // Close the channels and test there are no routes
+        peer1.peerChannelHandler.closeChannel();
+        peer2.peerChannelHandler.closeChannel();
+        peer3.peerChannelHandler.closeChannel();
+        bgpRoutes = waitForBgpRoutes(0);
+        assertThat(bgpRoutes, hasSize(0));
+    }
+}
diff --git a/apps/routing/common/src/test/java/org/onosproject/routing/bgp/PathSegmentTest.java b/apps/routing/common/src/test/java/org/onosproject/routing/bgp/PathSegmentTest.java
new file mode 100644
index 0000000..8605161
--- /dev/null
+++ b/apps/routing/common/src/test/java/org/onosproject/routing/bgp/PathSegmentTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.routing.bgp;
+
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+import java.util.ArrayList;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit tests for the BgpRouteEntry.PathSegment class.
+ */
+public class PathSegmentTest {
+    /**
+     * Generates a Path Segment.
+     *
+     * @return a generated PathSegment
+     */
+    private BgpRouteEntry.PathSegment generatePathSegment() {
+        byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add(1L);
+        segmentAsNumbers.add(2L);
+        segmentAsNumbers.add(3L);
+        BgpRouteEntry.PathSegment pathSegment =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+
+        return pathSegment;
+    }
+
+    /**
+     * Tests valid class constructor.
+     */
+    @Test
+    public void testConstructor() {
+        BgpRouteEntry.PathSegment pathSegment = generatePathSegment();
+
+        String expectedString =
+            "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}";
+        assertThat(pathSegment.toString(), is(expectedString));
+    }
+
+    /**
+     * Tests invalid class constructor for null Segment AS Numbers.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testInvalidConstructorNullSegmentAsNumbers() {
+        byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers = null;
+        new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+    }
+
+    /**
+     * Tests getting the fields of a Path Segment.
+     */
+    @Test
+    public void testGetFields() {
+        // Create the fields to compare against
+        byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add(1L);
+        segmentAsNumbers.add(2L);
+        segmentAsNumbers.add(3L);
+
+        // Generate the entry to test
+        BgpRouteEntry.PathSegment pathSegment = generatePathSegment();
+
+        assertThat(pathSegment.getType(), is(pathSegmentType));
+        assertThat(pathSegment.getSegmentAsNumbers(), is(segmentAsNumbers));
+    }
+
+    /**
+     * Tests equality of {@link BgpRouteEntry.PathSegment}.
+     */
+    @Test
+    public void testEquality() {
+        BgpRouteEntry.PathSegment pathSegment1 = generatePathSegment();
+        BgpRouteEntry.PathSegment pathSegment2 = generatePathSegment();
+
+        assertThat(pathSegment1, is(pathSegment2));
+    }
+
+    /**
+     * Tests non-equality of {@link BgpRouteEntry.PathSegment}.
+     */
+    @Test
+    public void testNonEquality() {
+        BgpRouteEntry.PathSegment pathSegment1 = generatePathSegment();
+
+        // Setup Path Segment 2
+        byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+        ArrayList<Long> segmentAsNumbers = new ArrayList<>();
+        segmentAsNumbers.add(1L);
+        segmentAsNumbers.add(22L);                        // Different
+        segmentAsNumbers.add(3L);
+        //
+        BgpRouteEntry.PathSegment pathSegment2 =
+            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
+
+        assertThat(pathSegment1, Matchers.is(Matchers.not(pathSegment2)));
+    }
+
+    /**
+     * Tests object string representation.
+     */
+    @Test
+    public void testToString() {
+        BgpRouteEntry.PathSegment pathSegment = generatePathSegment();
+
+        String expectedString =
+            "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}";
+        assertThat(pathSegment.toString(), is(expectedString));
+    }
+}
diff --git a/apps/routing/common/src/test/java/org/onosproject/routing/bgp/RouteEntryTest.java b/apps/routing/common/src/test/java/org/onosproject/routing/bgp/RouteEntryTest.java
new file mode 100644
index 0000000..901d608
--- /dev/null
+++ b/apps/routing/common/src/test/java/org/onosproject/routing/bgp/RouteEntryTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.routing.bgp;
+
+import org.hamcrest.Matchers;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.Ip6Prefix;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit tests for the RouteEntry class.
+ */
+public class RouteEntryTest {
+
+    /**
+     * Tests invalid class constructor for null IPv4 prefix.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testInvalidConstructorNullIpv4Prefix() {
+        Ip4Prefix prefix = null;
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+
+        new RouteEntry(prefix, nextHop);
+    }
+
+    /**
+     * Tests invalid class constructor for null IPv6 prefix.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testInvalidConstructorNullIpv6Prefix() {
+        Ip6Prefix prefix = null;
+        Ip6Address nextHop = Ip6Address.valueOf("2000::1");
+
+        new RouteEntry(prefix, nextHop);
+    }
+
+    /**
+     * Tests invalid class constructor for null IPv4 next-hop.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testInvalidConstructorNullIpv4NextHop() {
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = null;
+
+        new RouteEntry(prefix, nextHop);
+    }
+
+    /**
+     * Tests invalid class constructor for null IPv6 next-hop.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testInvalidConstructorNullIpv6NextHop() {
+        Ip6Prefix prefix = Ip6Prefix.valueOf("1000::/64");
+        Ip6Address nextHop = null;
+
+        new RouteEntry(prefix, nextHop);
+    }
+
+    /**
+     * Tests getting the fields of a route entry.
+     */
+    @Test
+    public void testGetFields() {
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        RouteEntry routeEntry = new RouteEntry(prefix, nextHop);
+        assertThat(routeEntry.prefix(), is(prefix));
+        assertThat(routeEntry.nextHop(), is(nextHop));
+
+        Ip6Prefix prefix6 = Ip6Prefix.valueOf("1000::/64");
+        Ip6Address nextHop6 = Ip6Address.valueOf("2000::1");
+        RouteEntry routeEntry6 = new RouteEntry(prefix6, nextHop6);
+        assertThat(routeEntry6.prefix(), is(prefix6));
+        assertThat(routeEntry6.nextHop(), is(nextHop6));
+    }
+
+    /**
+     * Tests equality of {@link RouteEntry}.
+     */
+    @Test
+    public void testEquality() {
+        Ip4Prefix prefix1 = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop1 = Ip4Address.valueOf("5.6.7.8");
+        RouteEntry routeEntry1 = new RouteEntry(prefix1, nextHop1);
+
+        Ip4Prefix prefix2 = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop2 = Ip4Address.valueOf("5.6.7.8");
+        RouteEntry routeEntry2 = new RouteEntry(prefix2, nextHop2);
+
+        assertThat(routeEntry1, is(routeEntry2));
+
+        Ip6Prefix prefix3 = Ip6Prefix.valueOf("1000::/64");
+        Ip6Address nextHop3 = Ip6Address.valueOf("2000::2");
+        RouteEntry routeEntry3 = new RouteEntry(prefix3, nextHop3);
+
+        Ip6Prefix prefix4 = Ip6Prefix.valueOf("1000::/64");
+        Ip6Address nextHop4 = Ip6Address.valueOf("2000::2");
+        RouteEntry routeEntry4 = new RouteEntry(prefix4, nextHop4);
+
+        assertThat(routeEntry3, is(routeEntry4));
+    }
+
+    /**
+     * Tests non-equality of {@link RouteEntry}.
+     */
+    @Test
+    public void testNonEquality() {
+        Ip4Prefix prefix1 = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop1 = Ip4Address.valueOf("5.6.7.8");
+        RouteEntry routeEntry1 = new RouteEntry(prefix1, nextHop1);
+
+        Ip4Prefix prefix2 = Ip4Prefix.valueOf("1.2.3.0/25");      // Different
+        Ip4Address nextHop2 = Ip4Address.valueOf("5.6.7.8");
+        RouteEntry routeEntry2 = new RouteEntry(prefix2, nextHop2);
+
+        Ip4Prefix prefix3 = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop3 = Ip4Address.valueOf("5.6.7.9");      // Different
+        RouteEntry routeEntry3 = new RouteEntry(prefix3, nextHop3);
+
+        assertThat(routeEntry1, Matchers.is(Matchers.not(routeEntry2)));
+        assertThat(routeEntry1, Matchers.is(Matchers.not(routeEntry3)));
+
+        Ip6Prefix prefix4 = Ip6Prefix.valueOf("1000::/64");
+        Ip6Address nextHop4 = Ip6Address.valueOf("2000::1");
+        RouteEntry routeEntry4 = new RouteEntry(prefix4, nextHop4);
+
+        Ip6Prefix prefix5 = Ip6Prefix.valueOf("1000::/65");
+        Ip6Address nextHop5 = Ip6Address.valueOf("2000::1");
+        RouteEntry routeEntry5 = new RouteEntry(prefix5, nextHop5);
+
+        Ip6Prefix prefix6 = Ip6Prefix.valueOf("1000::/64");
+        Ip6Address nextHop6 = Ip6Address.valueOf("2000::2");
+        RouteEntry routeEntry6 = new RouteEntry(prefix6, nextHop6);
+
+        assertThat(routeEntry4, Matchers.is(Matchers.not(routeEntry5)));
+        assertThat(routeEntry4, Matchers.is(Matchers.not(routeEntry6)));
+    }
+
+    /**
+     * Tests object string representation.
+     */
+    @Test
+    public void testToString() {
+        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
+        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
+        RouteEntry routeEntry = new RouteEntry(prefix, nextHop);
+
+        assertThat(routeEntry.toString(),
+                   is("RouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8}"));
+
+        Ip6Prefix prefix6 = Ip6Prefix.valueOf("1000::/64");
+        Ip6Address nextHop6 = Ip6Address.valueOf("2000::1");
+        RouteEntry routeEntry6 = new RouteEntry(prefix6, nextHop6);
+
+        assertThat(routeEntry6.toString(),
+                   is("RouteEntry{prefix=1000::/64, nextHop=2000::1}"));
+    }
+}
diff --git a/apps/routing/common/src/test/java/org/onosproject/routing/bgp/TestBgpPeerChannelHandler.java b/apps/routing/common/src/test/java/org/onosproject/routing/bgp/TestBgpPeerChannelHandler.java
new file mode 100644
index 0000000..5ce6462
--- /dev/null
+++ b/apps/routing/common/src/test/java/org/onosproject/routing/bgp/TestBgpPeerChannelHandler.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.routing.bgp;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelStateEvent;
+import org.jboss.netty.channel.SimpleChannelHandler;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+
+import java.util.Collection;
+
+/**
+ * Class for handling the remote BGP Peer session.
+ */
+class TestBgpPeerChannelHandler extends SimpleChannelHandler {
+    static final long PEER_AS = 65001;
+    static final long PEER_AS4 = 0x12345678;
+    static final int PEER_HOLDTIME = 120;       // 120 seconds
+
+    final BgpSessionInfo localInfo = new BgpSessionInfo();
+    ChannelHandlerContext savedCtx;
+
+    /**
+     * Constructor for given BGP ID.
+     *
+     * @param bgpId the BGP ID to use
+     */
+    TestBgpPeerChannelHandler(Ip4Address bgpId) {
+        this.localInfo.setBgpVersion(BgpConstants.BGP_VERSION);
+        this.localInfo.setBgpId(bgpId);
+        this.localInfo.setAsNumber(PEER_AS);
+        this.localInfo.setHoldtime(PEER_HOLDTIME);
+    }
+
+    /**
+     * Closes the channel.
+     */
+    void closeChannel() {
+        savedCtx.getChannel().close();
+    }
+
+    @Override
+    public void channelConnected(ChannelHandlerContext ctx,
+                                 ChannelStateEvent channelEvent) {
+        this.savedCtx = ctx;
+        // Prepare and transmit BGP OPEN message
+        ChannelBuffer message = BgpOpen.prepareBgpOpen(localInfo);
+        ctx.getChannel().write(message);
+
+        // Prepare and transmit BGP KEEPALIVE message
+        message = BgpKeepalive.prepareBgpKeepalive();
+        ctx.getChannel().write(message);
+    }
+
+    @Override
+    public void channelDisconnected(ChannelHandlerContext ctx,
+                                    ChannelStateEvent channelEvent) {
+        // Nothing to do
+    }
+
+    /**
+     * Prepares BGP UPDATE message.
+     *
+     * @param nextHopRouter the next-hop router address for the routes to add
+     * @param localPref the local preference for the routes to use
+     * @param multiExitDisc the MED value
+     * @param asPath the AS path for the routes to add
+     * @param addedRoutes the routes to add
+     * @param withdrawnRoutes the routes to withdraw
+     * @return the message to transmit (BGP header included)
+     */
+    ChannelBuffer prepareBgpUpdate(Ip4Address nextHopRouter,
+                                   long localPref,
+                                   long multiExitDisc,
+                                   BgpRouteEntry.AsPath asPath,
+                                   Collection<Ip4Prefix> addedRoutes,
+                                   Collection<Ip4Prefix> withdrawnRoutes) {
+        int attrFlags;
+        ChannelBuffer message =
+            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
+        ChannelBuffer pathAttributes =
+            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
+
+        // Encode the Withdrawn Routes
+        ChannelBuffer encodedPrefixes = encodePackedPrefixes(withdrawnRoutes);
+        message.writeShort(encodedPrefixes.readableBytes());
+        message.writeBytes(encodedPrefixes);
+
+        // Encode the Path Attributes
+        // ORIGIN: IGP
+        attrFlags = 0x40;                               // Transitive flag
+        pathAttributes.writeByte(attrFlags);
+        pathAttributes.writeByte(BgpConstants.Update.Origin.TYPE);
+        pathAttributes.writeByte(1);                    // Data length
+        pathAttributes.writeByte(BgpConstants.Update.Origin.IGP);
+
+        // AS_PATH: asPath
+        attrFlags = 0x40;                               // Transitive flag
+        pathAttributes.writeByte(attrFlags);
+        pathAttributes.writeByte(BgpConstants.Update.AsPath.TYPE);
+        ChannelBuffer encodedAsPath = encodeAsPath(asPath);
+        pathAttributes.writeByte(encodedAsPath.readableBytes()); // Data length
+        pathAttributes.writeBytes(encodedAsPath);
+        // NEXT_HOP: nextHopRouter
+        attrFlags = 0x40;                               // Transitive flag
+        pathAttributes.writeByte(attrFlags);
+        pathAttributes.writeByte(BgpConstants.Update.NextHop.TYPE);
+        pathAttributes.writeByte(4);                    // Data length
+        pathAttributes.writeInt(nextHopRouter.toInt()); // Next-hop router
+        // LOCAL_PREF: localPref
+        attrFlags = 0x40;                               // Transitive flag
+        pathAttributes.writeByte(attrFlags);
+        pathAttributes.writeByte(BgpConstants.Update.LocalPref.TYPE);
+        pathAttributes.writeByte(4);                    // Data length
+        pathAttributes.writeInt((int) localPref);       // Preference value
+        // MULTI_EXIT_DISC: multiExitDisc
+        attrFlags = 0x80;                               // Optional
+                                                        // Non-Transitive flag
+        pathAttributes.writeByte(attrFlags);
+        pathAttributes.writeByte(BgpConstants.Update.MultiExitDisc.TYPE);
+        pathAttributes.writeByte(4);                    // Data length
+        pathAttributes.writeInt((int) multiExitDisc);   // Preference value
+        // The NLRI prefixes
+        encodedPrefixes = encodePackedPrefixes(addedRoutes);
+
+        // Write the Path Attributes, beginning with its length
+        message.writeShort(pathAttributes.readableBytes());
+        message.writeBytes(pathAttributes);
+        message.writeBytes(encodedPrefixes);
+
+        return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_UPDATE,
+                                            message);
+    }
+
+    /**
+     * Encodes a collection of IPv4 network prefixes in a packed format.
+     * <p>
+     * The IPv4 prefixes are encoded in the form:
+     * <Length, Prefix> where Length is the length in bits of the IPv4 prefix,
+     * and Prefix is the IPv4 prefix (padded with trailing bits to the end
+     * of an octet).
+     *
+     * @param prefixes the prefixes to encode
+     * @return the buffer with the encoded prefixes
+     */
+    private ChannelBuffer encodePackedPrefixes(Collection<Ip4Prefix> prefixes) {
+        ChannelBuffer message =
+            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
+
+        // Write each of the prefixes
+        for (Ip4Prefix prefix : prefixes) {
+            int prefixBitlen = prefix.prefixLength();
+            int prefixBytelen = (prefixBitlen + 7) / 8;         // Round-up
+            message.writeByte(prefixBitlen);
+
+            Ip4Address address = prefix.address();
+            long value = address.toInt() & 0xffffffffL;
+            for (int i = 0; i < Ip4Address.BYTE_LENGTH; i++) {
+                if (prefixBytelen-- == 0) {
+                    break;
+                }
+                long nextByte =
+                    (value >> ((Ip4Address.BYTE_LENGTH - i - 1) * 8)) & 0xff;
+                message.writeByte((int) nextByte);
+            }
+        }
+
+        return message;
+    }
+
+    /**
+     * Encodes an AS path.
+     *
+     * @param asPath the AS path to encode
+     * @return the buffer with the encoded AS path
+     */
+    private ChannelBuffer encodeAsPath(BgpRouteEntry.AsPath asPath) {
+        ChannelBuffer message =
+            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
+
+        for (BgpRouteEntry.PathSegment pathSegment : asPath.getPathSegments()) {
+            message.writeByte(pathSegment.getType());
+            message.writeByte(pathSegment.getSegmentAsNumbers().size());
+            for (Long asNumber : pathSegment.getSegmentAsNumbers()) {
+                message.writeShort(asNumber.intValue());
+            }
+        }
+
+        return message;
+    }
+}
diff --git a/apps/routing/common/src/test/java/org/onosproject/routing/bgp/TestBgpPeerFrameDecoder.java b/apps/routing/common/src/test/java/org/onosproject/routing/bgp/TestBgpPeerFrameDecoder.java
new file mode 100644
index 0000000..ef9f1d3
--- /dev/null
+++ b/apps/routing/common/src/test/java/org/onosproject/routing/bgp/TestBgpPeerFrameDecoder.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.routing.bgp;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.handler.codec.frame.FrameDecoder;
+import org.onlab.packet.Ip4Address;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Class for handling the decoding of the BGP messages at the remote
+ * BGP peer session.
+ */
+class TestBgpPeerFrameDecoder extends FrameDecoder {
+    final BgpSessionInfo remoteInfo = new BgpSessionInfo();
+
+    final CountDownLatch receivedOpenMessageLatch = new CountDownLatch(1);
+    final CountDownLatch receivedKeepaliveMessageLatch = new CountDownLatch(1);
+
+    @Override
+    protected Object decode(ChannelHandlerContext ctx,
+                            Channel channel,
+                            ChannelBuffer buf) throws Exception {
+        // Test for minimum length of the BGP message
+        if (buf.readableBytes() < BgpConstants.BGP_HEADER_LENGTH) {
+            // No enough data received
+            return null;
+        }
+
+        //
+        // Mark the current buffer position in case we haven't received
+        // the whole message.
+        //
+        buf.markReaderIndex();
+
+        //
+        // Read and check the BGP message Marker field: it must be all ones
+        //
+        byte[] marker = new byte[BgpConstants.BGP_HEADER_MARKER_LENGTH];
+        buf.readBytes(marker);
+        for (int i = 0; i < marker.length; i++) {
+            if (marker[i] != (byte) 0xff) {
+                // ERROR: Connection Not Synchronized. Close the channel.
+                ctx.getChannel().close();
+                return null;
+            }
+        }
+
+        //
+        // Read and check the BGP message Length field
+        //
+        int length = buf.readUnsignedShort();
+        if ((length < BgpConstants.BGP_HEADER_LENGTH) ||
+            (length > BgpConstants.BGP_MESSAGE_MAX_LENGTH)) {
+            // ERROR: Bad Message Length. Close the channel.
+            ctx.getChannel().close();
+            return null;
+        }
+
+        //
+        // Test whether the rest of the message is received:
+        // So far we have read the Marker (16 octets) and the
+        // Length (2 octets) fields.
+        //
+        int remainingMessageLen =
+            length - BgpConstants.BGP_HEADER_MARKER_LENGTH - 2;
+        if (buf.readableBytes() < remainingMessageLen) {
+            // No enough data received
+            buf.resetReaderIndex();
+            return null;
+        }
+
+        //
+        // Read the BGP message Type field, and process based on that type
+        //
+        int type = buf.readUnsignedByte();
+        remainingMessageLen--;      // Adjust after reading the type
+        ChannelBuffer message = buf.readBytes(remainingMessageLen);
+
+        //
+        // Process the remaining of the message based on the message type
+        //
+        switch (type) {
+        case BgpConstants.BGP_TYPE_OPEN:
+            processBgpOpen(ctx, message);
+            break;
+        case BgpConstants.BGP_TYPE_UPDATE:
+            // NOTE: Not used as part of the test, because ONOS does not
+            // originate UPDATE messages.
+            break;
+        case BgpConstants.BGP_TYPE_NOTIFICATION:
+            // NOTE: Not used as part of the testing (yet)
+            break;
+        case BgpConstants.BGP_TYPE_KEEPALIVE:
+            processBgpKeepalive(ctx, message);
+            break;
+        default:
+            // ERROR: Bad Message Type. Close the channel.
+            ctx.getChannel().close();
+            return null;
+        }
+
+        return null;
+    }
+
+    /**
+     * Processes BGP OPEN message.
+     *
+     * @param ctx the Channel Handler Context.
+     * @param message the message to process.
+     */
+    private void processBgpOpen(ChannelHandlerContext ctx,
+                                ChannelBuffer message) {
+        int minLength =
+            BgpConstants.BGP_OPEN_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH;
+        if (message.readableBytes() < minLength) {
+            // ERROR: Bad Message Length. Close the channel.
+            ctx.getChannel().close();
+            return;
+        }
+
+        //
+        // Parse the OPEN message
+        //
+        remoteInfo.setBgpVersion(message.readUnsignedByte());
+        remoteInfo.setAsNumber(message.readUnsignedShort());
+        remoteInfo.setHoldtime(message.readUnsignedShort());
+        remoteInfo.setBgpId(Ip4Address.valueOf((int) message.readUnsignedInt()));
+        // Optional Parameters
+        int optParamLen = message.readUnsignedByte();
+        if (message.readableBytes() < optParamLen) {
+            // ERROR: Bad Message Length. Close the channel.
+            ctx.getChannel().close();
+            return;
+        }
+        message.readBytes(optParamLen);             // NOTE: data ignored
+
+        // BGP OPEN message successfully received
+        receivedOpenMessageLatch.countDown();
+    }
+
+    /**
+     * Processes BGP KEEPALIVE message.
+     *
+     * @param ctx the Channel Handler Context.
+     * @param message the message to process.
+     */
+    private void processBgpKeepalive(ChannelHandlerContext ctx,
+                                     ChannelBuffer message) {
+        if (message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH !=
+            BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH) {
+            // ERROR: Bad Message Length. Close the channel.
+            ctx.getChannel().close();
+            return;
+        }
+        // BGP KEEPALIVE message successfully received
+        receivedKeepaliveMessageLatch.countDown();
+    }
+}
