diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpFrameDecoder.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpFrameDecoder.java
index 781403d..4c9b56e 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpFrameDecoder.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpFrameDecoder.java
@@ -90,8 +90,9 @@
                 int errorSubcode =
                     MessageHeaderError.CONNECTION_NOT_SYNCHRONIZED;
                 ChannelBuffer txMessage =
-                    bgpSession.prepareBgpNotification(errorCode, errorSubcode,
-                                                      null);
+                    BgpNotification.prepareBgpNotification(errorCode,
+                                                           errorSubcode,
+                                                           null);
                 ctx.getChannel().write(txMessage);
                 bgpSession.closeSession(ctx);
                 return null;
@@ -114,7 +115,7 @@
             //
             // Send NOTIFICATION and close the connection
             ChannelBuffer txMessage =
-                bgpSession.prepareBgpNotificationBadMessageLength(length);
+                BgpNotification.prepareBgpNotificationBadMessageLength(length);
             ctx.getChannel().write(txMessage);
             bgpSession.closeSession(ctx);
             return null;
@@ -145,16 +146,16 @@
         //
         switch (type) {
         case BgpConstants.BGP_TYPE_OPEN:
-            bgpSession.processBgpOpen(ctx, message);
+            BgpOpen.processBgpOpen(bgpSession, ctx, message);
             break;
         case BgpConstants.BGP_TYPE_UPDATE:
-            bgpSession.processBgpUpdate(ctx, message);
+            BgpUpdate.processBgpUpdate(bgpSession, ctx, message);
             break;
         case BgpConstants.BGP_TYPE_NOTIFICATION:
-            bgpSession.processBgpNotification(ctx, message);
+            BgpNotification.processBgpNotification(bgpSession, ctx, message);
             break;
         case BgpConstants.BGP_TYPE_KEEPALIVE:
-            bgpSession.processBgpKeepalive(ctx, message);
+            BgpKeepalive.processBgpKeepalive(bgpSession, ctx, message);
             break;
         default:
             //
@@ -166,8 +167,8 @@
             ChannelBuffer data = ChannelBuffers.buffer(1);
             data.writeByte(type);
             ChannelBuffer txMessage =
-                bgpSession.prepareBgpNotification(errorCode, errorSubcode,
-                                                  data);
+                BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                       data);
             ctx.getChannel().write(txMessage);
             bgpSession.closeSession(ctx);
             return null;
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpKeepalive.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpKeepalive.java
new file mode 100644
index 0000000..833f2f9
--- /dev/null
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpKeepalive.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2014 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.sdnip.bgp;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A class for handling BGP KEEPALIVE messages.
+ */
+final class BgpKeepalive {
+    private static final Logger log =
+        LoggerFactory.getLogger(BgpKeepalive.class);
+
+    /**
+     * Default constructor.
+     * <p>
+     * The constructor is private to prevent creating an instance of
+     * this utility class.
+     */
+    private BgpKeepalive() {
+    }
+
+    /**
+     * Processes BGP KEEPALIVE message.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param message the message to process
+     */
+    static void processBgpKeepalive(BgpSession bgpSession,
+                                    ChannelHandlerContext ctx,
+                                    ChannelBuffer message) {
+        if (message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH !=
+            BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH) {
+            log.debug("BGP RX KEEPALIVE Error from {}: " +
+                      "Invalid total message length {}. Expected {}",
+                      bgpSession.getRemoteAddress(),
+                      message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH,
+                      BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH);
+            //
+            // ERROR: Bad Message Length
+            //
+            // Send NOTIFICATION and close the connection
+            ChannelBuffer txMessage =
+                BgpNotification.prepareBgpNotificationBadMessageLength(
+                message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH);
+            ctx.getChannel().write(txMessage);
+            bgpSession.closeSession(ctx);
+            return;
+        }
+
+        //
+        // Parse the KEEPALIVE message: nothing to do
+        //
+        log.trace("BGP RX KEEPALIVE message from {}",
+                  bgpSession.getRemoteAddress());
+
+        // Start the Session Timeout timer
+        bgpSession.restartSessionTimeoutTimer(ctx);
+    }
+
+    /**
+     * Prepares BGP KEEPALIVE message.
+     *
+     * @return the message to transmit (BGP header included)
+     */
+    static ChannelBuffer prepareBgpKeepalive() {
+        ChannelBuffer message =
+            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
+
+        //
+        // Prepare the KEEPALIVE message payload: nothing to do
+        //
+        return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_KEEPALIVE,
+                                            message);
+    }
+}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpMessage.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpMessage.java
new file mode 100644
index 0000000..292872f
--- /dev/null
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpMessage.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2014 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.sdnip.bgp;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A class for preparing BGP messages.
+ */
+final class BgpMessage {
+    private static final Logger log =
+        LoggerFactory.getLogger(BgpMessage.class);
+
+    /**
+     * Default constructor.
+     * <p>
+     * The constructor is private to prevent creating an instance of
+     * this utility class.
+     */
+    private BgpMessage() {
+    }
+
+    /**
+     * Prepares BGP message.
+     *
+     * @param type the BGP message type
+     * @param payload the message payload to transmit (BGP header excluded)
+     * @return the message to transmit (BGP header included)
+     */
+    static ChannelBuffer prepareBgpMessage(int type, ChannelBuffer payload) {
+        ChannelBuffer message =
+            ChannelBuffers.buffer(BgpConstants.BGP_HEADER_LENGTH +
+                                  payload.readableBytes());
+
+        // Write the marker
+        for (int i = 0; i < BgpConstants.BGP_HEADER_MARKER_LENGTH; i++) {
+            message.writeByte(0xff);
+        }
+
+        // Write the rest of the BGP header
+        message.writeShort(BgpConstants.BGP_HEADER_LENGTH +
+                           payload.readableBytes());
+        message.writeByte(type);
+
+        // Write the payload
+        message.writeBytes(payload);
+        return message;
+    }
+}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpNotification.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpNotification.java
new file mode 100644
index 0000000..4abdbf7
--- /dev/null
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpNotification.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2014 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.sdnip.bgp;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.onosproject.sdnip.bgp.BgpConstants.Notifications.MessageHeaderError;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A class for handling BGP NOTIFICATION messages.
+ */
+final class BgpNotification {
+    private static final Logger log =
+        LoggerFactory.getLogger(BgpNotification.class);
+
+    /**
+     * Default constructor.
+     * <p>
+     * The constructor is private to prevent creating an instance of
+     * this utility class.
+     */
+    private BgpNotification() {
+    }
+
+    /**
+     * Processes BGP NOTIFICATION message.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param message the message to process
+     */
+    static void processBgpNotification(BgpSession bgpSession,
+                                       ChannelHandlerContext ctx,
+                                       ChannelBuffer message) {
+        int minLength =
+            BgpConstants.BGP_NOTIFICATION_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH;
+        if (message.readableBytes() < minLength) {
+            log.debug("BGP RX NOTIFICATION Error from {}: " +
+                      "Message length {} too short. Must be at least {}",
+                      bgpSession.getRemoteAddress(), message.readableBytes(),
+                      minLength);
+            //
+            // ERROR: Bad Message Length
+            //
+            // NOTE: We do NOT send NOTIFICATION in response to a notification
+            return;
+        }
+
+        //
+        // Parse the NOTIFICATION message
+        //
+        int errorCode = message.readUnsignedByte();
+        int errorSubcode = message.readUnsignedByte();
+        int dataLength = message.readableBytes();
+
+        log.debug("BGP RX NOTIFICATION message from {}: Error Code {} " +
+                  "Error Subcode {} Data Length {}",
+                  bgpSession.getRemoteAddress(), errorCode, errorSubcode,
+                  dataLength);
+
+        //
+        // NOTE: If the peer sent a NOTIFICATION, we leave it to the peer to
+        // close the connection.
+        //
+
+        // Start the Session Timeout timer
+        bgpSession.restartSessionTimeoutTimer(ctx);
+    }
+
+    /**
+     * Prepares BGP NOTIFICATION message.
+     *
+     * @param errorCode the BGP NOTIFICATION Error Code
+     * @param errorSubcode the BGP NOTIFICATION Error Subcode if applicable,
+     * otherwise BgpConstants.Notifications.ERROR_SUBCODE_UNSPECIFIC
+     * @param data the BGP NOTIFICATION Data if applicable, otherwise null
+     * @return the message to transmit (BGP header included)
+     */
+    static ChannelBuffer prepareBgpNotification(int errorCode,
+                                                int errorSubcode,
+                                                ChannelBuffer data) {
+        ChannelBuffer message =
+            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
+
+        //
+        // Prepare the NOTIFICATION message payload
+        //
+        message.writeByte(errorCode);
+        message.writeByte(errorSubcode);
+        if (data != null) {
+            message.writeBytes(data);
+        }
+        return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_NOTIFICATION,
+                                            message);
+    }
+
+    /**
+     * Prepares BGP NOTIFICATION message: Bad Message Length.
+     *
+     * @param length the erroneous Length field
+     * @return the message to transmit (BGP header included)
+     */
+    static ChannelBuffer prepareBgpNotificationBadMessageLength(int length) {
+        int errorCode = MessageHeaderError.ERROR_CODE;
+        int errorSubcode = MessageHeaderError.BAD_MESSAGE_LENGTH;
+        ChannelBuffer data = ChannelBuffers.buffer(2);
+        data.writeShort(length);
+
+        return prepareBgpNotification(errorCode, errorSubcode, data);
+    }
+}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpOpen.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpOpen.java
new file mode 100644
index 0000000..92086f3
--- /dev/null
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpOpen.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2014 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.sdnip.bgp;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.sdnip.bgp.BgpConstants.Notifications;
+import org.onosproject.sdnip.bgp.BgpConstants.Notifications.OpenMessageError;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A class for handling BGP OPEN messages.
+ */
+final class BgpOpen {
+    private static final Logger log = LoggerFactory.getLogger(BgpOpen.class);
+
+    /**
+     * Default constructor.
+     * <p>
+     * The constructor is private to prevent creating an instance of
+     * this utility class.
+     */
+    private BgpOpen() {
+    }
+
+    /**
+     * Processes BGP OPEN message.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param message the message to process
+     */
+    static void processBgpOpen(BgpSession bgpSession,
+                               ChannelHandlerContext ctx,
+                               ChannelBuffer message) {
+        int minLength =
+            BgpConstants.BGP_OPEN_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH;
+        if (message.readableBytes() < minLength) {
+            log.debug("BGP RX OPEN Error from {}: " +
+                      "Message length {} too short. Must be at least {}",
+                      bgpSession.getRemoteAddress(), message.readableBytes(),
+                      minLength);
+            //
+            // ERROR: Bad Message Length
+            //
+            // Send NOTIFICATION and close the connection
+            ChannelBuffer txMessage =
+                BgpNotification.prepareBgpNotificationBadMessageLength(
+                        message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH);
+            ctx.getChannel().write(txMessage);
+            bgpSession.closeSession(ctx);
+            return;
+        }
+
+        //
+        // Parse the OPEN message
+        //
+        // Remote BGP version
+        int remoteBgpVersion = message.readUnsignedByte();
+        if (remoteBgpVersion != BgpConstants.BGP_VERSION) {
+            log.debug("BGP RX OPEN Error from {}: " +
+                      "Unsupported BGP version {}. Should be {}",
+                      bgpSession.getRemoteAddress(), remoteBgpVersion,
+                      BgpConstants.BGP_VERSION);
+            //
+            // ERROR: Unsupported Version Number
+            //
+            // Send NOTIFICATION and close the connection
+            int errorCode = OpenMessageError.ERROR_CODE;
+            int errorSubcode = OpenMessageError.UNSUPPORTED_VERSION_NUMBER;
+            ChannelBuffer data = ChannelBuffers.buffer(2);
+            data.writeShort(BgpConstants.BGP_VERSION);
+            ChannelBuffer txMessage =
+                BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                       data);
+            ctx.getChannel().write(txMessage);
+            bgpSession.closeSession(ctx);
+            return;
+        }
+        bgpSession.setRemoteBgpVersion(remoteBgpVersion);
+
+        // Remote AS number
+        long remoteAs = message.readUnsignedShort();
+        //
+        // Verify that the AS number is same for all other BGP Sessions
+        // NOTE: This check applies only for our use-case where all BGP
+        // sessions are iBGP.
+        //
+        for (BgpSession bs : bgpSession.getBgpSessionManager().getBgpSessions()) {
+            if ((bs.getRemoteAs() != 0) && (remoteAs != bs.getRemoteAs())) {
+                log.debug("BGP RX OPEN Error from {}: Bad Peer AS {}. " +
+                          "Expected {}",
+                          bgpSession.getRemoteAddress(), remoteAs,
+                          bs.getRemoteAs());
+                //
+                // ERROR: Bad Peer AS
+                //
+                // Send NOTIFICATION and close the connection
+                int errorCode = OpenMessageError.ERROR_CODE;
+                int errorSubcode = OpenMessageError.BAD_PEER_AS;
+                ChannelBuffer txMessage =
+                    BgpNotification.prepareBgpNotification(errorCode,
+                                                           errorSubcode, null);
+                ctx.getChannel().write(txMessage);
+                bgpSession.closeSession(ctx);
+                return;
+            }
+        }
+        bgpSession.setRemoteAs(remoteAs);
+
+        // Remote Hold Time
+        long remoteHoldtime = message.readUnsignedShort();
+        if ((remoteHoldtime != 0) &&
+            (remoteHoldtime < BgpConstants.BGP_KEEPALIVE_MIN_HOLDTIME)) {
+            log.debug("BGP RX OPEN Error from {}: " +
+                      "Unacceptable Hold Time field {}. " +
+                      "Should be 0 or at least {}",
+                      bgpSession.getRemoteAddress(), remoteHoldtime,
+                      BgpConstants.BGP_KEEPALIVE_MIN_HOLDTIME);
+            //
+            // ERROR: Unacceptable Hold Time
+            //
+            // Send NOTIFICATION and close the connection
+            int errorCode = OpenMessageError.ERROR_CODE;
+            int errorSubcode = OpenMessageError.UNACCEPTABLE_HOLD_TIME;
+            ChannelBuffer txMessage =
+                BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                       null);
+            ctx.getChannel().write(txMessage);
+            bgpSession.closeSession(ctx);
+            return;
+        }
+        bgpSession.setRemoteHoldtime(remoteHoldtime);
+
+        // Remote BGP Identifier
+        Ip4Address remoteBgpId =
+            Ip4Address.valueOf((int) message.readUnsignedInt());
+        bgpSession.setRemoteBgpId(remoteBgpId);
+
+        // Optional Parameters
+        int optParamLen = message.readUnsignedByte();
+        if (message.readableBytes() < optParamLen) {
+            log.debug("BGP RX OPEN Error from {}: " +
+                      "Invalid Optional Parameter Length field {}. " +
+                      "Remaining Optional Parameters {}",
+                      bgpSession.getRemoteAddress(), optParamLen,
+                      message.readableBytes());
+            //
+            // ERROR: Invalid Optional Parameter Length field: Unspecific
+            //
+            // Send NOTIFICATION and close the connection
+            int errorCode = OpenMessageError.ERROR_CODE;
+            int errorSubcode = Notifications.ERROR_SUBCODE_UNSPECIFIC;
+            ChannelBuffer txMessage =
+                BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                       null);
+            ctx.getChannel().write(txMessage);
+            bgpSession.closeSession(ctx);
+            return;
+        }
+        // NOTE: Parse the optional parameters (if needed)
+        message.readBytes(optParamLen);             // NOTE: data ignored
+
+        log.debug("BGP RX OPEN message from {}: " +
+                  "BGPv{} AS {} BGP-ID {} Holdtime {}",
+                  bgpSession.getRemoteAddress(), remoteBgpVersion, remoteAs,
+                  remoteBgpId, remoteHoldtime);
+
+        // Send my OPEN followed by KEEPALIVE
+        ChannelBuffer txMessage = prepareBgpOpen(bgpSession);
+        ctx.getChannel().write(txMessage);
+        //
+        txMessage = BgpKeepalive.prepareBgpKeepalive();
+        ctx.getChannel().write(txMessage);
+
+        // Start the KEEPALIVE timer
+        bgpSession.restartKeepaliveTimer(ctx);
+
+        // Start the Session Timeout timer
+        bgpSession.restartSessionTimeoutTimer(ctx);
+    }
+
+    /**
+     * Prepares BGP OPEN message.
+     *
+     * @param bgpSession the BGP Session to use
+     * @return the message to transmit (BGP header included)
+     */
+    private static ChannelBuffer prepareBgpOpen(BgpSession bgpSession) {
+        ChannelBuffer message =
+            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
+
+        //
+        // Prepare the OPEN message payload
+        //
+        message.writeByte(bgpSession.getLocalBgpVersion());
+        message.writeShort((int) bgpSession.getLocalAs());
+        message.writeShort((int) bgpSession.getLocalHoldtime());
+        message.writeInt(bgpSession.getLocalBgpId().toInt());
+        message.writeByte(0);               // No Optional Parameters
+        return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_OPEN,
+                                            message);
+    }
+}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSession.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSession.java
index a60cfc8..248085b 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSession.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSession.java
@@ -18,18 +18,14 @@
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.TimeUnit;
 
-import org.apache.commons.lang3.tuple.Pair;
 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.ExceptionEvent;
@@ -42,9 +38,6 @@
 import org.onlab.packet.Ip4Prefix;
 import org.onosproject.sdnip.bgp.BgpConstants.Notifications;
 import org.onosproject.sdnip.bgp.BgpConstants.Notifications.HoldTimerExpired;
-import org.onosproject.sdnip.bgp.BgpConstants.Notifications.MessageHeaderError;
-import org.onosproject.sdnip.bgp.BgpConstants.Notifications.OpenMessageError;
-import org.onosproject.sdnip.bgp.BgpConstants.Notifications.UpdateMessageError;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -94,6 +87,18 @@
      */
     BgpSession(BgpSessionManager bgpSessionManager) {
         this.bgpSessionManager = bgpSessionManager;
+
+        // NOTE: We support only BGP4
+        this.localBgpVersion = BgpConstants.BGP_VERSION;
+    }
+
+    /**
+     * Gets the BGP Session Manager.
+     *
+     * @return the BGP Session Manager
+     */
+    BgpSessionManager getBgpSessionManager() {
+        return bgpSessionManager;
     }
 
     /**
@@ -101,8 +106,8 @@
      *
      * @return the BGP RIB-IN routing entries
      */
-    public Collection<BgpRouteEntry> getBgpRibIn() {
-        return bgpRibIn.values();
+    public Map<Ip4Prefix, BgpRouteEntry> bgpRibIn() {
+        return bgpRibIn;
     }
 
     /**
@@ -143,6 +148,15 @@
     }
 
     /**
+     * Sets the BGP session remote BGP version.
+     *
+     * @param remoteBgpVersion the BGP session remote BGP version to set
+     */
+     void setRemoteBgpVersion(int remoteBgpVersion) {
+         this.remoteBgpVersion = remoteBgpVersion;
+     }
+
+    /**
      * Gets the BGP session remote AS number.
      *
      * @return the BGP session remote AS number
@@ -152,6 +166,23 @@
     }
 
     /**
+     * Sets the BGP session remote AS number.
+     *
+     * @param remoteAs the BGP session remote AS number to set
+     */
+    void setRemoteAs(long remoteAs) {
+        this.remoteAs = remoteAs;
+
+        //
+        // NOTE: Currently, the local AS number is always set to the remote AS.
+        // This is done, because the peer setup is always iBGP.
+        // In the future the local AS number should be configured as part
+        // of an explicit BGP peering configuration.
+        //
+        this.localAs = remoteAs;
+    }
+
+    /**
      * Gets the BGP session remote Holdtime.
      *
      * @return the BGP session remote Holdtime
@@ -161,6 +192,32 @@
     }
 
     /**
+     * Sets the BGP session remote Holdtime.
+     *
+     * @param remoteHoldtime the BGP session remote Holdtime to set
+     */
+    void setRemoteHoldtime(long remoteHoldtime) {
+        this.remoteHoldtime = remoteHoldtime;
+
+        //
+        // NOTE: Currently. the local BGP Holdtime is always set to the remote
+        // BGP holdtime.
+        // In the future, the local BGP Holdtime should be configured as part
+        // of an explicit BGP peering configuration.
+        //
+        this.localHoldtime = remoteHoldtime;
+
+        // Set the local Keepalive interval
+        if (localHoldtime == 0) {
+            localKeepaliveInterval = 0;
+        } else {
+            localKeepaliveInterval = Math.max(localHoldtime /
+                         BgpConstants.BGP_KEEPALIVE_PER_HOLD_INTERVAL,
+                         BgpConstants.BGP_KEEPALIVE_MIN_INTERVAL);
+        }
+    }
+
+    /**
      * Gets the BGP session remote BGP Identifier as an IPv4 address.
      *
      * @return the BGP session remote BGP Identifier as an IPv4 address
@@ -170,6 +227,15 @@
     }
 
     /**
+     * Sets the BGP session remote BGP Identifier as an IPv4 address.
+     *
+     * @param remoteBgpId the BGP session remote BGP Identifier to set
+     */
+    void setRemoteBgpId(Ip4Address remoteBgpId) {
+        this.remoteBgpId = remoteBgpId;
+    }
+
+    /**
      * Gets the BGP session local address.
      *
      * @return the BGP session local address
@@ -179,6 +245,15 @@
     }
 
     /**
+     * Gets the BGP session local IPv4 address.
+     *
+     * @return the BGP session local IPv4 address
+     */
+    public Ip4Address getLocalIp4Address() {
+        return localIp4Address;
+    }
+
+    /**
      * Gets the BGP session local BGP version.
      *
      * @return the BGP session local BGP version
@@ -282,6 +357,12 @@
                       remoteAddress);
             ctx.getChannel().close();
         }
+
+        //
+        // Assign the local BGP ID
+        // NOTE: This should be configuration-based
+        //
+        localBgpId = bgpSessionManager.getMyBgpId();
     }
 
     @Override
@@ -326,1458 +407,9 @@
     }
 
     /**
-     * Processes BGP OPEN message.
-     *
-     * @param ctx the Channel Handler Context
-     * @param message the message to process
-     */
-    void processBgpOpen(ChannelHandlerContext ctx, ChannelBuffer message) {
-        int minLength =
-            BgpConstants.BGP_OPEN_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH;
-        if (message.readableBytes() < minLength) {
-            log.debug("BGP RX OPEN Error from {}: " +
-                      "Message length {} too short. Must be at least {}",
-                      remoteAddress, message.readableBytes(), minLength);
-            //
-            // ERROR: Bad Message Length
-            //
-            // Send NOTIFICATION and close the connection
-            ChannelBuffer txMessage = prepareBgpNotificationBadMessageLength(
-                message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH);
-            ctx.getChannel().write(txMessage);
-            closeSession(ctx);
-            return;
-        }
-
-        //
-        // Parse the OPEN message
-        //
-        // Remote BGP version
-        remoteBgpVersion = message.readUnsignedByte();
-        if (remoteBgpVersion != BgpConstants.BGP_VERSION) {
-            log.debug("BGP RX OPEN Error from {}: " +
-                      "Unsupported BGP version {}. Should be {}",
-                      remoteAddress, remoteBgpVersion,
-                      BgpConstants.BGP_VERSION);
-            //
-            // ERROR: Unsupported Version Number
-            //
-            // Send NOTIFICATION and close the connection
-            int errorCode = OpenMessageError.ERROR_CODE;
-            int errorSubcode = OpenMessageError.UNSUPPORTED_VERSION_NUMBER;
-            ChannelBuffer data = ChannelBuffers.buffer(2);
-            data.writeShort(BgpConstants.BGP_VERSION);
-            ChannelBuffer txMessage =
-                prepareBgpNotification(errorCode, errorSubcode, data);
-            ctx.getChannel().write(txMessage);
-            closeSession(ctx);
-            return;
-        }
-
-        // Remote AS number
-        remoteAs = message.readUnsignedShort();
-        //
-        // Verify that the AS number is same for all other BGP Sessions
-        // NOTE: This check applies only for our use-case where all BGP
-        // sessions are iBGP.
-        //
-        for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
-            if (remoteAs != bgpSession.getRemoteAs()) {
-                log.debug("BGP RX OPEN Error from {}: Bad Peer AS {}. " +
-                          "Expected {}",
-                          remoteAddress, remoteAs, bgpSession.getRemoteAs());
-                //
-                // ERROR: Bad Peer AS
-                //
-                // Send NOTIFICATION and close the connection
-                int errorCode = OpenMessageError.ERROR_CODE;
-                int errorSubcode = OpenMessageError.BAD_PEER_AS;
-                ChannelBuffer txMessage =
-                    prepareBgpNotification(errorCode, errorSubcode, null);
-                ctx.getChannel().write(txMessage);
-                closeSession(ctx);
-                return;
-            }
-        }
-
-        // Remote Hold Time
-        remoteHoldtime = message.readUnsignedShort();
-        if ((remoteHoldtime != 0) &&
-            (remoteHoldtime < BgpConstants.BGP_KEEPALIVE_MIN_HOLDTIME)) {
-            log.debug("BGP RX OPEN Error from {}: " +
-                      "Unacceptable Hold Time field {}. " +
-                      "Should be 0 or at least {}",
-                      remoteAddress, remoteHoldtime,
-                      BgpConstants.BGP_KEEPALIVE_MIN_HOLDTIME);
-            //
-            // ERROR: Unacceptable Hold Time
-            //
-            // Send NOTIFICATION and close the connection
-            int errorCode = OpenMessageError.ERROR_CODE;
-            int errorSubcode = OpenMessageError.UNACCEPTABLE_HOLD_TIME;
-            ChannelBuffer txMessage =
-                prepareBgpNotification(errorCode, errorSubcode, null);
-            ctx.getChannel().write(txMessage);
-            closeSession(ctx);
-            return;
-        }
-
-        // Remote BGP Identifier
-        remoteBgpId = Ip4Address.valueOf((int) message.readUnsignedInt());
-
-        // Optional Parameters
-        int optParamLen = message.readUnsignedByte();
-        if (message.readableBytes() < optParamLen) {
-            log.debug("BGP RX OPEN Error from {}: " +
-                      "Invalid Optional Parameter Length field {}. " +
-                      "Remaining Optional Parameters {}",
-                      remoteAddress, optParamLen, message.readableBytes());
-            //
-            // ERROR: Invalid Optional Parameter Length field: Unspecific
-            //
-            // Send NOTIFICATION and close the connection
-            int errorCode = OpenMessageError.ERROR_CODE;
-            int errorSubcode = Notifications.ERROR_SUBCODE_UNSPECIFIC;
-            ChannelBuffer txMessage =
-                prepareBgpNotification(errorCode, errorSubcode, null);
-            ctx.getChannel().write(txMessage);
-            closeSession(ctx);
-            return;
-        }
-        // NOTE: Parse the optional parameters (if needed)
-        message.readBytes(optParamLen);             // NOTE: data ignored
-
-        //
-        // Copy some of the remote peer's state/setup to the local setup:
-        //  - BGP version
-        //  - AS number (NOTE: the peer setup is always iBGP)
-        //  - Holdtime
-        // Also, assign the local BGP ID based on the local setup
-        //
-        localBgpVersion = remoteBgpVersion;
-        localAs = remoteAs;
-        localHoldtime = remoteHoldtime;
-        localBgpId = bgpSessionManager.getMyBgpId();
-
-        // Set the Keepalive interval
-        if (localHoldtime == 0) {
-            localKeepaliveInterval = 0;
-        } else {
-            localKeepaliveInterval = Math.max(localHoldtime /
-                         BgpConstants.BGP_KEEPALIVE_PER_HOLD_INTERVAL,
-                         BgpConstants.BGP_KEEPALIVE_MIN_INTERVAL);
-        }
-
-        log.debug("BGP RX OPEN message from {}: " +
-                  "BGPv{} AS {} BGP-ID {} Holdtime {}",
-                  remoteAddress, remoteBgpVersion, remoteAs,
-                  remoteBgpId, remoteHoldtime);
-
-        // Send my OPEN followed by KEEPALIVE
-        ChannelBuffer txMessage = prepareBgpOpen();
-        ctx.getChannel().write(txMessage);
-        //
-        txMessage = prepareBgpKeepalive();
-        ctx.getChannel().write(txMessage);
-
-        // Start the KEEPALIVE timer
-        restartKeepaliveTimer(ctx);
-
-        // Start the Session Timeout timer
-        restartSessionTimeoutTimer(ctx);
-    }
-
-    /**
-     * Processes BGP UPDATE message.
-     *
-     * @param ctx the Channel Handler Context
-     * @param message the message to process
-     */
-    void processBgpUpdate(ChannelHandlerContext ctx, ChannelBuffer message) {
-        Collection<BgpRouteEntry> addedRoutes = null;
-        Map<Ip4Prefix, BgpRouteEntry> deletedRoutes = new HashMap<>();
-
-        int minLength =
-            BgpConstants.BGP_UPDATE_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH;
-        if (message.readableBytes() < minLength) {
-            log.debug("BGP RX UPDATE Error from {}: " +
-                      "Message length {} too short. Must be at least {}",
-                      remoteAddress, message.readableBytes(), minLength);
-            //
-            // ERROR: Bad Message Length
-            //
-            // Send NOTIFICATION and close the connection
-            ChannelBuffer txMessage = prepareBgpNotificationBadMessageLength(
-                message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH);
-            ctx.getChannel().write(txMessage);
-            closeSession(ctx);
-            return;
-        }
-
-        log.debug("BGP RX UPDATE message from {}", remoteAddress);
-
-        //
-        // Parse the UPDATE message
-        //
-
-        //
-        // Parse the Withdrawn Routes
-        //
-        int withdrawnRoutesLength = message.readUnsignedShort();
-        if (withdrawnRoutesLength > message.readableBytes()) {
-            // ERROR: Malformed Attribute List
-            actionsBgpUpdateMalformedAttributeList(ctx);
-            return;
-        }
-        Collection<Ip4Prefix> withdrawnPrefixes = null;
-        try {
-            withdrawnPrefixes = parsePackedPrefixes(withdrawnRoutesLength,
-                                                    message);
-        } catch (BgpParseException e) {
-            // ERROR: Invalid Network Field
-            log.debug("Exception parsing Withdrawn Prefixes from BGP peer {}: ",
-                      remoteBgpId, e);
-            actionsBgpUpdateInvalidNetworkField(ctx);
-            return;
-        }
-        for (Ip4Prefix prefix : withdrawnPrefixes) {
-            log.debug("BGP RX UPDATE message WITHDRAWN from {}: {}",
-                      remoteAddress, prefix);
-            BgpRouteEntry bgpRouteEntry = bgpRibIn.get(prefix);
-            if (bgpRouteEntry != null) {
-                deletedRoutes.put(prefix, bgpRouteEntry);
-            }
-        }
-
-        //
-        // Parse the Path Attributes
-        //
-        try {
-            addedRoutes = parsePathAttributes(ctx, message);
-        } catch (BgpParseException e) {
-            log.debug("Exception parsing Path Attributes from BGP peer {}: ",
-                      remoteBgpId, e);
-            // NOTE: The session was already closed, so nothing else to do
-            return;
-        }
-        // Ignore WITHDRAWN routes that are ADDED
-        for (BgpRouteEntry bgpRouteEntry : addedRoutes) {
-            deletedRoutes.remove(bgpRouteEntry.prefix());
-        }
-
-        // Update the BGP RIB-IN
-        for (BgpRouteEntry bgpRouteEntry : deletedRoutes.values()) {
-            bgpRibIn.remove(bgpRouteEntry.prefix());
-        }
-        for (BgpRouteEntry bgpRouteEntry : addedRoutes) {
-            bgpRibIn.put(bgpRouteEntry.prefix(), bgpRouteEntry);
-        }
-
-        // Push the updates to the BGP Merged RIB
-        BgpSessionManager.BgpRouteSelector bgpRouteSelector =
-            bgpSessionManager.getBgpRouteSelector();
-        bgpRouteSelector.routeUpdates(this, addedRoutes,
-                                      deletedRoutes.values());
-
-        // Start the Session Timeout timer
-        restartSessionTimeoutTimer(ctx);
-    }
-
-    /**
-     * Parse BGP Path Attributes from the BGP UPDATE message.
-     *
-     * @param ctx the Channel Handler Context
-     * @param message the message to parse
-     * @return a collection of the result BGP Route Entries
-     * @throws BgpParseException
-     */
-    private Collection<BgpRouteEntry> parsePathAttributes(
-                                ChannelHandlerContext ctx,
-                                ChannelBuffer message)
-        throws BgpParseException {
-        Map<Ip4Prefix, BgpRouteEntry> addedRoutes = new HashMap<>();
-
-        //
-        // Parsed values
-        //
-        Short origin = -1;                      // Mandatory
-        BgpRouteEntry.AsPath asPath = null;     // Mandatory
-        Ip4Address nextHop = null;              // Mandatory
-        long multiExitDisc =                    // Optional
-            BgpConstants.Update.MultiExitDisc.LOWEST_MULTI_EXIT_DISC;
-        Long localPref = null;                  // Mandatory
-        Long aggregatorAsNumber = null;         // Optional: unused
-        Ip4Address aggregatorIpAddress = null;  // Optional: unused
-
-        //
-        // Get and verify the Path Attributes Length
-        //
-        int pathAttributeLength = message.readUnsignedShort();
-        if (pathAttributeLength > message.readableBytes()) {
-            // ERROR: Malformed Attribute List
-            actionsBgpUpdateMalformedAttributeList(ctx);
-            String errorMsg = "Malformed Attribute List";
-            throw new BgpParseException(errorMsg);
-        }
-        if (pathAttributeLength == 0) {
-            return addedRoutes.values();
-        }
-
-        //
-        // Parse the Path Attributes
-        //
-        int pathAttributeEnd = message.readerIndex() + pathAttributeLength;
-        while (message.readerIndex() < pathAttributeEnd) {
-            int attrFlags = message.readUnsignedByte();
-            if (message.readerIndex() >= pathAttributeEnd) {
-                // ERROR: Malformed Attribute List
-                actionsBgpUpdateMalformedAttributeList(ctx);
-                String errorMsg = "Malformed Attribute List";
-                throw new BgpParseException(errorMsg);
-            }
-            int attrTypeCode = message.readUnsignedByte();
-
-            // The Attribute Flags
-            boolean optionalBit =       ((0x80 & attrFlags) != 0);
-            boolean transitiveBit =     ((0x40 & attrFlags) != 0);
-            boolean partialBit =        ((0x20 & attrFlags) != 0);
-            boolean extendedLengthBit = ((0x10 & attrFlags) != 0);
-
-            // The Attribute Length
-            int attrLen = 0;
-            int attrLenOctets = 1;
-            if (extendedLengthBit) {
-                attrLenOctets = 2;
-            }
-            if (message.readerIndex() + attrLenOctets > pathAttributeEnd) {
-                // ERROR: Malformed Attribute List
-                actionsBgpUpdateMalformedAttributeList(ctx);
-                String errorMsg = "Malformed Attribute List";
-                throw new BgpParseException(errorMsg);
-            }
-            if (extendedLengthBit) {
-                attrLen = message.readUnsignedShort();
-            } else {
-                attrLen = message.readUnsignedByte();
-            }
-            if (message.readerIndex() + attrLen > pathAttributeEnd) {
-                // ERROR: Malformed Attribute List
-                actionsBgpUpdateMalformedAttributeList(ctx);
-                String errorMsg = "Malformed Attribute List";
-                throw new BgpParseException(errorMsg);
-            }
-
-            //
-            // Verify the Attribute Flags
-            //
-            verifyBgpUpdateAttributeFlags(ctx, attrTypeCode, attrLen,
-                                          attrFlags, message);
-
-            //
-            // Extract the Attribute Value based on the Attribute Type Code
-            //
-            switch (attrTypeCode) {
-
-            case BgpConstants.Update.Origin.TYPE:
-                // Attribute Type Code ORIGIN
-                origin = parseAttributeTypeOrigin(ctx, attrTypeCode, attrLen,
-                                                  attrFlags, message);
-                break;
-
-            case BgpConstants.Update.AsPath.TYPE:
-                // Attribute Type Code AS_PATH
-                asPath = parseAttributeTypeAsPath(ctx, attrTypeCode, attrLen,
-                                                  attrFlags, message);
-                break;
-
-            case BgpConstants.Update.NextHop.TYPE:
-                // Attribute Type Code NEXT_HOP
-                nextHop = parseAttributeTypeNextHop(ctx, attrTypeCode, attrLen,
-                                                    attrFlags, message);
-                break;
-
-            case BgpConstants.Update.MultiExitDisc.TYPE:
-                // Attribute Type Code MULTI_EXIT_DISC
-                multiExitDisc =
-                    parseAttributeTypeMultiExitDisc(ctx, attrTypeCode, attrLen,
-                                                    attrFlags, message);
-                break;
-
-            case BgpConstants.Update.LocalPref.TYPE:
-                // Attribute Type Code LOCAL_PREF
-                localPref =
-                    parseAttributeTypeLocalPref(ctx, attrTypeCode, attrLen,
-                                                attrFlags, message);
-                break;
-
-            case BgpConstants.Update.AtomicAggregate.TYPE:
-                // Attribute Type Code ATOMIC_AGGREGATE
-                parseAttributeTypeAtomicAggregate(ctx, attrTypeCode, attrLen,
-                                                  attrFlags, message);
-                // Nothing to do: this attribute is primarily informational
-                break;
-
-            case BgpConstants.Update.Aggregator.TYPE:
-                // Attribute Type Code AGGREGATOR
-                Pair<Long, Ip4Address> aggregator =
-                    parseAttributeTypeAggregator(ctx, attrTypeCode, attrLen,
-                                                 attrFlags, message);
-                aggregatorAsNumber = aggregator.getLeft();
-                aggregatorIpAddress = aggregator.getRight();
-                break;
-
-            default:
-                // NOTE: Parse any new Attribute Types if needed
-                if (!optionalBit) {
-                    // ERROR: Unrecognized Well-known Attribute
-                    actionsBgpUpdateUnrecognizedWellKnownAttribute(
-                        ctx, attrTypeCode, attrLen, attrFlags, message);
-                    String errorMsg = "Unrecognized Well-known Attribute: " +
-                        attrTypeCode;
-                    throw new BgpParseException(errorMsg);
-                }
-
-                // Skip the data from the unrecognized attribute
-                log.debug("BGP RX UPDATE message from {}: " +
-                          "Unrecognized Attribute Type {}",
-                          remoteAddress, attrTypeCode);
-                message.skipBytes(attrLen);
-                break;
-            }
-        }
-
-        //
-        // Verify the Well-known Attributes
-        //
-        verifyBgpUpdateWellKnownAttributes(ctx, origin, asPath, nextHop,
-                                           localPref);
-
-        //
-        // Parse the NLRI (Network Layer Reachability Information)
-        //
-        Collection<Ip4Prefix> addedPrefixes = null;
-        int nlriLength = message.readableBytes();
-        try {
-            addedPrefixes = parsePackedPrefixes(nlriLength, message);
-        } catch (BgpParseException e) {
-            // ERROR: Invalid Network Field
-            log.debug("Exception parsing NLRI from BGP peer {}: ",
-                      remoteBgpId, e);
-            actionsBgpUpdateInvalidNetworkField(ctx);
-            // Rethrow the exception
-            throw e;
-        }
-
-        // Generate the added routes
-        for (Ip4Prefix prefix : addedPrefixes) {
-            BgpRouteEntry bgpRouteEntry =
-                new BgpRouteEntry(this, prefix, nextHop,
-                                  origin.byteValue(), asPath, localPref);
-            bgpRouteEntry.setMultiExitDisc(multiExitDisc);
-            if (bgpRouteEntry.hasAsPathLoop(localAs)) {
-                log.debug("BGP RX UPDATE message IGNORED from {}: {} " +
-                          "nextHop {}: contains AS Path loop",
-                          remoteAddress, prefix, nextHop);
-                continue;
-            } else {
-                log.debug("BGP RX UPDATE message ADDED from {}: {} nextHop {}",
-                          remoteAddress, prefix, nextHop);
-            }
-            addedRoutes.put(prefix, bgpRouteEntry);
-        }
-
-        return addedRoutes.values();
-    }
-
-    /**
-     * Verifies BGP UPDATE Well-known Attributes.
-     *
-     * @param ctx the Channel Handler Context
-     * @param origin the ORIGIN well-known mandatory attribute
-     * @param asPath the AS_PATH well-known mandatory attribute
-     * @param nextHop the NEXT_HOP well-known mandatory attribute
-     * @param localPref the LOCAL_PREF required attribute
-     * @throws BgpParseException
-     */
-    private void verifyBgpUpdateWellKnownAttributes(
-                        ChannelHandlerContext ctx,
-                        Short origin,
-                        BgpRouteEntry.AsPath asPath,
-                        Ip4Address nextHop,
-                        Long localPref)
-        throws BgpParseException {
-        //
-        // Check for Missing Well-known Attributes
-        //
-        if ((origin == null) || (origin == -1)) {
-            // Missing Attribute Type Code ORIGIN
-            int type = BgpConstants.Update.Origin.TYPE;
-            actionsBgpUpdateMissingWellKnownAttribute(ctx, type);
-            String errorMsg = "Missing Well-known Attribute: ORIGIN";
-            throw new BgpParseException(errorMsg);
-        }
-        if (asPath == null) {
-            // Missing Attribute Type Code AS_PATH
-            int type = BgpConstants.Update.AsPath.TYPE;
-            actionsBgpUpdateMissingWellKnownAttribute(ctx, type);
-            String errorMsg = "Missing Well-known Attribute: AS_PATH";
-            throw new BgpParseException(errorMsg);
-        }
-        if (nextHop == null) {
-            // Missing Attribute Type Code NEXT_HOP
-            int type = BgpConstants.Update.NextHop.TYPE;
-            actionsBgpUpdateMissingWellKnownAttribute(ctx, type);
-            String errorMsg = "Missing Well-known Attribute: NEXT_HOP";
-            throw new BgpParseException(errorMsg);
-        }
-        if (localPref == null) {
-            // Missing Attribute Type Code LOCAL_PREF
-            // NOTE: Required for iBGP
-            int type = BgpConstants.Update.LocalPref.TYPE;
-            actionsBgpUpdateMissingWellKnownAttribute(ctx, type);
-            String errorMsg = "Missing Well-known Attribute: LOCAL_PREF";
-            throw new BgpParseException(errorMsg);
-        }
-    }
-
-    /**
-     * Verifies the BGP UPDATE Attribute Flags.
-     *
-     * @param ctx the Channel Handler Context
-     * @param attrTypeCode the attribute type code
-     * @param attrLen the attribute length (in octets)
-     * @param attrFlags the attribute flags
-     * @param message the message to parse
-     * @throws BgpParseException
-     */
-    private void verifyBgpUpdateAttributeFlags(
-                        ChannelHandlerContext ctx,
-                        int attrTypeCode,
-                        int attrLen,
-                        int attrFlags,
-                        ChannelBuffer message)
-        throws BgpParseException {
-
-        //
-        // Assign the Attribute Type Name and the Well-known flag
-        //
-        String typeName = "UNKNOWN";
-        boolean isWellKnown = false;
-        switch (attrTypeCode) {
-        case BgpConstants.Update.Origin.TYPE:
-            isWellKnown = true;
-            typeName = "ORIGIN";
-            break;
-        case BgpConstants.Update.AsPath.TYPE:
-            isWellKnown = true;
-            typeName = "AS_PATH";
-            break;
-        case BgpConstants.Update.NextHop.TYPE:
-            isWellKnown = true;
-            typeName = "NEXT_HOP";
-            break;
-        case BgpConstants.Update.MultiExitDisc.TYPE:
-            isWellKnown = false;
-            typeName = "MULTI_EXIT_DISC";
-            break;
-        case BgpConstants.Update.LocalPref.TYPE:
-            isWellKnown = true;
-            typeName = "LOCAL_PREF";
-            break;
-        case BgpConstants.Update.AtomicAggregate.TYPE:
-            isWellKnown = true;
-            typeName = "ATOMIC_AGGREGATE";
-            break;
-        case BgpConstants.Update.Aggregator.TYPE:
-            isWellKnown = false;
-            typeName = "AGGREGATOR";
-            break;
-        default:
-            isWellKnown = false;
-            typeName = "UNKNOWN(" + attrTypeCode + ")";
-            break;
-        }
-
-        //
-        // Verify the Attribute Flags
-        //
-        boolean optionalBit =       ((0x80 & attrFlags) != 0);
-        boolean transitiveBit =     ((0x40 & attrFlags) != 0);
-        boolean partialBit =        ((0x20 & attrFlags) != 0);
-        if ((isWellKnown && optionalBit) ||
-            (isWellKnown && (!transitiveBit)) ||
-            (isWellKnown && partialBit) ||
-            (optionalBit && (!transitiveBit) && partialBit)) {
-            //
-            // ERROR: The Optional bit cannot be set for Well-known attributes
-            // ERROR: The Transtive bit MUST be 1 for well-known attributes
-            // ERROR: The Partial bit MUST be 0 for well-known attributes
-            // ERROR: The Partial bit MUST be 0 for optional non-transitive
-            //        attributes
-            //
-            actionsBgpUpdateAttributeFlagsError(
-                ctx, attrTypeCode, attrLen, attrFlags, message);
-            String errorMsg = "Attribute Flags Error for " + typeName + ": " +
-                attrFlags;
-            throw new BgpParseException(errorMsg);
-        }
-    }
-
-    /**
-     * Parses BGP UPDATE Attribute Type ORIGIN.
-     *
-     * @param ctx the Channel Handler Context
-     * @param attrTypeCode the attribute type code
-     * @param attrLen the attribute length (in octets)
-     * @param attrFlags the attribute flags
-     * @param message the message to parse
-     * @return the parsed ORIGIN value
-     * @throws BgpParseException
-     */
-    private short parseAttributeTypeOrigin(
-                        ChannelHandlerContext ctx,
-                        int attrTypeCode,
-                        int attrLen,
-                        int attrFlags,
-                        ChannelBuffer message)
-        throws BgpParseException {
-
-        // Check the Attribute Length
-        if (attrLen != BgpConstants.Update.Origin.LENGTH) {
-            // ERROR: Attribute Length Error
-            actionsBgpUpdateAttributeLengthError(
-                        ctx, attrTypeCode, attrLen, attrFlags, message);
-            String errorMsg = "Attribute Length Error";
-            throw new BgpParseException(errorMsg);
-        }
-
-        message.markReaderIndex();
-        short origin = message.readUnsignedByte();
-        switch (origin) {
-        case BgpConstants.Update.Origin.IGP:
-            // FALLTHROUGH
-        case BgpConstants.Update.Origin.EGP:
-            // FALLTHROUGH
-        case BgpConstants.Update.Origin.INCOMPLETE:
-            break;
-        default:
-            // ERROR: Invalid ORIGIN Attribute
-            message.resetReaderIndex();
-            actionsBgpUpdateInvalidOriginAttribute(
-                ctx, attrTypeCode, attrLen, attrFlags, message, origin);
-            String errorMsg = "Invalid ORIGIN Attribute: " + origin;
-            throw new BgpParseException(errorMsg);
-        }
-
-        return origin;
-    }
-
-    /**
-     * Parses BGP UPDATE Attribute AS Path.
-     *
-     * @param ctx the Channel Handler Context
-     * @param attrTypeCode the attribute type code
-     * @param attrLen the attribute length (in octets)
-     * @param attrFlags the attribute flags
-     * @param message the message to parse
-     * @return the parsed AS Path
-     * @throws BgpParseException
-     */
-    private BgpRouteEntry.AsPath parseAttributeTypeAsPath(
-                        ChannelHandlerContext ctx,
-                        int attrTypeCode,
-                        int attrLen,
-                        int attrFlags,
-                        ChannelBuffer message)
-        throws BgpParseException {
-        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
-
-        //
-        // Parse the message
-        //
-        while (attrLen > 0) {
-            if (attrLen < 2) {
-                // ERROR: Malformed AS_PATH
-                actionsBgpUpdateMalformedAsPath(ctx);
-                String errorMsg = "Malformed AS Path";
-                throw new BgpParseException(errorMsg);
-            }
-            // Get the Path Segment Type and Length (in number of ASes)
-            short pathSegmentType = message.readUnsignedByte();
-            short pathSegmentLength = message.readUnsignedByte();
-            attrLen -= 2;
-
-            // Verify the Path Segment Type
-            switch (pathSegmentType) {
-            case BgpConstants.Update.AsPath.AS_SET:
-                // FALLTHROUGH
-            case BgpConstants.Update.AsPath.AS_SEQUENCE:
-                // FALLTHROUGH
-            case BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE:
-                // FALLTHROUGH
-            case BgpConstants.Update.AsPath.AS_CONFED_SET:
-                break;
-            default:
-                // ERROR: Invalid Path Segment Type
-                //
-                // NOTE: The BGP Spec (RFC 4271) doesn't contain Error Subcode
-                // for "Invalid Path Segment Type", hence we return
-                // the error as "Malformed AS_PATH".
-                //
-                actionsBgpUpdateMalformedAsPath(ctx);
-                String errorMsg =
-                    "Invalid AS Path Segment Type: " + pathSegmentType;
-                throw new BgpParseException(errorMsg);
-            }
-
-            // Parse the AS numbers
-            if (2 * pathSegmentLength > attrLen) {
-                // ERROR: Malformed AS_PATH
-                actionsBgpUpdateMalformedAsPath(ctx);
-                String errorMsg = "Malformed AS Path";
-                throw new BgpParseException(errorMsg);
-            }
-            attrLen -= (2 * pathSegmentLength);
-            ArrayList<Long> segmentAsNumbers = new ArrayList<>();
-            while (pathSegmentLength-- > 0) {
-                long asNumber = message.readUnsignedShort();
-                segmentAsNumbers.add(asNumber);
-            }
-
-            BgpRouteEntry.PathSegment pathSegment =
-                new BgpRouteEntry.PathSegment((byte) pathSegmentType,
-                                              segmentAsNumbers);
-            pathSegments.add(pathSegment);
-        }
-
-        return new BgpRouteEntry.AsPath(pathSegments);
-    }
-
-    /**
-     * Parses BGP UPDATE Attribute Type NEXT_HOP.
-     *
-     * @param ctx the Channel Handler Context
-     * @param attrTypeCode the attribute type code
-     * @param attrLen the attribute length (in octets)
-     * @param attrFlags the attribute flags
-     * @param message the message to parse
-     * @return the parsed NEXT_HOP value
-     * @throws BgpParseException
-     */
-    private Ip4Address parseAttributeTypeNextHop(
-                        ChannelHandlerContext ctx,
-                        int attrTypeCode,
-                        int attrLen,
-                        int attrFlags,
-                        ChannelBuffer message)
-        throws BgpParseException {
-
-        // Check the Attribute Length
-        if (attrLen != BgpConstants.Update.NextHop.LENGTH) {
-            // ERROR: Attribute Length Error
-            actionsBgpUpdateAttributeLengthError(
-                        ctx, attrTypeCode, attrLen, attrFlags, message);
-            String errorMsg = "Attribute Length Error";
-            throw new BgpParseException(errorMsg);
-        }
-
-        message.markReaderIndex();
-        Ip4Address nextHopAddress =
-            Ip4Address.valueOf((int) message.readUnsignedInt());
-        //
-        // Check whether the NEXT_HOP IP address is semantically correct.
-        // As per RFC 4271, Section 6.3:
-        //
-        //  a) It MUST NOT be the IP address of the receiving speaker
-        //  b) In the case of an EBGP ....
-        //
-        // Here we check only (a), because (b) doesn't apply for us: all our
-        // peers are iBGP.
-        //
-        if (nextHopAddress.equals(localIp4Address)) {
-            // ERROR: Invalid NEXT_HOP Attribute
-            message.resetReaderIndex();
-            actionsBgpUpdateInvalidNextHopAttribute(
-                        ctx, attrTypeCode, attrLen, attrFlags, message,
-                        nextHopAddress);
-            String errorMsg = "Invalid NEXT_HOP Attribute: " + nextHopAddress;
-            throw new BgpParseException(errorMsg);
-        }
-
-        return nextHopAddress;
-    }
-
-    /**
-     * Parses BGP UPDATE Attribute Type MULTI_EXIT_DISC.
-     *
-     * @param ctx the Channel Handler Context
-     * @param attrTypeCode the attribute type code
-     * @param attrLen the attribute length (in octets)
-     * @param attrFlags the attribute flags
-     * @param message the message to parse
-     * @return the parsed MULTI_EXIT_DISC value
-     * @throws BgpParseException
-     */
-    private long parseAttributeTypeMultiExitDisc(
-                        ChannelHandlerContext ctx,
-                        int attrTypeCode,
-                        int attrLen,
-                        int attrFlags,
-                        ChannelBuffer message)
-        throws BgpParseException {
-
-        // Check the Attribute Length
-        if (attrLen != BgpConstants.Update.MultiExitDisc.LENGTH) {
-            // ERROR: Attribute Length Error
-            actionsBgpUpdateAttributeLengthError(
-                        ctx, attrTypeCode, attrLen, attrFlags, message);
-            String errorMsg = "Attribute Length Error";
-            throw new BgpParseException(errorMsg);
-        }
-
-        long multiExitDisc = message.readUnsignedInt();
-        return multiExitDisc;
-    }
-
-    /**
-     * Parses BGP UPDATE Attribute Type LOCAL_PREF.
-     *
-     * @param ctx the Channel Handler Context
-     * @param attrTypeCode the attribute type code
-     * @param attrLen the attribute length (in octets)
-     * @param attrFlags the attribute flags
-     * @param message the message to parse
-     * @return the parsed LOCAL_PREF value
-     * @throws BgpParseException
-     */
-    private long parseAttributeTypeLocalPref(
-                        ChannelHandlerContext ctx,
-                        int attrTypeCode,
-                        int attrLen,
-                        int attrFlags,
-                        ChannelBuffer message)
-        throws BgpParseException {
-
-        // Check the Attribute Length
-        if (attrLen != BgpConstants.Update.LocalPref.LENGTH) {
-            // ERROR: Attribute Length Error
-            actionsBgpUpdateAttributeLengthError(
-                        ctx, attrTypeCode, attrLen, attrFlags, message);
-            String errorMsg = "Attribute Length Error";
-            throw new BgpParseException(errorMsg);
-        }
-
-        long localPref = message.readUnsignedInt();
-        return localPref;
-    }
-
-    /**
-     * Parses BGP UPDATE Attribute Type ATOMIC_AGGREGATE.
-     *
-     * @param ctx the Channel Handler Context
-     * @param attrTypeCode the attribute type code
-     * @param attrLen the attribute length (in octets)
-     * @param attrFlags the attribute flags
-     * @param message the message to parse
-     * @throws BgpParseException
-     */
-    private void parseAttributeTypeAtomicAggregate(
-                        ChannelHandlerContext ctx,
-                        int attrTypeCode,
-                        int attrLen,
-                        int attrFlags,
-                        ChannelBuffer message)
-        throws BgpParseException {
-
-        // Check the Attribute Length
-        if (attrLen != BgpConstants.Update.AtomicAggregate.LENGTH) {
-            // ERROR: Attribute Length Error
-            actionsBgpUpdateAttributeLengthError(
-                        ctx, attrTypeCode, attrLen, attrFlags, message);
-            String errorMsg = "Attribute Length Error";
-            throw new BgpParseException(errorMsg);
-        }
-
-        // Nothing to do: this attribute is primarily informational
-    }
-
-    /**
-     * Parses BGP UPDATE Attribute Type AGGREGATOR.
-     *
-     * @param ctx the Channel Handler Context
-     * @param attrTypeCode the attribute type code
-     * @param attrLen the attribute length (in octets)
-     * @param attrFlags the attribute flags
-     * @param message the message to parse
-     * @return the parsed AGGREGATOR value: a tuple of <AS-Number, IP-Address>
-     * @throws BgpParseException
-     */
-    private Pair<Long, Ip4Address> parseAttributeTypeAggregator(
-                        ChannelHandlerContext ctx,
-                        int attrTypeCode,
-                        int attrLen,
-                        int attrFlags,
-                        ChannelBuffer message)
-        throws BgpParseException {
-
-        // Check the Attribute Length
-        if (attrLen != BgpConstants.Update.Aggregator.LENGTH) {
-            // ERROR: Attribute Length Error
-            actionsBgpUpdateAttributeLengthError(
-                        ctx, attrTypeCode, attrLen, attrFlags, message);
-            String errorMsg = "Attribute Length Error";
-            throw new BgpParseException(errorMsg);
-        }
-
-        // The AGGREGATOR AS number
-        long aggregatorAsNumber = message.readUnsignedShort();
-        // The AGGREGATOR IP address
-        Ip4Address aggregatorIpAddress =
-            Ip4Address.valueOf((int) message.readUnsignedInt());
-
-        Pair<Long, Ip4Address> aggregator = Pair.of(aggregatorAsNumber,
-                                                    aggregatorIpAddress);
-        return aggregator;
-    }
-
-    /**
-     * Parses a message that contains encoded IPv4 network prefixes.
-     * <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 totalLength the total length of the data to parse
-     * @param message the message with data to parse
-     * @return a collection of parsed IPv4 network prefixes
-     * @throws BgpParseException
-     */
-    private Collection<Ip4Prefix> parsePackedPrefixes(int totalLength,
-                                                      ChannelBuffer message)
-        throws BgpParseException {
-        Collection<Ip4Prefix> result = new ArrayList<>();
-
-        if (totalLength == 0) {
-            return result;
-        }
-
-        // Parse the data
-        int dataEnd = message.readerIndex() + totalLength;
-        while (message.readerIndex() < dataEnd) {
-            int prefixBitlen = message.readUnsignedByte();
-            int prefixBytelen = (prefixBitlen + 7) / 8;     // Round-up
-            if (message.readerIndex() + prefixBytelen > dataEnd) {
-                String errorMsg = "Malformed Network Prefixes";
-                throw new BgpParseException(errorMsg);
-            }
-
-            long address = 0;
-            long extraShift = (4 - prefixBytelen) * 8;
-            while (prefixBytelen > 0) {
-                address <<= 8;
-                address |= message.readUnsignedByte();
-                prefixBytelen--;
-            }
-            address <<= extraShift;
-            Ip4Prefix prefix =
-                Ip4Prefix.valueOf(Ip4Address.valueOf((int) address),
-                                  prefixBitlen);
-            result.add(prefix);
-        }
-
-        return result;
-    }
-
-    /**
-     * Applies the appropriate actions after detecting BGP UPDATE
-     * Invalid Network Field Error: send NOTIFICATION and close the channel.
-     *
-     * @param ctx the Channel Handler Context
-     */
-    private void actionsBgpUpdateInvalidNetworkField(
-                        ChannelHandlerContext ctx) {
-        log.debug("BGP RX UPDATE Error from {}: Invalid Network Field",
-                  remoteAddress);
-
-        //
-        // ERROR: Invalid Network Field
-        //
-        // Send NOTIFICATION and close the connection
-        int errorCode = UpdateMessageError.ERROR_CODE;
-        int errorSubcode = UpdateMessageError.INVALID_NETWORK_FIELD;
-        ChannelBuffer txMessage =
-            prepareBgpNotification(errorCode, errorSubcode, null);
-        ctx.getChannel().write(txMessage);
-        closeSession(ctx);
-    }
-
-    /**
-     * Applies the appropriate actions after detecting BGP UPDATE
-     * Malformed Attribute List Error: send NOTIFICATION and close the channel.
-     *
-     * @param ctx the Channel Handler Context
-     */
-    private void actionsBgpUpdateMalformedAttributeList(
-                        ChannelHandlerContext ctx) {
-        log.debug("BGP RX UPDATE Error from {}: Malformed Attribute List",
-                  remoteAddress);
-
-        //
-        // ERROR: Malformed Attribute List
-        //
-        // Send NOTIFICATION and close the connection
-        int errorCode = UpdateMessageError.ERROR_CODE;
-        int errorSubcode = UpdateMessageError.MALFORMED_ATTRIBUTE_LIST;
-        ChannelBuffer txMessage =
-            prepareBgpNotification(errorCode, errorSubcode, null);
-        ctx.getChannel().write(txMessage);
-        closeSession(ctx);
-    }
-
-    /**
-     * Applies the appropriate actions after detecting BGP UPDATE
-     * Missing Well-known Attribute Error: send NOTIFICATION and close the
-     * channel.
-     *
-     * @param ctx the Channel Handler Context
-     * @param missingAttrTypeCode the missing attribute type code
-     */
-    private void actionsBgpUpdateMissingWellKnownAttribute(
-                        ChannelHandlerContext ctx,
-                        int missingAttrTypeCode) {
-        log.debug("BGP RX UPDATE Error from {}: Missing Well-known Attribute: {}",
-                  remoteAddress, missingAttrTypeCode);
-
-        //
-        // ERROR: Missing Well-known Attribute
-        //
-        // Send NOTIFICATION and close the connection
-        int errorCode = UpdateMessageError.ERROR_CODE;
-        int errorSubcode = UpdateMessageError.MISSING_WELL_KNOWN_ATTRIBUTE;
-        ChannelBuffer data = ChannelBuffers.buffer(1);
-        data.writeByte(missingAttrTypeCode);
-        ChannelBuffer txMessage =
-            prepareBgpNotification(errorCode, errorSubcode, data);
-        ctx.getChannel().write(txMessage);
-        closeSession(ctx);
-    }
-
-    /**
-     * Applies the appropriate actions after detecting BGP UPDATE
-     * Invalid ORIGIN Attribute Error: send NOTIFICATION and close the channel.
-     *
-     * @param ctx the Channel Handler Context
-     * @param attrTypeCode the attribute type code
-     * @param attrLen the attribute length (in octets)
-     * @param attrFlags the attribute flags
-     * @param message the message with the data
-     * @param origin the ORIGIN attribute value
-     */
-    private void actionsBgpUpdateInvalidOriginAttribute(
-                        ChannelHandlerContext ctx,
-                        int attrTypeCode,
-                        int attrLen,
-                        int attrFlags,
-                        ChannelBuffer message,
-                        short origin) {
-        log.debug("BGP RX UPDATE Error from {}: Invalid ORIGIN Attribute",
-                  remoteAddress);
-
-        //
-        // ERROR: Invalid ORIGIN Attribute
-        //
-        // Send NOTIFICATION and close the connection
-        int errorCode = UpdateMessageError.ERROR_CODE;
-        int errorSubcode = UpdateMessageError.INVALID_ORIGIN_ATTRIBUTE;
-        ChannelBuffer data =
-            prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
-                                                    attrFlags, message);
-        ChannelBuffer txMessage =
-            prepareBgpNotification(errorCode, errorSubcode, data);
-        ctx.getChannel().write(txMessage);
-        closeSession(ctx);
-    }
-
-    /**
-     * Applies the appropriate actions after detecting BGP UPDATE
-     * Attribute Flags Error: send NOTIFICATION and close the channel.
-     *
-     * @param ctx the Channel Handler Context
-     * @param attrTypeCode the attribute type code
-     * @param attrLen the attribute length (in octets)
-     * @param attrFlags the attribute flags
-     * @param message the message with the data
-     */
-    private void actionsBgpUpdateAttributeFlagsError(
-                        ChannelHandlerContext ctx,
-                        int attrTypeCode,
-                        int attrLen,
-                        int attrFlags,
-                        ChannelBuffer message) {
-        log.debug("BGP RX UPDATE Error from {}: Attribute Flags Error",
-                  remoteAddress);
-
-        //
-        // ERROR: Attribute Flags Error
-        //
-        // Send NOTIFICATION and close the connection
-        int errorCode = UpdateMessageError.ERROR_CODE;
-        int errorSubcode = UpdateMessageError.ATTRIBUTE_FLAGS_ERROR;
-        ChannelBuffer data =
-            prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
-                                                    attrFlags, message);
-        ChannelBuffer txMessage =
-            prepareBgpNotification(errorCode, errorSubcode, data);
-        ctx.getChannel().write(txMessage);
-        closeSession(ctx);
-    }
-
-    /**
-     * Applies the appropriate actions after detecting BGP UPDATE
-     * Invalid NEXT_HOP Attribute Error: send NOTIFICATION and close the
-     * channel.
-     *
-     * @param ctx the Channel Handler Context
-     * @param attrTypeCode the attribute type code
-     * @param attrLen the attribute length (in octets)
-     * @param attrFlags the attribute flags
-     * @param message the message with the data
-     * @param nextHop the NEXT_HOP attribute value
-     */
-    private void actionsBgpUpdateInvalidNextHopAttribute(
-                        ChannelHandlerContext ctx,
-                        int attrTypeCode,
-                        int attrLen,
-                        int attrFlags,
-                        ChannelBuffer message,
-                        Ip4Address nextHop) {
-        log.debug("BGP RX UPDATE Error from {}: Invalid NEXT_HOP Attribute {}",
-                  remoteAddress, nextHop);
-
-        //
-        // ERROR: Invalid ORIGIN Attribute
-        //
-        // Send NOTIFICATION and close the connection
-        int errorCode = UpdateMessageError.ERROR_CODE;
-        int errorSubcode = UpdateMessageError.INVALID_NEXT_HOP_ATTRIBUTE;
-        ChannelBuffer data =
-            prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
-                                                    attrFlags, message);
-        ChannelBuffer txMessage =
-            prepareBgpNotification(errorCode, errorSubcode, data);
-        ctx.getChannel().write(txMessage);
-        closeSession(ctx);
-    }
-
-    /**
-     * Applies the appropriate actions after detecting BGP UPDATE
-     * Unrecognized Well-known Attribute Error: send NOTIFICATION and close
-     * the channel.
-     *
-     * @param ctx the Channel Handler Context
-     * @param attrTypeCode the attribute type code
-     * @param attrLen the attribute length (in octets)
-     * @param attrFlags the attribute flags
-     * @param message the message with the data
-     */
-    private void actionsBgpUpdateUnrecognizedWellKnownAttribute(
-                        ChannelHandlerContext ctx,
-                        int attrTypeCode,
-                        int attrLen,
-                        int attrFlags,
-                        ChannelBuffer message) {
-        log.debug("BGP RX UPDATE Error from {}: " +
-                  "Unrecognized Well-known Attribute Error: {}",
-                  remoteAddress, attrTypeCode);
-
-        //
-        // ERROR: Unrecognized Well-known Attribute
-        //
-        // Send NOTIFICATION and close the connection
-        int errorCode = UpdateMessageError.ERROR_CODE;
-        int errorSubcode =
-            UpdateMessageError.UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE;
-        ChannelBuffer data =
-            prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
-                                                    attrFlags, message);
-        ChannelBuffer txMessage =
-            prepareBgpNotification(errorCode, errorSubcode, data);
-        ctx.getChannel().write(txMessage);
-        closeSession(ctx);
-    }
-
-    /**
-     * Applies the appropriate actions after detecting BGP UPDATE
-     * Attribute Length Error: send NOTIFICATION and close the channel.
-     *
-     * @param ctx the Channel Handler Context
-     * @param attrTypeCode the attribute type code
-     * @param attrLen the attribute length (in octets)
-     * @param attrFlags the attribute flags
-     * @param message the message with the data
-     */
-    private void actionsBgpUpdateAttributeLengthError(
-                        ChannelHandlerContext ctx,
-                        int attrTypeCode,
-                        int attrLen,
-                        int attrFlags,
-                        ChannelBuffer message) {
-        log.debug("BGP RX UPDATE Error from {}: Attribute Length Error",
-                  remoteAddress);
-
-        //
-        // ERROR: Attribute Length Error
-        //
-        // Send NOTIFICATION and close the connection
-        int errorCode = UpdateMessageError.ERROR_CODE;
-        int errorSubcode = UpdateMessageError.ATTRIBUTE_LENGTH_ERROR;
-        ChannelBuffer data =
-            prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
-                                                    attrFlags, message);
-        ChannelBuffer txMessage =
-            prepareBgpNotification(errorCode, errorSubcode, data);
-        ctx.getChannel().write(txMessage);
-        closeSession(ctx);
-    }
-
-    /**
-     * Applies the appropriate actions after detecting BGP UPDATE
-     * Malformed AS_PATH Error: send NOTIFICATION and close the channel.
-     *
-     * @param ctx the Channel Handler Context
-     */
-    private void actionsBgpUpdateMalformedAsPath(
-                        ChannelHandlerContext ctx) {
-        log.debug("BGP RX UPDATE Error from {}: Malformed AS Path",
-                  remoteAddress);
-
-        //
-        // ERROR: Malformed AS_PATH
-        //
-        // Send NOTIFICATION and close the connection
-        int errorCode = UpdateMessageError.ERROR_CODE;
-        int errorSubcode = UpdateMessageError.MALFORMED_AS_PATH;
-        ChannelBuffer txMessage =
-            prepareBgpNotification(errorCode, errorSubcode, null);
-        ctx.getChannel().write(txMessage);
-        closeSession(ctx);
-    }
-
-    /**
-     * Processes BGP NOTIFICATION message.
-     *
-     * @param ctx the Channel Handler Context
-     * @param message the message to process
-     */
-    void processBgpNotification(ChannelHandlerContext ctx,
-                                ChannelBuffer message) {
-        int minLength =
-            BgpConstants.BGP_NOTIFICATION_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH;
-        if (message.readableBytes() < minLength) {
-            log.debug("BGP RX NOTIFICATION Error from {}: " +
-                      "Message length {} too short. Must be at least {}",
-                      remoteAddress, message.readableBytes(), minLength);
-            //
-            // ERROR: Bad Message Length
-            //
-            // NOTE: We do NOT send NOTIFICATION in response to a notification
-            return;
-        }
-
-        //
-        // Parse the NOTIFICATION message
-        //
-        int errorCode = message.readUnsignedByte();
-        int errorSubcode = message.readUnsignedByte();
-        int dataLength = message.readableBytes();
-
-        log.debug("BGP RX NOTIFICATION message from {}: Error Code {} " +
-                  "Error Subcode {} Data Length {}",
-                  remoteAddress, errorCode, errorSubcode, dataLength);
-
-        //
-        // NOTE: If the peer sent a NOTIFICATION, we leave it to the peer to
-        // close the connection.
-        //
-
-        // Start the Session Timeout timer
-        restartSessionTimeoutTimer(ctx);
-    }
-
-    /**
-     * Processes BGP KEEPALIVE message.
-     *
-     * @param ctx the Channel Handler Context
-     * @param message the message to process
-     */
-    void processBgpKeepalive(ChannelHandlerContext ctx,
-                             ChannelBuffer message) {
-        if (message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH !=
-            BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH) {
-            log.debug("BGP RX KEEPALIVE Error from {}: " +
-                      "Invalid total message length {}. Expected {}",
-                      remoteAddress,
-                      message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH,
-                      BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH);
-            //
-            // ERROR: Bad Message Length
-            //
-            // Send NOTIFICATION and close the connection
-            ChannelBuffer txMessage = prepareBgpNotificationBadMessageLength(
-                message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH);
-            ctx.getChannel().write(txMessage);
-            closeSession(ctx);
-            return;
-        }
-
-        //
-        // Parse the KEEPALIVE message: nothing to do
-        //
-        log.trace("BGP RX KEEPALIVE message from {}", remoteAddress);
-
-        // Start the Session Timeout timer
-        restartSessionTimeoutTimer(ctx);
-    }
-
-    /**
-     * Prepares BGP OPEN message.
-     *
-     * @return the message to transmit (BGP header included)
-     */
-    private ChannelBuffer prepareBgpOpen() {
-        ChannelBuffer message =
-            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
-
-        //
-        // Prepare the OPEN message payload
-        //
-        message.writeByte(localBgpVersion);
-        message.writeShort((int) localAs);
-        message.writeShort((int) localHoldtime);
-        message.writeInt(bgpSessionManager.getMyBgpId().toInt());
-        message.writeByte(0);               // No Optional Parameters
-        return prepareBgpMessage(BgpConstants.BGP_TYPE_OPEN, message);
-    }
-
-    /**
-     * Prepares BGP KEEPALIVE message.
-     *
-     * @return the message to transmit (BGP header included)
-     */
-    private ChannelBuffer prepareBgpKeepalive() {
-        ChannelBuffer message =
-            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
-
-        //
-        // Prepare the KEEPALIVE message payload: nothing to do
-        //
-        return prepareBgpMessage(BgpConstants.BGP_TYPE_KEEPALIVE, message);
-    }
-
-    /**
-     * Prepares BGP NOTIFICATION message.
-     *
-     * @param errorCode the BGP NOTIFICATION Error Code
-     * @param errorSubcode the BGP NOTIFICATION Error Subcode if applicable,
-     * otherwise BgpConstants.Notifications.ERROR_SUBCODE_UNSPECIFIC
-     * @param data the BGP NOTIFICATION Data if applicable, otherwise null
-     * @return the message to transmit (BGP header included)
-     */
-    ChannelBuffer prepareBgpNotification(int errorCode, int errorSubcode,
-                                         ChannelBuffer data) {
-        ChannelBuffer message =
-            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
-
-        //
-        // Prepare the NOTIFICATION message payload
-        //
-        message.writeByte(errorCode);
-        message.writeByte(errorSubcode);
-        if (data != null) {
-            message.writeBytes(data);
-        }
-        return prepareBgpMessage(BgpConstants.BGP_TYPE_NOTIFICATION, message);
-    }
-
-    /**
-     * Prepares BGP NOTIFICATION message: Bad Message Length.
-     *
-     * @param length the erroneous Length field
-     * @return the message to transmit (BGP header included)
-     */
-    ChannelBuffer prepareBgpNotificationBadMessageLength(int length) {
-        int errorCode = MessageHeaderError.ERROR_CODE;
-        int errorSubcode = MessageHeaderError.BAD_MESSAGE_LENGTH;
-        ChannelBuffer data = ChannelBuffers.buffer(2);
-        data.writeShort(length);
-
-        return prepareBgpNotification(errorCode, errorSubcode, data);
-    }
-
-    /**
-     * Prepares BGP UPDATE Notification data payload.
-     *
-     * @param attrTypeCode the attribute type code
-     * @param attrLen the attribute length (in octets)
-     * @param attrFlags the attribute flags
-     * @param message the message with the data
-     * @return the buffer with the data payload for the BGP UPDATE Notification
-     */
-    private ChannelBuffer prepareBgpUpdateNotificationDataPayload(
-                        int attrTypeCode,
-                        int attrLen,
-                        int attrFlags,
-                        ChannelBuffer message) {
-        // Compute the attribute length field octets
-        boolean extendedLengthBit = ((0x10 & attrFlags) != 0);
-        int attrLenOctets = 1;
-        if (extendedLengthBit) {
-            attrLenOctets = 2;
-        }
-        ChannelBuffer data =
-            ChannelBuffers.buffer(attrLen + attrLenOctets + 1);
-        data.writeByte(attrTypeCode);
-        if (extendedLengthBit) {
-            data.writeShort(attrLen);
-        } else {
-            data.writeByte(attrLen);
-        }
-        data.writeBytes(message, attrLen);
-        return data;
-    }
-
-    /**
-     * Prepares BGP message.
-     *
-     * @param type the BGP message type
-     * @param payload the message payload to transmit (BGP header excluded)
-     * @return the message to transmit (BGP header included)
-     */
-    private ChannelBuffer prepareBgpMessage(int type, ChannelBuffer payload) {
-        ChannelBuffer message =
-            ChannelBuffers.buffer(BgpConstants.BGP_HEADER_LENGTH +
-                                  payload.readableBytes());
-
-        // Write the marker
-        for (int i = 0; i < BgpConstants.BGP_HEADER_MARKER_LENGTH; i++) {
-            message.writeByte(0xff);
-        }
-
-        // Write the rest of the BGP header
-        message.writeShort(BgpConstants.BGP_HEADER_LENGTH +
-                           payload.readableBytes());
-        message.writeByte(type);
-
-        // Write the payload
-        message.writeBytes(payload);
-        return message;
-    }
-
-    /**
      * Restarts the BGP KeepaliveTimer.
      */
-    private void restartKeepaliveTimer(ChannelHandlerContext ctx) {
+    void restartKeepaliveTimer(ChannelHandlerContext ctx) {
         if (localKeepaliveInterval == 0) {
             return;                 // Nothing to do
         }
@@ -1811,7 +443,7 @@
             }
 
             // Transmit the KEEPALIVE
-            ChannelBuffer txMessage = prepareBgpKeepalive();
+            ChannelBuffer txMessage = BgpKeepalive.prepareBgpKeepalive();
             ctx.getChannel().write(txMessage);
 
             // Restart the KEEPALIVE timer
@@ -1822,7 +454,7 @@
     /**
      * Restarts the BGP Session Timeout Timer.
      */
-    private void restartSessionTimeoutTimer(ChannelHandlerContext ctx) {
+    void restartSessionTimeoutTimer(ChannelHandlerContext ctx) {
         if (remoteHoldtime == 0) {
             return;                 // Nothing to do
         }
@@ -1866,30 +498,10 @@
             int errorCode = HoldTimerExpired.ERROR_CODE;
             int errorSubcode = Notifications.ERROR_SUBCODE_UNSPECIFIC;
             ChannelBuffer txMessage =
-                prepareBgpNotification(errorCode, errorSubcode, null);
+                BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                       null);
             ctx.getChannel().write(txMessage);
             closeChannel(ctx);
         }
     }
-
-    /**
-     * An exception indicating a parsing error of the BGP message.
-     */
-    private static class BgpParseException extends Exception {
-        /**
-         * Default constructor.
-         */
-        public BgpParseException() {
-            super();
-        }
-
-        /**
-         * Constructor for a specific exception details message.
-         *
-         * @param message the message with the exception details
-         */
-         public BgpParseException(String message) {
-             super(message);
-         }
-    }
 }
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpUpdate.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpUpdate.java
new file mode 100644
index 0000000..733965e
--- /dev/null
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpUpdate.java
@@ -0,0 +1,1236 @@
+/*
+ * Copyright 2014 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.sdnip.bgp;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onosproject.sdnip.bgp.BgpConstants.Notifications.UpdateMessageError;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A class for handling BGP UPDATE messages.
+ */
+final class BgpUpdate {
+    private static final Logger log = LoggerFactory.getLogger(BgpUpdate.class);
+
+    /**
+     * Default constructor.
+     * <p>
+     * The constructor is private to prevent creating an instance of
+     * this utility class.
+     */
+    private BgpUpdate() {
+    }
+
+    /**
+     * Processes BGP UPDATE message.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param message the message to process
+     */
+    static void processBgpUpdate(BgpSession bgpSession,
+                                 ChannelHandlerContext ctx,
+                                 ChannelBuffer message) {
+        Collection<BgpRouteEntry> addedRoutes = null;
+        Map<Ip4Prefix, BgpRouteEntry> deletedRoutes = new HashMap<>();
+
+        int minLength =
+            BgpConstants.BGP_UPDATE_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH;
+        if (message.readableBytes() < minLength) {
+            log.debug("BGP RX UPDATE Error from {}: " +
+                      "Message length {} too short. Must be at least {}",
+                      bgpSession.getRemoteAddress(), message.readableBytes(),
+                      minLength);
+            //
+            // ERROR: Bad Message Length
+            //
+            // Send NOTIFICATION and close the connection
+            ChannelBuffer txMessage =
+                BgpNotification.prepareBgpNotificationBadMessageLength(
+                message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH);
+            ctx.getChannel().write(txMessage);
+            bgpSession.closeSession(ctx);
+            return;
+        }
+
+        log.debug("BGP RX UPDATE message from {}",
+                  bgpSession.getRemoteAddress());
+
+        //
+        // Parse the UPDATE message
+        //
+
+        //
+        // Parse the Withdrawn Routes
+        //
+        int withdrawnRoutesLength = message.readUnsignedShort();
+        if (withdrawnRoutesLength > message.readableBytes()) {
+            // ERROR: Malformed Attribute List
+            actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
+            return;
+        }
+        Collection<Ip4Prefix> withdrawnPrefixes = null;
+        try {
+            withdrawnPrefixes = parsePackedPrefixes(withdrawnRoutesLength,
+                                                    message);
+        } catch (BgpParseException e) {
+            // ERROR: Invalid Network Field
+            log.debug("Exception parsing Withdrawn Prefixes from BGP peer {}: ",
+                      bgpSession.getRemoteBgpId(), e);
+            actionsBgpUpdateInvalidNetworkField(bgpSession, ctx);
+            return;
+        }
+        for (Ip4Prefix prefix : withdrawnPrefixes) {
+            log.debug("BGP RX UPDATE message WITHDRAWN from {}: {}",
+                      bgpSession.getRemoteAddress(), prefix);
+            BgpRouteEntry bgpRouteEntry = bgpSession.bgpRibIn().get(prefix);
+            if (bgpRouteEntry != null) {
+                deletedRoutes.put(prefix, bgpRouteEntry);
+            }
+        }
+
+        //
+        // Parse the Path Attributes
+        //
+        try {
+            addedRoutes = parsePathAttributes(bgpSession, ctx, message);
+        } catch (BgpParseException e) {
+            log.debug("Exception parsing Path Attributes from BGP peer {}: ",
+                      bgpSession.getRemoteBgpId(), e);
+            // NOTE: The session was already closed, so nothing else to do
+            return;
+        }
+        // Ignore WITHDRAWN routes that are ADDED
+        for (BgpRouteEntry bgpRouteEntry : addedRoutes) {
+            deletedRoutes.remove(bgpRouteEntry.prefix());
+        }
+
+        // Update the BGP RIB-IN
+        for (BgpRouteEntry bgpRouteEntry : deletedRoutes.values()) {
+            bgpSession.bgpRibIn().remove(bgpRouteEntry.prefix());
+        }
+        for (BgpRouteEntry bgpRouteEntry : addedRoutes) {
+            bgpSession.bgpRibIn().put(bgpRouteEntry.prefix(), bgpRouteEntry);
+        }
+
+        // Push the updates to the BGP Merged RIB
+        BgpSessionManager.BgpRouteSelector bgpRouteSelector =
+            bgpSession.getBgpSessionManager().getBgpRouteSelector();
+        bgpRouteSelector.routeUpdates(bgpSession, addedRoutes,
+                                      deletedRoutes.values());
+
+        // Start the Session Timeout timer
+        bgpSession.restartSessionTimeoutTimer(ctx);
+    }
+
+    /**
+     * Parse BGP Path Attributes from the BGP UPDATE message.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param message the message to parse
+     * @return a collection of the result BGP Route Entries
+     * @throws BgpParseException
+     */
+    private static Collection<BgpRouteEntry> parsePathAttributes(
+                                                BgpSession bgpSession,
+                                                ChannelHandlerContext ctx,
+                                                ChannelBuffer message)
+        throws BgpParseException {
+        Map<Ip4Prefix, BgpRouteEntry> addedRoutes = new HashMap<>();
+
+        //
+        // Parsed values
+        //
+        Short origin = -1;                      // Mandatory
+        BgpRouteEntry.AsPath asPath = null;     // Mandatory
+        Ip4Address nextHop = null;              // Mandatory
+        long multiExitDisc =                    // Optional
+            BgpConstants.Update.MultiExitDisc.LOWEST_MULTI_EXIT_DISC;
+        Long localPref = null;                  // Mandatory
+        Long aggregatorAsNumber = null;         // Optional: unused
+        Ip4Address aggregatorIpAddress = null;  // Optional: unused
+
+        //
+        // Get and verify the Path Attributes Length
+        //
+        int pathAttributeLength = message.readUnsignedShort();
+        if (pathAttributeLength > message.readableBytes()) {
+            // ERROR: Malformed Attribute List
+            actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
+            String errorMsg = "Malformed Attribute List";
+            throw new BgpParseException(errorMsg);
+        }
+        if (pathAttributeLength == 0) {
+            return addedRoutes.values();
+        }
+
+        //
+        // Parse the Path Attributes
+        //
+        int pathAttributeEnd = message.readerIndex() + pathAttributeLength;
+        while (message.readerIndex() < pathAttributeEnd) {
+            int attrFlags = message.readUnsignedByte();
+            if (message.readerIndex() >= pathAttributeEnd) {
+                // ERROR: Malformed Attribute List
+                actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
+                String errorMsg = "Malformed Attribute List";
+                throw new BgpParseException(errorMsg);
+            }
+            int attrTypeCode = message.readUnsignedByte();
+
+            // The Attribute Flags
+            boolean optionalBit =       ((0x80 & attrFlags) != 0);
+            boolean transitiveBit =     ((0x40 & attrFlags) != 0);
+            boolean partialBit =        ((0x20 & attrFlags) != 0);
+            boolean extendedLengthBit = ((0x10 & attrFlags) != 0);
+
+            // The Attribute Length
+            int attrLen = 0;
+            int attrLenOctets = 1;
+            if (extendedLengthBit) {
+                attrLenOctets = 2;
+            }
+            if (message.readerIndex() + attrLenOctets > pathAttributeEnd) {
+                // ERROR: Malformed Attribute List
+                actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
+                String errorMsg = "Malformed Attribute List";
+                throw new BgpParseException(errorMsg);
+            }
+            if (extendedLengthBit) {
+                attrLen = message.readUnsignedShort();
+            } else {
+                attrLen = message.readUnsignedByte();
+            }
+            if (message.readerIndex() + attrLen > pathAttributeEnd) {
+                // ERROR: Malformed Attribute List
+                actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
+                String errorMsg = "Malformed Attribute List";
+                throw new BgpParseException(errorMsg);
+            }
+
+            // Verify the Attribute Flags
+            verifyBgpUpdateAttributeFlags(bgpSession, ctx, attrTypeCode,
+                                          attrLen, attrFlags, message);
+
+            //
+            // Extract the Attribute Value based on the Attribute Type Code
+            //
+            switch (attrTypeCode) {
+
+            case BgpConstants.Update.Origin.TYPE:
+                // Attribute Type Code ORIGIN
+                origin = parseAttributeTypeOrigin(bgpSession, ctx,
+                                                  attrTypeCode, attrLen,
+                                                  attrFlags, message);
+                break;
+
+            case BgpConstants.Update.AsPath.TYPE:
+                // Attribute Type Code AS_PATH
+                asPath = parseAttributeTypeAsPath(bgpSession, ctx,
+                                                  attrTypeCode, attrLen,
+                                                  attrFlags, message);
+                break;
+
+            case BgpConstants.Update.NextHop.TYPE:
+                // Attribute Type Code NEXT_HOP
+                nextHop = parseAttributeTypeNextHop(bgpSession, ctx,
+                                                    attrTypeCode, attrLen,
+                                                    attrFlags, message);
+                break;
+
+            case BgpConstants.Update.MultiExitDisc.TYPE:
+                // Attribute Type Code MULTI_EXIT_DISC
+                multiExitDisc =
+                    parseAttributeTypeMultiExitDisc(bgpSession, ctx,
+                                                    attrTypeCode, attrLen,
+                                                    attrFlags, message);
+                break;
+
+            case BgpConstants.Update.LocalPref.TYPE:
+                // Attribute Type Code LOCAL_PREF
+                localPref =
+                    parseAttributeTypeLocalPref(bgpSession, ctx,
+                                                attrTypeCode, attrLen,
+                                                attrFlags, message);
+                break;
+
+            case BgpConstants.Update.AtomicAggregate.TYPE:
+                // Attribute Type Code ATOMIC_AGGREGATE
+                parseAttributeTypeAtomicAggregate(bgpSession, ctx,
+                                                  attrTypeCode, attrLen,
+                                                  attrFlags, message);
+                // Nothing to do: this attribute is primarily informational
+                break;
+
+            case BgpConstants.Update.Aggregator.TYPE:
+                // Attribute Type Code AGGREGATOR
+                Pair<Long, Ip4Address> aggregator =
+                    parseAttributeTypeAggregator(bgpSession, ctx,
+                                                 attrTypeCode, attrLen,
+                                                 attrFlags, message);
+                aggregatorAsNumber = aggregator.getLeft();
+                aggregatorIpAddress = aggregator.getRight();
+                break;
+
+            default:
+                // NOTE: Parse any new Attribute Types if needed
+                if (!optionalBit) {
+                    // ERROR: Unrecognized Well-known Attribute
+                    actionsBgpUpdateUnrecognizedWellKnownAttribute(
+                        bgpSession, ctx, attrTypeCode, attrLen, attrFlags,
+                        message);
+                    String errorMsg = "Unrecognized Well-known Attribute: " +
+                        attrTypeCode;
+                    throw new BgpParseException(errorMsg);
+                }
+
+                // Skip the data from the unrecognized attribute
+                log.debug("BGP RX UPDATE message from {}: " +
+                          "Unrecognized Attribute Type {}",
+                          bgpSession.getRemoteAddress(), attrTypeCode);
+                message.skipBytes(attrLen);
+                break;
+            }
+        }
+
+        // Verify the Well-known Attributes
+        verifyBgpUpdateWellKnownAttributes(bgpSession, ctx, origin, asPath,
+                                           nextHop, localPref);
+
+        //
+        // Parse the NLRI (Network Layer Reachability Information)
+        //
+        Collection<Ip4Prefix> addedPrefixes = null;
+        int nlriLength = message.readableBytes();
+        try {
+            addedPrefixes = parsePackedPrefixes(nlriLength, message);
+        } catch (BgpParseException e) {
+            // ERROR: Invalid Network Field
+            log.debug("Exception parsing NLRI from BGP peer {}: ",
+                      bgpSession.getRemoteBgpId(), e);
+            actionsBgpUpdateInvalidNetworkField(bgpSession, ctx);
+            // Rethrow the exception
+            throw e;
+        }
+
+        // Generate the added routes
+        for (Ip4Prefix prefix : addedPrefixes) {
+            BgpRouteEntry bgpRouteEntry =
+                new BgpRouteEntry(bgpSession, prefix, nextHop,
+                                  origin.byteValue(), asPath, localPref);
+            bgpRouteEntry.setMultiExitDisc(multiExitDisc);
+            if (bgpRouteEntry.hasAsPathLoop(bgpSession.getLocalAs())) {
+                log.debug("BGP RX UPDATE message IGNORED from {}: {} " +
+                          "nextHop {}: contains AS Path loop",
+                          bgpSession.getRemoteAddress(), prefix, nextHop);
+                continue;
+            } else {
+                log.debug("BGP RX UPDATE message ADDED from {}: {} nextHop {}",
+                          bgpSession.getRemoteAddress(), prefix, nextHop);
+            }
+            addedRoutes.put(prefix, bgpRouteEntry);
+        }
+
+        return addedRoutes.values();
+    }
+
+    /**
+     * Verifies BGP UPDATE Well-known Attributes.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param origin the ORIGIN well-known mandatory attribute
+     * @param asPath the AS_PATH well-known mandatory attribute
+     * @param nextHop the NEXT_HOP well-known mandatory attribute
+     * @param localPref the LOCAL_PREF required attribute
+     * @throws BgpParseException
+     */
+    private static void verifyBgpUpdateWellKnownAttributes(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                Short origin,
+                                BgpRouteEntry.AsPath asPath,
+                                Ip4Address nextHop,
+                                Long localPref)
+        throws BgpParseException {
+        //
+        // Check for Missing Well-known Attributes
+        //
+        if ((origin == null) || (origin == -1)) {
+            // Missing Attribute Type Code ORIGIN
+            int type = BgpConstants.Update.Origin.TYPE;
+            actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type);
+            String errorMsg = "Missing Well-known Attribute: ORIGIN";
+            throw new BgpParseException(errorMsg);
+        }
+        if (asPath == null) {
+            // Missing Attribute Type Code AS_PATH
+            int type = BgpConstants.Update.AsPath.TYPE;
+            actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type);
+            String errorMsg = "Missing Well-known Attribute: AS_PATH";
+            throw new BgpParseException(errorMsg);
+        }
+        if (nextHop == null) {
+            // Missing Attribute Type Code NEXT_HOP
+            int type = BgpConstants.Update.NextHop.TYPE;
+            actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type);
+            String errorMsg = "Missing Well-known Attribute: NEXT_HOP";
+            throw new BgpParseException(errorMsg);
+        }
+        if (localPref == null) {
+            // Missing Attribute Type Code LOCAL_PREF
+            // NOTE: Required for iBGP
+            int type = BgpConstants.Update.LocalPref.TYPE;
+            actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type);
+            String errorMsg = "Missing Well-known Attribute: LOCAL_PREF";
+            throw new BgpParseException(errorMsg);
+        }
+    }
+
+    /**
+     * Verifies the BGP UPDATE Attribute Flags.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @throws BgpParseException
+     */
+    private static void verifyBgpUpdateAttributeFlags(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message)
+        throws BgpParseException {
+
+        //
+        // Assign the Attribute Type Name and the Well-known flag
+        //
+        String typeName = "UNKNOWN";
+        boolean isWellKnown = false;
+        switch (attrTypeCode) {
+        case BgpConstants.Update.Origin.TYPE:
+            isWellKnown = true;
+            typeName = "ORIGIN";
+            break;
+        case BgpConstants.Update.AsPath.TYPE:
+            isWellKnown = true;
+            typeName = "AS_PATH";
+            break;
+        case BgpConstants.Update.NextHop.TYPE:
+            isWellKnown = true;
+            typeName = "NEXT_HOP";
+            break;
+        case BgpConstants.Update.MultiExitDisc.TYPE:
+            isWellKnown = false;
+            typeName = "MULTI_EXIT_DISC";
+            break;
+        case BgpConstants.Update.LocalPref.TYPE:
+            isWellKnown = true;
+            typeName = "LOCAL_PREF";
+            break;
+        case BgpConstants.Update.AtomicAggregate.TYPE:
+            isWellKnown = true;
+            typeName = "ATOMIC_AGGREGATE";
+            break;
+        case BgpConstants.Update.Aggregator.TYPE:
+            isWellKnown = false;
+            typeName = "AGGREGATOR";
+            break;
+        default:
+            isWellKnown = false;
+            typeName = "UNKNOWN(" + attrTypeCode + ")";
+            break;
+        }
+
+        //
+        // Verify the Attribute Flags
+        //
+        boolean optionalBit =       ((0x80 & attrFlags) != 0);
+        boolean transitiveBit =     ((0x40 & attrFlags) != 0);
+        boolean partialBit =        ((0x20 & attrFlags) != 0);
+        if ((isWellKnown && optionalBit) ||
+            (isWellKnown && (!transitiveBit)) ||
+            (isWellKnown && partialBit) ||
+            (optionalBit && (!transitiveBit) && partialBit)) {
+            //
+            // ERROR: The Optional bit cannot be set for Well-known attributes
+            // ERROR: The Transtive bit MUST be 1 for well-known attributes
+            // ERROR: The Partial bit MUST be 0 for well-known attributes
+            // ERROR: The Partial bit MUST be 0 for optional non-transitive
+            //        attributes
+            //
+            actionsBgpUpdateAttributeFlagsError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Attribute Flags Error for " + typeName + ": " +
+                attrFlags;
+            throw new BgpParseException(errorMsg);
+        }
+    }
+
+    /**
+     * Parses BGP UPDATE Attribute Type ORIGIN.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @return the parsed ORIGIN value
+     * @throws BgpParseException
+     */
+    private static short parseAttributeTypeOrigin(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message)
+        throws BgpParseException {
+
+        // Check the Attribute Length
+        if (attrLen != BgpConstants.Update.Origin.LENGTH) {
+            // ERROR: Attribute Length Error
+            actionsBgpUpdateAttributeLengthError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Attribute Length Error";
+            throw new BgpParseException(errorMsg);
+        }
+
+        message.markReaderIndex();
+        short origin = message.readUnsignedByte();
+        switch (origin) {
+        case BgpConstants.Update.Origin.IGP:
+            // FALLTHROUGH
+        case BgpConstants.Update.Origin.EGP:
+            // FALLTHROUGH
+        case BgpConstants.Update.Origin.INCOMPLETE:
+            break;
+        default:
+            // ERROR: Invalid ORIGIN Attribute
+            message.resetReaderIndex();
+            actionsBgpUpdateInvalidOriginAttribute(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message,
+                origin);
+            String errorMsg = "Invalid ORIGIN Attribute: " + origin;
+            throw new BgpParseException(errorMsg);
+        }
+
+        return origin;
+    }
+
+    /**
+     * Parses BGP UPDATE Attribute AS Path.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @return the parsed AS Path
+     * @throws BgpParseException
+     */
+    private static BgpRouteEntry.AsPath parseAttributeTypeAsPath(
+                                                BgpSession bgpSession,
+                                                ChannelHandlerContext ctx,
+                                                int attrTypeCode,
+                                                int attrLen,
+                                                int attrFlags,
+                                                ChannelBuffer message)
+        throws BgpParseException {
+        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+
+        //
+        // Parse the message
+        //
+        while (attrLen > 0) {
+            if (attrLen < 2) {
+                // ERROR: Malformed AS_PATH
+                actionsBgpUpdateMalformedAsPath(bgpSession, ctx);
+                String errorMsg = "Malformed AS Path";
+                throw new BgpParseException(errorMsg);
+            }
+            // Get the Path Segment Type and Length (in number of ASes)
+            short pathSegmentType = message.readUnsignedByte();
+            short pathSegmentLength = message.readUnsignedByte();
+            attrLen -= 2;
+
+            // Verify the Path Segment Type
+            switch (pathSegmentType) {
+            case BgpConstants.Update.AsPath.AS_SET:
+                // FALLTHROUGH
+            case BgpConstants.Update.AsPath.AS_SEQUENCE:
+                // FALLTHROUGH
+            case BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE:
+                // FALLTHROUGH
+            case BgpConstants.Update.AsPath.AS_CONFED_SET:
+                break;
+            default:
+                // ERROR: Invalid Path Segment Type
+                //
+                // NOTE: The BGP Spec (RFC 4271) doesn't contain Error Subcode
+                // for "Invalid Path Segment Type", hence we return
+                // the error as "Malformed AS_PATH".
+                //
+                actionsBgpUpdateMalformedAsPath(bgpSession, ctx);
+                String errorMsg =
+                    "Invalid AS Path Segment Type: " + pathSegmentType;
+                throw new BgpParseException(errorMsg);
+            }
+
+            // Parse the AS numbers
+            if (2 * pathSegmentLength > attrLen) {
+                // ERROR: Malformed AS_PATH
+                actionsBgpUpdateMalformedAsPath(bgpSession, ctx);
+                String errorMsg = "Malformed AS Path";
+                throw new BgpParseException(errorMsg);
+            }
+            attrLen -= (2 * pathSegmentLength);
+            ArrayList<Long> segmentAsNumbers = new ArrayList<>();
+            while (pathSegmentLength-- > 0) {
+                long asNumber = message.readUnsignedShort();
+                segmentAsNumbers.add(asNumber);
+            }
+
+            BgpRouteEntry.PathSegment pathSegment =
+                new BgpRouteEntry.PathSegment((byte) pathSegmentType,
+                                              segmentAsNumbers);
+            pathSegments.add(pathSegment);
+        }
+
+        return new BgpRouteEntry.AsPath(pathSegments);
+    }
+
+    /**
+     * Parses BGP UPDATE Attribute Type NEXT_HOP.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @return the parsed NEXT_HOP value
+     * @throws BgpParseException
+     */
+    private static Ip4Address parseAttributeTypeNextHop(
+                                        BgpSession bgpSession,
+                                        ChannelHandlerContext ctx,
+                                        int attrTypeCode,
+                                        int attrLen,
+                                        int attrFlags,
+                                        ChannelBuffer message)
+        throws BgpParseException {
+
+        // Check the Attribute Length
+        if (attrLen != BgpConstants.Update.NextHop.LENGTH) {
+            // ERROR: Attribute Length Error
+            actionsBgpUpdateAttributeLengthError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Attribute Length Error";
+            throw new BgpParseException(errorMsg);
+        }
+
+        message.markReaderIndex();
+        Ip4Address nextHopAddress =
+            Ip4Address.valueOf((int) message.readUnsignedInt());
+        //
+        // Check whether the NEXT_HOP IP address is semantically correct.
+        // As per RFC 4271, Section 6.3:
+        //
+        //  a) It MUST NOT be the IP address of the receiving speaker
+        //  b) In the case of an EBGP ....
+        //
+        // Here we check only (a), because (b) doesn't apply for us: all our
+        // peers are iBGP.
+        //
+        if (nextHopAddress.equals(bgpSession.getLocalIp4Address())) {
+            // ERROR: Invalid NEXT_HOP Attribute
+            message.resetReaderIndex();
+            actionsBgpUpdateInvalidNextHopAttribute(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message,
+                nextHopAddress);
+            String errorMsg = "Invalid NEXT_HOP Attribute: " + nextHopAddress;
+            throw new BgpParseException(errorMsg);
+        }
+
+        return nextHopAddress;
+    }
+
+    /**
+     * Parses BGP UPDATE Attribute Type MULTI_EXIT_DISC.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @return the parsed MULTI_EXIT_DISC value
+     * @throws BgpParseException
+     */
+    private static long parseAttributeTypeMultiExitDisc(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message)
+        throws BgpParseException {
+
+        // Check the Attribute Length
+        if (attrLen != BgpConstants.Update.MultiExitDisc.LENGTH) {
+            // ERROR: Attribute Length Error
+            actionsBgpUpdateAttributeLengthError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Attribute Length Error";
+            throw new BgpParseException(errorMsg);
+        }
+
+        long multiExitDisc = message.readUnsignedInt();
+        return multiExitDisc;
+    }
+
+    /**
+     * Parses BGP UPDATE Attribute Type LOCAL_PREF.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @return the parsed LOCAL_PREF value
+     * @throws BgpParseException
+     */
+    private static long parseAttributeTypeLocalPref(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message)
+        throws BgpParseException {
+
+        // Check the Attribute Length
+        if (attrLen != BgpConstants.Update.LocalPref.LENGTH) {
+            // ERROR: Attribute Length Error
+            actionsBgpUpdateAttributeLengthError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Attribute Length Error";
+            throw new BgpParseException(errorMsg);
+        }
+
+        long localPref = message.readUnsignedInt();
+        return localPref;
+    }
+
+    /**
+     * Parses BGP UPDATE Attribute Type ATOMIC_AGGREGATE.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @throws BgpParseException
+     */
+    private static void parseAttributeTypeAtomicAggregate(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message)
+        throws BgpParseException {
+
+        // Check the Attribute Length
+        if (attrLen != BgpConstants.Update.AtomicAggregate.LENGTH) {
+            // ERROR: Attribute Length Error
+            actionsBgpUpdateAttributeLengthError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Attribute Length Error";
+            throw new BgpParseException(errorMsg);
+        }
+
+        // Nothing to do: this attribute is primarily informational
+    }
+
+    /**
+     * Parses BGP UPDATE Attribute Type AGGREGATOR.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message to parse
+     * @return the parsed AGGREGATOR value: a tuple of <AS-Number, IP-Address>
+     * @throws BgpParseException
+     */
+    private static Pair<Long, Ip4Address> parseAttributeTypeAggregator(
+                                                BgpSession bgpSession,
+                                                ChannelHandlerContext ctx,
+                                                int attrTypeCode,
+                                                int attrLen,
+                                                int attrFlags,
+                                                ChannelBuffer message)
+        throws BgpParseException {
+
+        // Check the Attribute Length
+        if (attrLen != BgpConstants.Update.Aggregator.LENGTH) {
+            // ERROR: Attribute Length Error
+            actionsBgpUpdateAttributeLengthError(
+                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
+            String errorMsg = "Attribute Length Error";
+            throw new BgpParseException(errorMsg);
+        }
+
+        // The AGGREGATOR AS number
+        long aggregatorAsNumber = message.readUnsignedShort();
+        // The AGGREGATOR IP address
+        Ip4Address aggregatorIpAddress =
+            Ip4Address.valueOf((int) message.readUnsignedInt());
+
+        Pair<Long, Ip4Address> aggregator = Pair.of(aggregatorAsNumber,
+                                                    aggregatorIpAddress);
+        return aggregator;
+    }
+
+    /**
+     * Parses a message that contains encoded IPv4 network prefixes.
+     * <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 totalLength the total length of the data to parse
+     * @param message the message with data to parse
+     * @return a collection of parsed IPv4 network prefixes
+     * @throws BgpParseException
+     */
+    private static Collection<Ip4Prefix> parsePackedPrefixes(
+                                                int totalLength,
+                                                ChannelBuffer message)
+        throws BgpParseException {
+        Collection<Ip4Prefix> result = new ArrayList<>();
+
+        if (totalLength == 0) {
+            return result;
+        }
+
+        // Parse the data
+        int dataEnd = message.readerIndex() + totalLength;
+        while (message.readerIndex() < dataEnd) {
+            int prefixBitlen = message.readUnsignedByte();
+            int prefixBytelen = (prefixBitlen + 7) / 8;     // Round-up
+            if (message.readerIndex() + prefixBytelen > dataEnd) {
+                String errorMsg = "Malformed Network Prefixes";
+                throw new BgpParseException(errorMsg);
+            }
+
+            long address = 0;
+            long extraShift = (4 - prefixBytelen) * 8;
+            while (prefixBytelen > 0) {
+                address <<= 8;
+                address |= message.readUnsignedByte();
+                prefixBytelen--;
+            }
+            address <<= extraShift;
+            Ip4Prefix prefix =
+                Ip4Prefix.valueOf(Ip4Address.valueOf((int) address),
+                                  prefixBitlen);
+            result.add(prefix);
+        }
+
+        return result;
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Invalid Network Field Error: send NOTIFICATION and close the channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     */
+    private static void actionsBgpUpdateInvalidNetworkField(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx) {
+        log.debug("BGP RX UPDATE Error from {}: Invalid Network Field",
+                  bgpSession.getRemoteAddress());
+
+        //
+        // ERROR: Invalid Network Field
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = UpdateMessageError.ERROR_CODE;
+        int errorSubcode = UpdateMessageError.INVALID_NETWORK_FIELD;
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   null);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Malformed Attribute List Error: send NOTIFICATION and close the channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     */
+    private static void actionsBgpUpdateMalformedAttributeList(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx) {
+        log.debug("BGP RX UPDATE Error from {}: Malformed Attribute List",
+                  bgpSession.getRemoteAddress());
+
+        //
+        // ERROR: Malformed Attribute List
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = UpdateMessageError.ERROR_CODE;
+        int errorSubcode = UpdateMessageError.MALFORMED_ATTRIBUTE_LIST;
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   null);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Missing Well-known Attribute Error: send NOTIFICATION and close the
+     * channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param missingAttrTypeCode the missing attribute type code
+     */
+    private static void actionsBgpUpdateMissingWellKnownAttribute(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int missingAttrTypeCode) {
+        log.debug("BGP RX UPDATE Error from {}: Missing Well-known Attribute: {}",
+                  bgpSession.getRemoteAddress(), missingAttrTypeCode);
+
+        //
+        // ERROR: Missing Well-known Attribute
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = UpdateMessageError.ERROR_CODE;
+        int errorSubcode = UpdateMessageError.MISSING_WELL_KNOWN_ATTRIBUTE;
+        ChannelBuffer data = ChannelBuffers.buffer(1);
+        data.writeByte(missingAttrTypeCode);
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   data);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Invalid ORIGIN Attribute Error: send NOTIFICATION and close the channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message with the data
+     * @param origin the ORIGIN attribute value
+     */
+    private static void actionsBgpUpdateInvalidOriginAttribute(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message,
+                                short origin) {
+        log.debug("BGP RX UPDATE Error from {}: Invalid ORIGIN Attribute",
+                  bgpSession.getRemoteAddress());
+
+        //
+        // ERROR: Invalid ORIGIN Attribute
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = UpdateMessageError.ERROR_CODE;
+        int errorSubcode = UpdateMessageError.INVALID_ORIGIN_ATTRIBUTE;
+        ChannelBuffer data =
+            prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
+                                                    attrFlags, message);
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   data);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Attribute Flags Error: send NOTIFICATION and close the channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message with the data
+     */
+    private static void actionsBgpUpdateAttributeFlagsError(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message) {
+        log.debug("BGP RX UPDATE Error from {}: Attribute Flags Error",
+                  bgpSession.getRemoteAddress());
+
+        //
+        // ERROR: Attribute Flags Error
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = UpdateMessageError.ERROR_CODE;
+        int errorSubcode = UpdateMessageError.ATTRIBUTE_FLAGS_ERROR;
+        ChannelBuffer data =
+            prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
+                                                    attrFlags, message);
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   data);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Invalid NEXT_HOP Attribute Error: send NOTIFICATION and close the
+     * channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message with the data
+     * @param nextHop the NEXT_HOP attribute value
+     */
+    private static void actionsBgpUpdateInvalidNextHopAttribute(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message,
+                                Ip4Address nextHop) {
+        log.debug("BGP RX UPDATE Error from {}: Invalid NEXT_HOP Attribute {}",
+                  bgpSession.getRemoteAddress(), nextHop);
+
+        //
+        // ERROR: Invalid ORIGIN Attribute
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = UpdateMessageError.ERROR_CODE;
+        int errorSubcode = UpdateMessageError.INVALID_NEXT_HOP_ATTRIBUTE;
+        ChannelBuffer data =
+            prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
+                                                    attrFlags, message);
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   data);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Unrecognized Well-known Attribute Error: send NOTIFICATION and close
+     * the channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message with the data
+     */
+    private static void actionsBgpUpdateUnrecognizedWellKnownAttribute(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message) {
+        log.debug("BGP RX UPDATE Error from {}: " +
+                  "Unrecognized Well-known Attribute Error: {}",
+                  bgpSession.getRemoteAddress(), attrTypeCode);
+
+        //
+        // ERROR: Unrecognized Well-known Attribute
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = UpdateMessageError.ERROR_CODE;
+        int errorSubcode =
+            UpdateMessageError.UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE;
+        ChannelBuffer data =
+            prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
+                                                    attrFlags, message);
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   data);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Attribute Length Error: send NOTIFICATION and close the channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message with the data
+     */
+    private static void actionsBgpUpdateAttributeLengthError(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx,
+                                int attrTypeCode,
+                                int attrLen,
+                                int attrFlags,
+                                ChannelBuffer message) {
+        log.debug("BGP RX UPDATE Error from {}: Attribute Length Error",
+                  bgpSession.getRemoteAddress());
+
+        //
+        // ERROR: Attribute Length Error
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = UpdateMessageError.ERROR_CODE;
+        int errorSubcode = UpdateMessageError.ATTRIBUTE_LENGTH_ERROR;
+        ChannelBuffer data =
+            prepareBgpUpdateNotificationDataPayload(attrTypeCode, attrLen,
+                                                    attrFlags, message);
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   data);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Applies the appropriate actions after detecting BGP UPDATE
+     * Malformed AS_PATH Error: send NOTIFICATION and close the channel.
+     *
+     * @param bgpSession the BGP Session to use
+     * @param ctx the Channel Handler Context
+     */
+    private static void actionsBgpUpdateMalformedAsPath(
+                                BgpSession bgpSession,
+                                ChannelHandlerContext ctx) {
+        log.debug("BGP RX UPDATE Error from {}: Malformed AS Path",
+                  bgpSession.getRemoteAddress());
+
+        //
+        // ERROR: Malformed AS_PATH
+        //
+        // Send NOTIFICATION and close the connection
+        int errorCode = UpdateMessageError.ERROR_CODE;
+        int errorSubcode = UpdateMessageError.MALFORMED_AS_PATH;
+        ChannelBuffer txMessage =
+            BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
+                                                   null);
+        ctx.getChannel().write(txMessage);
+        bgpSession.closeSession(ctx);
+    }
+
+    /**
+     * Prepares BGP UPDATE Notification data payload.
+     *
+     * @param attrTypeCode the attribute type code
+     * @param attrLen the attribute length (in octets)
+     * @param attrFlags the attribute flags
+     * @param message the message with the data
+     * @return the buffer with the data payload for the BGP UPDATE Notification
+     */
+    private static ChannelBuffer prepareBgpUpdateNotificationDataPayload(
+                                        int attrTypeCode,
+                                        int attrLen,
+                                        int attrFlags,
+                                        ChannelBuffer message) {
+        // Compute the attribute length field octets
+        boolean extendedLengthBit = ((0x10 & attrFlags) != 0);
+        int attrLenOctets = 1;
+        if (extendedLengthBit) {
+            attrLenOctets = 2;
+        }
+        ChannelBuffer data =
+            ChannelBuffers.buffer(attrLen + attrLenOctets + 1);
+        data.writeByte(attrTypeCode);
+        if (extendedLengthBit) {
+            data.writeShort(attrLen);
+        } else {
+            data.writeByte(attrLen);
+        }
+        data.writeBytes(message, attrLen);
+        return data;
+    }
+
+    /**
+     * An exception indicating a parsing error of the BGP message.
+     */
+    private static final class BgpParseException extends Exception {
+        /**
+         * Default constructor.
+         */
+        private BgpParseException() {
+            super();
+        }
+
+        /**
+         * Constructor for a specific exception details message.
+         *
+         * @param message the message with the exception details
+         */
+         private BgpParseException(String message) {
+             super(message);
+         }
+    }
+}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/BgpRoutesListCommand.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/BgpRoutesListCommand.java
index 43673c3..d7b7cc7 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/BgpRoutesListCommand.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/BgpRoutesListCommand.java
@@ -81,7 +81,7 @@
 
         // Print the routes
         if (foundBgpSession != null) {
-            printRoutes(foundBgpSession.getBgpRibIn());
+            printRoutes(foundBgpSession.bgpRibIn().values());
         } else {
             printRoutes(service.getBgpRoutes());
         }
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpSessionManagerTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpSessionManagerTest.java
index 5199f20..0eaaa22 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpSessionManagerTest.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpSessionManagerTest.java
@@ -303,7 +303,7 @@
     private Collection<BgpRouteEntry> waitForBgpRibIn(BgpSession bgpSession,
                                                       long expectedRoutes)
         throws InterruptedException {
-        Collection<BgpRouteEntry> bgpRibIn = bgpSession.getBgpRibIn();
+        Collection<BgpRouteEntry> bgpRibIn = bgpSession.bgpRibIn().values();
 
         final int maxChecks = 500;              // Max wait of 5 seconds
         for (int i = 0; i < maxChecks; i++) {
@@ -311,7 +311,7 @@
                 break;
             }
             Thread.sleep(10);
-            bgpRibIn = bgpSession.getBgpRibIn();
+            bgpRibIn = bgpSession.bgpRibIn().values();
         }
 
         return bgpRibIn;
