ONOS-866: Refactor the storing and handling of BgpSession info.

Moved the local and remote BGP session info to a separate class BgpSessionInfo.
No functional changes.

Also, removed methods TestBgpPeerChannelHandler.prepareBgpKeepalive(),
prepareBgpNotification() and prepareBgpMessage() from the unit tests.
Instead, use the corresponding methods in the BGP implementation itself
to generate the BGP messages.

Change-Id: I7f4b6ad4f6995c242cd8a9848ea527b1fcac9c11
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
index 833f2f9..fe9404c 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpKeepalive.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpKeepalive.java
@@ -51,7 +51,7 @@
             BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH) {
             log.debug("BGP RX KEEPALIVE Error from {}: " +
                       "Invalid total message length {}. Expected {}",
-                      bgpSession.getRemoteAddress(),
+                      bgpSession.remoteInfo().address(),
                       message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH,
                       BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH);
             //
@@ -70,7 +70,7 @@
         // Parse the KEEPALIVE message: nothing to do
         //
         log.trace("BGP RX KEEPALIVE message from {}",
-                  bgpSession.getRemoteAddress());
+                  bgpSession.remoteInfo().address());
 
         // Start the Session Timeout timer
         bgpSession.restartSessionTimeoutTimer(ctx);
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
index 4abdbf7..cf6bbb7 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpNotification.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpNotification.java
@@ -53,8 +53,8 @@
         if (message.readableBytes() < minLength) {
             log.debug("BGP RX NOTIFICATION Error from {}: " +
                       "Message length {} too short. Must be at least {}",
-                      bgpSession.getRemoteAddress(), message.readableBytes(),
-                      minLength);
+                      bgpSession.remoteInfo().address(),
+                      message.readableBytes(), minLength);
             //
             // ERROR: Bad Message Length
             //
@@ -71,7 +71,7 @@
 
         log.debug("BGP RX NOTIFICATION message from {}: Error Code {} " +
                   "Error Subcode {} Data Length {}",
-                  bgpSession.getRemoteAddress(), errorCode, errorSubcode,
+                  bgpSession.remoteInfo().address(), errorCode, errorSubcode,
                   dataLength);
 
         //
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
index 31471a3..d15a669 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpOpen.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpOpen.java
@@ -58,8 +58,8 @@
         if (message.readableBytes() < minLength) {
             log.debug("BGP RX OPEN Error from {}: " +
                       "Message length {} too short. Must be at least {}",
-                      bgpSession.getRemoteAddress(), message.readableBytes(),
-                      minLength);
+                      bgpSession.remoteInfo().address(),
+                      message.readableBytes(), minLength);
             //
             // ERROR: Bad Message Length
             //
@@ -80,7 +80,7 @@
         if (remoteBgpVersion != BgpConstants.BGP_VERSION) {
             log.debug("BGP RX OPEN Error from {}: " +
                       "Unsupported BGP version {}. Should be {}",
-                      bgpSession.getRemoteAddress(), remoteBgpVersion,
+                      bgpSession.remoteInfo().address(), remoteBgpVersion,
                       BgpConstants.BGP_VERSION);
             //
             // ERROR: Unsupported Version Number
@@ -97,7 +97,7 @@
             bgpSession.closeSession(ctx);
             return;
         }
-        bgpSession.setRemoteBgpVersion(remoteBgpVersion);
+        bgpSession.remoteInfo().setBgpVersion(remoteBgpVersion);
 
         // Remote AS number
         long remoteAs = message.readUnsignedShort();
@@ -107,11 +107,12 @@
         // sessions are iBGP.
         //
         for (BgpSession bs : bgpSession.getBgpSessionManager().getBgpSessions()) {
-            if ((bs.getRemoteAs() != 0) && (remoteAs != bs.getRemoteAs())) {
+            if ((bs.remoteInfo().asNumber() != 0) &&
+                (remoteAs != bs.remoteInfo().asNumber())) {
                 log.debug("BGP RX OPEN Error from {}: Bad Peer AS {}. " +
                           "Expected {}",
-                          bgpSession.getRemoteAddress(), remoteAs,
-                          bs.getRemoteAs());
+                          bgpSession.remoteInfo().address(), remoteAs,
+                          bs.remoteInfo().asNumber());
                 //
                 // ERROR: Bad Peer AS
                 //
@@ -126,7 +127,14 @@
                 return;
             }
         }
-        bgpSession.setRemoteAs(remoteAs);
+        bgpSession.remoteInfo().setAsNumber(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.
+        //
+        bgpSession.localInfo().setAsNumber(remoteAs);
 
         // Remote Hold Time
         long remoteHoldtime = message.readUnsignedShort();
@@ -135,7 +143,7 @@
             log.debug("BGP RX OPEN Error from {}: " +
                       "Unacceptable Hold Time field {}. " +
                       "Should be 0 or at least {}",
-                      bgpSession.getRemoteAddress(), remoteHoldtime,
+                      bgpSession.remoteInfo().address(), remoteHoldtime,
                       BgpConstants.BGP_KEEPALIVE_MIN_HOLDTIME);
             //
             // ERROR: Unacceptable Hold Time
@@ -150,12 +158,19 @@
             bgpSession.closeSession(ctx);
             return;
         }
-        bgpSession.setRemoteHoldtime(remoteHoldtime);
+        bgpSession.remoteInfo().setHoldtime(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.
+        //
+        bgpSession.localInfo().setHoldtime(remoteHoldtime);
 
         // Remote BGP Identifier
         Ip4Address remoteBgpId =
             Ip4Address.valueOf((int) message.readUnsignedInt());
-        bgpSession.setRemoteBgpId(remoteBgpId);
+        bgpSession.remoteInfo().setBgpId(remoteBgpId);
 
         // Parse the Optional Parameters
         try {
@@ -164,7 +179,7 @@
             // ERROR: Error parsing optional parameters
             log.debug("BGP RX OPEN Error from {}: " +
                       "Exception parsing Optional Parameters: {}",
-                      bgpSession.getRemoteAddress(), e);
+                      bgpSession.remoteInfo().address(), e);
             //
             // ERROR: Invalid Optional Parameters: Unspecific
             //
@@ -181,11 +196,11 @@
 
         log.debug("BGP RX OPEN message from {}: " +
                   "BGPv{} AS {} BGP-ID {} Holdtime {}",
-                  bgpSession.getRemoteAddress(), remoteBgpVersion, remoteAs,
-                  remoteBgpId, remoteHoldtime);
+                  bgpSession.remoteInfo().address(), remoteBgpVersion,
+                  remoteAs, remoteBgpId, remoteHoldtime);
 
         // Send my OPEN followed by KEEPALIVE
-        ChannelBuffer txMessage = prepareBgpOpen(bgpSession);
+        ChannelBuffer txMessage = prepareBgpOpen(bgpSession.localInfo());
         ctx.getChannel().write(txMessage);
         //
         txMessage = BgpKeepalive.prepareBgpKeepalive();
@@ -201,24 +216,24 @@
     /**
      * Prepares BGP OPEN message.
      *
-     * @param bgpSession the BGP Session to use
+     * @param localInfo the BGP Session local information to use
      * @return the message to transmit (BGP header included)
      */
-    private static ChannelBuffer prepareBgpOpen(BgpSession bgpSession) {
+    private static ChannelBuffer prepareBgpOpen(BgpSessionInfo localInfo) {
         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(localInfo.bgpVersion());
+        message.writeShort((int) localInfo.asNumber());
+        message.writeShort((int) localInfo.holdtime());
+        message.writeInt(localInfo.bgpId().toInt());
 
         // Prepare the optional BGP Capabilities
         ChannelBuffer capabilitiesMessage =
-            prepareBgpOpenCapabilities(bgpSession);
+            prepareBgpOpenCapabilities(localInfo);
         message.writeByte(capabilitiesMessage.readableBytes());
         message.writeBytes(capabilitiesMessage);
 
@@ -309,18 +324,25 @@
                     //
                     // Setup the AFI/SAFI in the BgpSession
                     //
+                    // NOTE: For now we just copy the remote AFI/SAFI setting
+                    // to the local configuration.
+                    //
                     if (afi == MultiprotocolExtensions.AFI_IPV4 &&
                         safi == MultiprotocolExtensions.SAFI_UNICAST) {
-                        bgpSession.setRemoteIpv4Unicast();
+                        bgpSession.remoteInfo().setIpv4Unicast();
+                        bgpSession.localInfo().setIpv4Unicast();
                     } else if (afi == MultiprotocolExtensions.AFI_IPV4 &&
                                safi == MultiprotocolExtensions.SAFI_MULTICAST) {
-                        bgpSession.setRemoteIpv4Multicast();
+                        bgpSession.remoteInfo().setIpv4Multicast();
+                        bgpSession.localInfo().setIpv4Multicast();
                     } else if (afi == MultiprotocolExtensions.AFI_IPV6 &&
                                safi == MultiprotocolExtensions.SAFI_UNICAST) {
-                        bgpSession.setRemoteIpv6Unicast();
+                        bgpSession.remoteInfo().setIpv6Unicast();
+                        bgpSession.localInfo().setIpv6Unicast();
                     } else if (afi == MultiprotocolExtensions.AFI_IPV6 &&
                                safi == MultiprotocolExtensions.SAFI_MULTICAST) {
-                        bgpSession.setRemoteIpv6Multicast();
+                        bgpSession.remoteInfo().setIpv6Multicast();
+                        bgpSession.localInfo().setIpv6Multicast();
                     } else {
                         log.debug("BGP RX OPEN Capability: Unknown AFI = {} SAFI = {}",
                                   afi, safi);
@@ -336,14 +358,21 @@
                     }
                     long as4Number = message.readUnsignedInt();
 
-                    bgpSession.setRemoteAs4OctetCapability();
-                    bgpSession.setRemoteAs4Octet(as4Number);
+                    bgpSession.remoteInfo().setAs4OctetCapability();
+                    bgpSession.remoteInfo().setAs4Number(as4Number);
+                    // Use the 4-octet AS number in lieu of the "My AS" field
+                    // See RFC 6793, Section 4.1, second paragraph.
+                    bgpSession.remoteInfo().setAsNumber(as4Number);
 
-                    // Copy remote 4-octet AS Number Capabilities and AS Number.
-                    // This is temporary setting until local AS number configuration is supported.
-                    bgpSession.setLocalAs4OctetCapability();
-                    bgpSession.setRemoteAs(as4Number);
-                    log.debug("BGP RX OPEN Capability:  AS4 Number = {}",
+                    //
+                    // Copy remote 4-octet AS Number Capabilities and AS
+                    // Number. This is a temporary setting until local AS
+                    // number configuration is supported.
+                    //
+                    bgpSession.localInfo().setAs4OctetCapability();
+                    bgpSession.localInfo().setAs4Number(as4Number);
+                    bgpSession.localInfo().setAsNumber(as4Number);
+                    log.debug("BGP RX OPEN Capability: AS4 Number = {}",
                               as4Number);
                     break;
 
@@ -370,11 +399,11 @@
     /**
      * Prepares the Capabilities for the BGP OPEN message.
      *
-     * @param bgpSession the BGP Session to use
+     * @param localInfo the BGP Session local information to use
      * @return the buffer with the BGP Capabilities to transmit
      */
     private static ChannelBuffer prepareBgpOpenCapabilities(
-                                        BgpSession bgpSession) {
+                                        BgpSessionInfo localInfo) {
         ChannelBuffer message =
             ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
 
@@ -383,7 +412,7 @@
         //
 
         // IPv4 unicast
-        if (bgpSession.getLocalIpv4Unicast()) {
+        if (localInfo.ipv4Unicast()) {
             message.writeByte(Capabilities.TYPE);               // Param type
             message.writeByte(Capabilities.MIN_LENGTH +
                               MultiprotocolExtensions.LENGTH);  // Param len
@@ -394,7 +423,7 @@
             message.writeByte(MultiprotocolExtensions.SAFI_UNICAST);
         }
         // IPv4 multicast
-        if (bgpSession.getLocalIpv4Multicast()) {
+        if (localInfo.ipv4Multicast()) {
             message.writeByte(Capabilities.TYPE);               // Param type
             message.writeByte(Capabilities.MIN_LENGTH +
                               MultiprotocolExtensions.LENGTH);  // Param len
@@ -405,7 +434,7 @@
             message.writeByte(MultiprotocolExtensions.SAFI_MULTICAST);
         }
         // IPv6 unicast
-        if (bgpSession.getLocalIpv6Unicast()) {
+        if (localInfo.ipv6Unicast()) {
             message.writeByte(Capabilities.TYPE);               // Param type
             message.writeByte(Capabilities.MIN_LENGTH +
                               MultiprotocolExtensions.LENGTH);  // Param len
@@ -416,7 +445,7 @@
             message.writeByte(MultiprotocolExtensions.SAFI_UNICAST);
         }
         // IPv6 multicast
-        if (bgpSession.getLocalIpv6Multicast()) {
+        if (localInfo.ipv6Multicast()) {
             message.writeByte(Capabilities.TYPE);               // Param type
             message.writeByte(Capabilities.MIN_LENGTH +
                               MultiprotocolExtensions.LENGTH);  // Param len
@@ -428,13 +457,13 @@
         }
 
         // 4 octet AS path capability
-        if (bgpSession.getLocalAs4OctetCapability()) {
+        if (localInfo.as4OctetCapability()) {
             message.writeByte(Capabilities.TYPE);               // Param type
             message.writeByte(Capabilities.MIN_LENGTH +
                               As4Octet.LENGTH);                 // Param len
             message.writeByte(As4Octet.CODE);                   // Capab, code
             message.writeByte(As4Octet.LENGTH);                 // Capab, len
-            message.writeInt((int) bgpSession.getLocalAs());
+            message.writeInt((int) localInfo.as4Number());
         }
         return message;
     }
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpRouteEntry.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpRouteEntry.java
index 67ef5b1..3abdc79 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpRouteEntry.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpRouteEntry.java
@@ -258,16 +258,16 @@
         }
 
         // Compare the peer BGP ID: lower is better
-        Ip4Address peerBgpId = getBgpSession().getRemoteBgpId();
-        Ip4Address otherPeerBgpId = other.getBgpSession().getRemoteBgpId();
+        Ip4Address peerBgpId = getBgpSession().remoteInfo().bgpId();
+        Ip4Address otherPeerBgpId = other.getBgpSession().remoteInfo().bgpId();
         if (!peerBgpId.equals(otherPeerBgpId)) {
             return (peerBgpId.compareTo(otherPeerBgpId) < 0);
         }
 
         // Compare the peer BGP address: lower is better
-        Ip4Address peerAddress = getBgpSession().getRemoteIp4Address();
+        Ip4Address peerAddress = getBgpSession().remoteInfo().ip4Address();
         Ip4Address otherPeerAddress =
-            other.getBgpSession().getRemoteIp4Address();
+            other.getBgpSession().remoteInfo().ip4Address();
         if (!peerAddress.equals(otherPeerAddress)) {
             return (peerAddress.compareTo(otherPeerAddress) < 0);
         }
@@ -486,7 +486,7 @@
         return MoreObjects.toStringHelper(getClass())
             .add("prefix", prefix())
             .add("nextHop", nextHop())
-            .add("bgpId", bgpSession.getRemoteBgpId())
+            .add("bgpId", bgpSession.remoteInfo().bgpId())
             .add("origin", Update.Origin.typeToString(origin))
             .add("asPath", asPath)
             .add("localPref", localPref)
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 38e6b12..ace6b53 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
@@ -17,7 +17,6 @@
 
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
-import java.net.SocketAddress;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.concurrent.ConcurrentHashMap;
@@ -56,36 +55,9 @@
     // It is used to avoid the Netty's asynchronous closing of a channel.
     private boolean isClosed = false;
 
-    private SocketAddress remoteAddress;        // Peer IP addr/port
-    private Ip4Address remoteIp4Address;        // Peer IPv4 address
-    private int remoteBgpVersion;               // 1 octet
-    private long remoteAs;                      // 2 octets
-    private long remoteAs4Octet;                // 4 octets
-    private long remoteHoldtime;                // 2 octets
-    private Ip4Address remoteBgpId;             // 4 octets -> IPv4 address
-    private boolean remoteMpExtensions;         // Peer Multiprotocol
-                                                // Extensions enabled: RFC 4760
-    private boolean remoteIpv4Unicast;          // Peer IPv4/UNICAST AFI/SAFI
-    private boolean remoteIpv4Multicast;        // Peer IPv4/MULTICAST AFI/SAFI
-    private boolean remoteIpv6Unicast;          // Peer IPv6/UNICAST AFI/SAFI
-    private boolean remoteIpv6Multicast;        // Peer IPv6/MULTICAST AFI/SAFI
-    private boolean remoteAs4OctetCapability;   // Peer 4 octet AS path capability
-    //
-    private SocketAddress localAddress;         // Local IP addr/port
-    private Ip4Address localIp4Address;         // Local IPv4 address
-    private int localBgpVersion;                // 1 octet
-    private long localAs;                       // 2 octets
-    private long localHoldtime;                 // 2 octets
-    private Ip4Address localBgpId;              // 4 octets -> IPv4 address
-    private boolean localMpExtensions;          // Local Multiprotocol
-                                                // Extensions enabled: RFC 4760
-    private boolean localIpv4Unicast;        // Local IPv4/UNICAST AFI/SAFI
-    private boolean localIpv4Multicast;      // Local IPv4/MULTICAST AFI/SAFI
-    private boolean localIpv6Unicast;        // Local IPv6/UNICAST AFI/SAFI
-    private boolean localIpv6Multicast;      // Local IPv6/MULTICAST AFI/SAFI
-    private boolean localAs4OctetCapability;    // Local 4 octet AS path capability
-    //
-    private long localKeepaliveInterval;        // Keepalive interval
+    // BGP session info: local and remote
+    private final BgpSessionInfo localInfo;     // BGP session local info
+    private final BgpSessionInfo remoteInfo;    // BGP session remote info
 
     // Timers state
     private Timer timer = new HashedWheelTimer();
@@ -105,9 +77,11 @@
      */
     BgpSession(BgpSessionManager bgpSessionManager) {
         this.bgpSessionManager = bgpSessionManager;
+        this.localInfo = new BgpSessionInfo();
+        this.remoteInfo = new BgpSessionInfo();
 
         // NOTE: We support only BGP4
-        this.localBgpVersion = BgpConstants.BGP_VERSION;
+        this.localInfo.setBgpVersion(BgpConstants.BGP_VERSION);
     }
 
     /**
@@ -120,6 +94,44 @@
     }
 
     /**
+     * Gets the BGP Session local information.
+     *
+     * @return the BGP Session local information.
+     */
+    public BgpSessionInfo localInfo() {
+        return localInfo;
+    }
+
+    /**
+     * Gets the BGP Session remote information.
+     *
+     * @return the BGP Session remote information.
+     */
+    public BgpSessionInfo remoteInfo() {
+        return remoteInfo;
+    }
+
+    /**
+     * Gets the BGP Multiprotocol Extensions for the session.
+     *
+     * @return true if the BGP Multiprotocol Extensions are enabled for the
+     * session, otherwise false
+     */
+    public boolean mpExtensions() {
+        return remoteInfo.mpExtensions() && localInfo.mpExtensions();
+    }
+
+    /**
+     * Gets the BGP session 4 octet AS path capability.
+     *
+     * @return true when the BGP session is 4 octet AS path capable
+     */
+    public boolean isAs4OctetCapable() {
+        return remoteInfo.as4OctetCapability() &&
+            localInfo.as4OctetCapability();
+    }
+
+    /**
      * Gets the IPv4 BGP RIB-IN routing entries.
      *
      * @return the IPv4 BGP RIB-IN routing entries
@@ -227,360 +239,6 @@
     }
 
     /**
-     * Gets the BGP session remote address.
-     *
-     * @return the BGP session remote address
-     */
-    public SocketAddress getRemoteAddress() {
-        return remoteAddress;
-    }
-
-    /**
-     * Gets the BGP session remote IPv4 address.
-     *
-     * @return the BGP session remote IPv4 address
-     */
-    public Ip4Address getRemoteIp4Address() {
-        return remoteIp4Address;
-    }
-
-    /**
-     * Gets the BGP session remote BGP version.
-     *
-     * @return the BGP session remote BGP version
-     */
-    public int getRemoteBgpVersion() {
-        return remoteBgpVersion;
-    }
-
-    /**
-     * 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
-     */
-    public long getRemoteAs() {
-        return remoteAs;
-    }
-
-    /**
-     * 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.
-        //
-        setLocalAs(remoteAs);
-    }
-
-    /**
-     * Sets the BGP session remote 4 octet AS number.
-     *
-     * @param remoteAs4Octet the BGP session remote 4 octet AS number to set
-     */
-    void setRemoteAs4Octet(long remoteAs4Octet) {
-        this.remoteAs4Octet = remoteAs4Octet;
-    }
-
-    /**
-     * Gets the BGP session remote Holdtime.
-     *
-     * @return the BGP session remote Holdtime
-     */
-    public long getRemoteHoldtime() {
-        return remoteHoldtime;
-    }
-
-    /**
-     * 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
-     */
-    public Ip4Address getRemoteBgpId() {
-        return remoteBgpId;
-    }
-
-    /**
-     * 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 Multiprotocol Extensions for the session.
-     *
-     * @return true if the BGP Multiprotocol Extensions are enabled for the
-     * session, otherwise false
-     */
-     public boolean getMpExtensions() {
-        return remoteMpExtensions && localMpExtensions;
-    }
-
-    /**
-     * Gets the BGP session remote AFI/SAFI configuration for IPv4 unicast.
-     *
-     * @return the BGP session remote AFI/SAFI configuration for IPv4 unicast
-     */
-    public boolean getRemoteIpv4Unicast() {
-        return remoteIpv4Unicast;
-    }
-
-    /**
-     * Sets the BGP session remote AFI/SAFI configuration for IPv4 unicast.
-     */
-    void setRemoteIpv4Unicast() {
-        this.remoteMpExtensions = true;
-        this.remoteIpv4Unicast = true;
-        // Copy the remote AFI/SAFI setting to the local configuration
-        this.localMpExtensions = true;
-        this.localIpv4Unicast = true;
-    }
-
-    /**
-     * Gets the BGP session remote AFI/SAFI configuration for IPv4 multicast.
-     *
-     * @return the BGP session remote AFI/SAFI configuration for IPv4 multicast
-     */
-    public boolean getRemoteIpv4Multicast() {
-        return remoteIpv4Multicast;
-    }
-
-    /**
-     * Sets the BGP session remote AFI/SAFI configuration for IPv4 multicast.
-     */
-    void setRemoteIpv4Multicast() {
-        this.remoteMpExtensions = true;
-        this.remoteIpv4Multicast = true;
-        // Copy the remote AFI/SAFI setting to the local configuration
-        this.localMpExtensions = true;
-        this.localIpv4Multicast = true;
-    }
-
-    /**
-     * Gets the BGP session remote AFI/SAFI configuration for IPv6 unicast.
-     *
-     * @return the BGP session remote AFI/SAFI configuration for IPv6 unicast
-     */
-    public boolean getRemoteIpv6Unicast() {
-        return remoteIpv6Unicast;
-    }
-
-    /**
-     * Sets the BGP session remote AFI/SAFI configuration for IPv6 unicast.
-     */
-    void setRemoteIpv6Unicast() {
-        this.remoteMpExtensions = true;
-        this.remoteIpv6Unicast = true;
-        // Copy the remote AFI/SAFI setting to the local configuration
-        this.localMpExtensions = true;
-        this.localIpv6Unicast = true;
-    }
-
-    /**
-     * Gets the BGP session remote AFI/SAFI configuration for IPv6 multicast.
-     *
-     * @return the BGP session remote AFI/SAFI configuration for IPv6 multicast
-     */
-    public boolean getRemoteIpv6Multicast() {
-        return remoteIpv6Multicast;
-    }
-
-    /**
-     * Sets the BGP session remote AFI/SAFI configuration for IPv6 multicast.
-     */
-    void setRemoteIpv6Multicast() {
-        this.remoteMpExtensions = true;
-        this.remoteIpv6Multicast = true;
-        // Copy the remote AFI/SAFI setting to the local configuration
-        this.localMpExtensions = true;
-        this.localIpv6Multicast = true;
-    }
-
-    /**
-     * Gets the BGP session remote 4 octet AS path capability.
-     *
-     * @return true when the BGP session remote has 4 octet AS path capability
-     */
-    public boolean getRemoteAs4OctetCapability() {
-        return remoteAs4OctetCapability;
-    }
-
-    /**
-     * Sets the BGP session remote 4 octet AS path capability.
-     */
-    void setRemoteAs4OctetCapability() {
-        this.remoteAs4OctetCapability = true;
-    }
-
-    /**
-     * Gets the BGP session local 4 octet AS path capability.
-     *
-     * @return true when the BGP session local has 4 octet AS path capability
-     */
-    public boolean getLocalAs4OctetCapability() {
-        return localAs4OctetCapability;
-    }
-
-    /**
-     * Sets the BGP session local 4 octet AS path capability.
-     */
-    void setLocalAs4OctetCapability() {
-        this.localAs4OctetCapability = true;
-    }
-
-    /**
-     * Gets the BGP session 4 octet AS path capability.
-     *
-     * @return true when the BGP session is 4 octet AS path capable
-     */
-    public boolean isAs4OctetCapable() {
-        return getRemoteAs4OctetCapability() && getLocalAs4OctetCapability();
-    }
-
-    /**
-     * Gets the BGP session local address.
-     *
-     * @return the BGP session local address
-     */
-    public SocketAddress getLocalAddress() {
-        return localAddress;
-    }
-
-    /**
-     * 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
-     */
-    public int getLocalBgpVersion() {
-        return localBgpVersion;
-    }
-
-    /**
-     * Gets the BGP session local AS number.
-     *
-     * @return the BGP session local AS number
-     */
-    public long getLocalAs() {
-        return localAs;
-    }
-
-    /**
-     * Sets the BGP session local AS number.
-     *
-     * @param localAs the BGP session local AS number to set
-     */
-    public void setLocalAs(long localAs) {
-        this.localAs = localAs;
-    }
-
-    /**
-     * Gets the BGP session local Holdtime.
-     *
-     * @return the BGP session local Holdtime
-     */
-    public long getLocalHoldtime() {
-        return localHoldtime;
-    }
-
-    /**
-     * Gets the BGP session local BGP Identifier as an IPv4 address.
-     *
-     * @return the BGP session local BGP Identifier as an IPv4 address
-     */
-    public Ip4Address getLocalBgpId() {
-        return localBgpId;
-    }
-
-    /**
-     * Gets the BGP session local AFI/SAFI configuration for IPv4 unicast.
-     *
-     * @return the BGP session local AFI/SAFI configuration for IPv4 unicast
-     */
-    public boolean getLocalIpv4Unicast() {
-        return localIpv4Unicast;
-    }
-
-    /**
-     * Gets the BGP session local AFI/SAFI configuration for IPv4 multicast.
-     *
-     * @return the BGP session local AFI/SAFI configuration for IPv4 multicast
-     */
-    public boolean getLocalIpv4Multicast() {
-        return localIpv4Multicast;
-    }
-
-    /**
-     * Gets the BGP session local AFI/SAFI configuration for IPv6 unicast.
-     *
-     * @return the BGP session local AFI/SAFI configuration for IPv6 unicast
-     */
-    public boolean getLocalIpv6Unicast() {
-        return localIpv6Unicast;
-    }
-
-    /**
-     * Gets the BGP session local AFI/SAFI configuration for IPv6 multicast.
-     *
-     * @return the BGP session local AFI/SAFI configuration for IPv6 multicast
-     */
-    public boolean getLocalIpv6Multicast() {
-        return localIpv6Multicast;
-    }
-
-    /**
      * Tests whether the session is closed.
      * <p>
      * NOTE: We use this method to avoid the Netty's asynchronous closing
@@ -627,25 +285,25 @@
     @Override
     public void channelConnected(ChannelHandlerContext ctx,
                                  ChannelStateEvent channelEvent) {
-        localAddress = ctx.getChannel().getLocalAddress();
-        remoteAddress = ctx.getChannel().getRemoteAddress();
+        localInfo.setAddress(ctx.getChannel().getLocalAddress());
+        remoteInfo.setAddress(ctx.getChannel().getRemoteAddress());
 
         // Assign the local and remote IPv4 addresses
         InetAddress inetAddr;
-        if (localAddress instanceof InetSocketAddress) {
-            inetAddr = ((InetSocketAddress) localAddress).getAddress();
-            localIp4Address = Ip4Address.valueOf(inetAddr.getAddress());
+        if (localInfo.address() instanceof InetSocketAddress) {
+            inetAddr = ((InetSocketAddress) localInfo.address()).getAddress();
+            localInfo.setIp4Address(Ip4Address.valueOf(inetAddr.getAddress()));
         }
-        if (remoteAddress instanceof InetSocketAddress) {
-            inetAddr = ((InetSocketAddress) remoteAddress).getAddress();
-            remoteIp4Address = Ip4Address.valueOf(inetAddr.getAddress());
+        if (remoteInfo.address() instanceof InetSocketAddress) {
+            inetAddr = ((InetSocketAddress) remoteInfo.address()).getAddress();
+            remoteInfo.setIp4Address(Ip4Address.valueOf(inetAddr.getAddress()));
         }
 
         log.debug("BGP Session Connected from {} on {}",
-                  remoteAddress, localAddress);
+                  remoteInfo.address(), localInfo.address());
         if (!bgpSessionManager.peerConnected(this)) {
             log.debug("Cannot setup BGP Session Connection from {}. Closing...",
-                      remoteAddress);
+                      remoteInfo.address());
             ctx.getChannel().close();
         }
 
@@ -653,7 +311,7 @@
         // Assign the local BGP ID
         // NOTE: This should be configuration-based
         //
-        localBgpId = bgpSessionManager.getMyBgpId();
+        localInfo.setBgpId(bgpSessionManager.getMyBgpId());
     }
 
     @Override
@@ -706,6 +364,18 @@
      * @param ctx the Channel Handler Context to use
      */
     void restartKeepaliveTimer(ChannelHandlerContext ctx) {
+        long localKeepaliveInterval = 0;
+
+        //
+        // Compute the local Keepalive interval
+        //
+        if (localInfo.holdtime() != 0) {
+            localKeepaliveInterval = Math.max(localInfo.holdtime() /
+                         BgpConstants.BGP_KEEPALIVE_PER_HOLD_INTERVAL,
+                         BgpConstants.BGP_KEEPALIVE_MIN_INTERVAL);
+        }
+
+        // Restart the Keepalive timer
         if (localKeepaliveInterval == 0) {
             return;                 // Nothing to do
         }
@@ -753,14 +423,14 @@
      * @param ctx the Channel Handler Context to use
      */
     void restartSessionTimeoutTimer(ChannelHandlerContext ctx) {
-        if (remoteHoldtime == 0) {
+        if (remoteInfo.holdtime() == 0) {
             return;                 // Nothing to do
         }
         if (sessionTimeout != null) {
             sessionTimeout.cancel();
         }
         sessionTimeout = timer.newTimeout(new SessionTimeoutTask(ctx),
-                                          remoteHoldtime,
+                                          remoteInfo.holdtime(),
                                           TimeUnit.SECONDS);
     }
 
@@ -788,7 +458,7 @@
                 return;
             }
 
-            log.debug("BGP Session Timeout: peer {}", remoteAddress);
+            log.debug("BGP Session Timeout: peer {}", remoteInfo.address());
             //
             // ERROR: Invalid Optional Parameter Length field: Unspecific
             //
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSessionInfo.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSessionInfo.java
new file mode 100644
index 0000000..a492d80
--- /dev/null
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSessionInfo.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2015 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.net.SocketAddress;
+import org.onlab.packet.Ip4Address;
+
+/**
+ * Class for keeping information about a BGP session.
+ *
+ * There are two instances per each BGP peer session: one to keep the local
+ * information about the BGP session, and another to keep information about
+ * the remote BGP peer.
+ */
+public class BgpSessionInfo {
+    private SocketAddress address;              // IP addr/port
+    private Ip4Address ip4Address;              // IPv4 address
+    private int bgpVersion;                     // 1 octet
+    private long asNumber;                      // AS number: 2 octets
+    private long as4Number;                     // AS4 number: 4 octets
+    private long holdtime;                      // 2 octets
+    private Ip4Address bgpId;                   // 4 octets -> IPv4 address
+    private boolean mpExtensions;               // Multiprotocol Extensions
+                                                // enabled: RFC 4760
+    private boolean ipv4Unicast;                // IPv4/UNICAST AFI/SAFI
+    private boolean ipv4Multicast;              // IPv4/MULTICAST AFI/SAFI
+    private boolean ipv6Unicast;                // IPv6/UNICAST AFI/SAFI
+    private boolean ipv6Multicast;              // IPv6/MULTICAST AFI/SAFI
+    private boolean as4OctetCapability;         // AS 4 octet path capability
+
+    /**
+     * Gets the BGP session address: local or remote.
+     *
+     * @return the BGP session address
+     */
+    public SocketAddress address() {
+        return this.address;
+    }
+
+    /**
+     * Sets the BGP session address: local or remote.
+     *
+     * @param address the BGP session address to set
+     */
+    public void setAddress(SocketAddress address) {
+        this.address = address;
+    }
+
+    /**
+     * Gets the BGP session IPv4 address: local or remote.
+     *
+     * @return the BGP session IPv4 address
+     */
+    public Ip4Address ip4Address() {
+        return this.ip4Address;
+    }
+
+    /**
+     * Sets the BGP session IPv4 address: local or remote.
+     *
+     * @param ip4Address the BGP session IPv4 address to set
+     */
+    public void setIp4Address(Ip4Address ip4Address) {
+        this.ip4Address = ip4Address;
+    }
+
+    /**
+     * Gets the BGP session BGP version: local or remote.
+     *
+     * @return the BGP session BGP version
+     */
+    public int bgpVersion() {
+        return this.bgpVersion;
+    }
+
+    /**
+     * Sets the BGP session BGP version: local or remote.
+     *
+     * @param bgpVersion the BGP session BGP version to set
+     */
+    public void setBgpVersion(int bgpVersion) {
+        this.bgpVersion = bgpVersion;
+    }
+
+    /**
+     * Gets the BGP session AS number: local or remote.
+     *
+     * @return the BGP session AS number
+     */
+    public long asNumber() {
+        return this.asNumber;
+    }
+
+    /**
+     * Sets the BGP session AS number: local or remote.
+     *
+     * @param asNumber the BGP session AS number to set
+     */
+    public void setAsNumber(long asNumber) {
+        this.asNumber = asNumber;
+    }
+
+    /**
+     * Gets the BGP session AS4 number: local or remote.
+     *
+     * @return the BGP session AS4 number
+     */
+    public long as4Number() {
+        return this.as4Number;
+    }
+
+    /**
+     * Sets the BGP session AS4 number: local or remote.
+     *
+     * @param as4Number the BGP session AS4 number to set
+     */
+    public void setAs4Number(long as4Number) {
+        this.as4Number = as4Number;
+    }
+
+    /**
+     * Gets the BGP session holdtime: local or remote.
+     *
+     * @return the BGP session holdtime
+     */
+    public long holdtime() {
+        return this.holdtime;
+    }
+
+    /**
+     * Sets the BGP session holdtime: local or remote.
+     *
+     * @param holdtime the BGP session holdtime to set
+     */
+    public void setHoldtime(long holdtime) {
+        this.holdtime = holdtime;
+    }
+
+    /**
+     * Gets the BGP session BGP Identifier as an IPv4 address: local or remote.
+     *
+     * @return the BGP session BGP Identifier as an IPv4 address
+     */
+    public Ip4Address bgpId() {
+        return this.bgpId;
+    }
+
+    /**
+     * Sets the BGP session BGP Identifier as an IPv4 address: local or remote.
+     *
+     * @param bgpId the BGP session BGP Identifier to set
+     */
+    public void setBgpId(Ip4Address bgpId) {
+        this.bgpId = bgpId;
+    }
+
+    /**
+     * Gets the BGP Multiprotocol Extensions: local or remote.
+     *
+     * @return true if the BGP Multiprotocol Extensions are enabled, otherwise
+     * false
+     */
+    public boolean mpExtensions() {
+        return this.mpExtensions;
+    }
+
+    /**
+     * Gets the BGP session AFI/SAFI configuration for IPv4 unicast: local or
+     * remote.
+     *
+     * @return the BGP session AFI/SAFI configuration for IPv4 unicast
+     */
+    public boolean ipv4Unicast() {
+        return ipv4Unicast;
+    }
+
+    /**
+     * Sets the BGP session AFI/SAFI configuration for IPv4 unicast: local or
+     * remote.
+     */
+    public void setIpv4Unicast() {
+        this.mpExtensions = true;
+        this.ipv4Unicast = true;
+    }
+
+    /**
+     * Gets the BGP session AFI/SAFI configuration for IPv4 multicast: local or
+     * remote.
+     *
+     * @return the BGP session AFI/SAFI configuration for IPv4 multicast
+     */
+    public boolean ipv4Multicast() {
+        return ipv4Multicast;
+    }
+
+    /**
+     * Sets the BGP session AFI/SAFI configuration for IPv4 multicast: local or
+     * remote.
+     */
+    public void setIpv4Multicast() {
+        this.mpExtensions = true;
+        this.ipv4Multicast = true;
+    }
+
+    /**
+     * Gets the BGP session AFI/SAFI configuration for IPv6 unicast: local or
+     * remote.
+     *
+     * @return the BGP session AFI/SAFI configuration for IPv6 unicast
+     */
+    public boolean ipv6Unicast() {
+        return ipv6Unicast;
+    }
+
+    /**
+     * Sets the BGP session AFI/SAFI configuration for IPv6 unicast: local or
+     * remote.
+     */
+    void setIpv6Unicast() {
+        this.mpExtensions = true;
+        this.ipv6Unicast = true;
+    }
+
+    /**
+     * Gets the BGP session AFI/SAFI configuration for IPv6 multicast: local or
+     * remote.
+     *
+     * @return the BGP session AFI/SAFI configuration for IPv6 multicast
+     */
+    public boolean ipv6Multicast() {
+        return ipv6Multicast;
+    }
+
+    /**
+     * Sets the BGP session AFI/SAFI configuration for IPv6 multicast: local or
+     * remote.
+     */
+    public void setIpv6Multicast() {
+        this.mpExtensions = true;
+        this.ipv6Multicast = true;
+    }
+
+    /**
+     * Gets the BGP session 4 octet AS path capability: local or remote.
+     *
+     * @return true when the BGP session has 4 octet AS path capability
+     */
+    public boolean as4OctetCapability() {
+        return this.as4OctetCapability;
+    }
+
+    /**
+     * Sets the BGP session 4 octet AS path capability.
+     */
+    public void setAs4OctetCapability() {
+        this.as4OctetCapability = true;
+    }
+}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSessionManager.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSessionManager.java
index 557e9b6..2ca2972 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSessionManager.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSessionManager.java
@@ -189,18 +189,18 @@
     boolean peerConnected(BgpSession bgpSession) {
 
         // Test whether there is already a session from the same remote
-        if (bgpSessions.get(bgpSession.getRemoteAddress()) != null) {
+        if (bgpSessions.get(bgpSession.remoteInfo().address()) != null) {
             return false;               // Duplicate BGP session
         }
-        bgpSessions.put(bgpSession.getRemoteAddress(), bgpSession);
+        bgpSessions.put(bgpSession.remoteInfo().address(), bgpSession);
 
         //
         // If the first connection, set my BGP ID to the local address
         // of the socket.
         //
-        if (bgpSession.getLocalAddress() instanceof InetSocketAddress) {
+        if (bgpSession.localInfo().address() instanceof InetSocketAddress) {
             InetAddress inetAddr =
-                    ((InetSocketAddress) bgpSession.getLocalAddress()).getAddress();
+                ((InetSocketAddress) bgpSession.localInfo().address()).getAddress();
             Ip4Address ip4Address = Ip4Address.valueOf(inetAddr.getAddress());
             updateMyBgpId(ip4Address);
         }
@@ -213,7 +213,7 @@
      * @param bgpSession the BGP session for the peer
      */
     void peerDisconnected(BgpSession bgpSession) {
-        bgpSessions.remove(bgpSession.getRemoteAddress());
+        bgpSessions.remove(bgpSession.remoteInfo().address());
     }
 
     /**
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
index ddce3a7..2068324 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpUpdate.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpUpdate.java
@@ -68,8 +68,8 @@
         if (message.readableBytes() < minLength) {
             log.debug("BGP RX UPDATE Error from {}: " +
                       "Message length {} too short. Must be at least {}",
-                      bgpSession.getRemoteAddress(), message.readableBytes(),
-                      minLength);
+                      bgpSession.remoteInfo().address(),
+                      message.readableBytes(), minLength);
             //
             // ERROR: Bad Message Length
             //
@@ -83,7 +83,7 @@
         }
 
         log.debug("BGP RX UPDATE message from {}",
-                  bgpSession.getRemoteAddress());
+                  bgpSession.remoteInfo().address());
 
         //
         // Parse the UPDATE message
@@ -105,13 +105,13 @@
         } catch (BgpParseException e) {
             // ERROR: Invalid Network Field
             log.debug("Exception parsing Withdrawn Prefixes from BGP peer {}: ",
-                      bgpSession.getRemoteBgpId(), e);
+                      bgpSession.remoteInfo().bgpId(), e);
             actionsBgpUpdateInvalidNetworkField(bgpSession, ctx);
             return;
         }
         for (Ip4Prefix prefix : withdrawnPrefixes) {
             log.debug("BGP RX UPDATE message WITHDRAWN from {}: {}",
-                      bgpSession.getRemoteAddress(), prefix);
+                      bgpSession.remoteInfo().address(), prefix);
             BgpRouteEntry bgpRouteEntry = bgpSession.findBgpRoute(prefix);
             if (bgpRouteEntry != null) {
                 decodedBgpRoutes.deletedUnicastRoutes4.put(prefix,
@@ -126,7 +126,7 @@
             parsePathAttributes(bgpSession, ctx, message, decodedBgpRoutes);
         } catch (BgpParseException e) {
             log.debug("Exception parsing Path Attributes from BGP peer {}: ",
-                      bgpSession.getRemoteBgpId(), e);
+                      bgpSession.remoteInfo().bgpId(), e);
             // NOTE: The session was already closed, so nothing else to do
             return;
         }
@@ -366,7 +366,7 @@
                 // Skip the data from the unrecognized attribute
                 log.debug("BGP RX UPDATE message from {}: " +
                           "Unrecognized Attribute Type {}",
-                          bgpSession.getRemoteAddress(), attrTypeCode);
+                          bgpSession.remoteInfo().address(), attrTypeCode);
                 message.skipBytes(attrLen);
                 break;
             }
@@ -384,7 +384,7 @@
         } catch (BgpParseException e) {
             // ERROR: Invalid Network Field
             log.debug("Exception parsing NLRI from BGP peer {}: ",
-                      bgpSession.getRemoteBgpId(), e);
+                      bgpSession.remoteInfo().bgpId(), e);
             actionsBgpUpdateInvalidNetworkField(bgpSession, ctx);
             // Rethrow the exception
             throw e;
@@ -433,15 +433,15 @@
                     new BgpRouteEntry(bgpSession, prefix, mpNlri.nextHop4,
                                       origin.byteValue(), asPath, localPref);
                 bgpRouteEntry.setMultiExitDisc(multiExitDisc);
-                if (bgpRouteEntry.hasAsPathLoop(bgpSession.getLocalAs())) {
+                if (bgpRouteEntry.hasAsPathLoop(bgpSession.localInfo().asNumber())) {
                     log.debug("BGP RX UPDATE message IGNORED from {}: {} " +
                               "nextHop {}: contains AS Path loop",
-                              bgpSession.getRemoteAddress(), prefix,
+                              bgpSession.remoteInfo().address(), prefix,
                               mpNlri.nextHop4);
                     continue;
                 } else {
                     log.debug("BGP RX UPDATE message ADDED from {}: {} nextHop {}",
-                              bgpSession.getRemoteAddress(), prefix,
+                              bgpSession.remoteInfo().address(), prefix,
                               mpNlri.nextHop4);
                 }
                 // Remove from the collection of deleted routes
@@ -456,15 +456,15 @@
                     new BgpRouteEntry(bgpSession, prefix, mpNlri.nextHop6,
                                       origin.byteValue(), asPath, localPref);
                 bgpRouteEntry.setMultiExitDisc(multiExitDisc);
-                if (bgpRouteEntry.hasAsPathLoop(bgpSession.getLocalAs())) {
+                if (bgpRouteEntry.hasAsPathLoop(bgpSession.localInfo().asNumber())) {
                     log.debug("BGP RX UPDATE message IGNORED from {}: {} " +
                               "nextHop {}: contains AS Path loop",
-                              bgpSession.getRemoteAddress(), prefix,
+                              bgpSession.remoteInfo().address(), prefix,
                               mpNlri.nextHop6);
                     continue;
                 } else {
                     log.debug("BGP RX UPDATE message ADDED from {}: {} nextHop {}",
-                              bgpSession.getRemoteAddress(), prefix,
+                              bgpSession.remoteInfo().address(), prefix,
                               mpNlri.nextHop6);
                 }
                 // Remove from the collection of deleted routes
@@ -507,7 +507,7 @@
         // Multiprotocol Extensions are not enabled, even if the UPDATE
         // message doesn't contain the legacy NLRI (per RFC 4271).
         //
-        if (!bgpSession.getMpExtensions()) {
+        if (!bgpSession.mpExtensions()) {
             hasNlri = true;
             hasLegacyNlri = true;
         } else {
@@ -838,7 +838,7 @@
         // Here we check only (a), because (b) doesn't apply for us: all our
         // peers are iBGP.
         //
-        if (nextHopAddress.equals(bgpSession.getLocalIp4Address())) {
+        if (nextHopAddress.equals(bgpSession.localInfo().ip4Address())) {
             // ERROR: Invalid NEXT_HOP Attribute
             message.resetReaderIndex();
             actionsBgpUpdateInvalidNextHopAttribute(
@@ -1297,7 +1297,7 @@
                                 BgpSession bgpSession,
                                 ChannelHandlerContext ctx) {
         log.debug("BGP RX UPDATE Error from {}: Invalid Network Field",
-                  bgpSession.getRemoteAddress());
+                  bgpSession.remoteInfo().address());
 
         //
         // ERROR: Invalid Network Field
@@ -1323,7 +1323,7 @@
                                 BgpSession bgpSession,
                                 ChannelHandlerContext ctx) {
         log.debug("BGP RX UPDATE Error from {}: Malformed Attribute List",
-                  bgpSession.getRemoteAddress());
+                  bgpSession.remoteInfo().address());
 
         //
         // ERROR: Malformed Attribute List
@@ -1352,7 +1352,7 @@
                                 ChannelHandlerContext ctx,
                                 int missingAttrTypeCode) {
         log.debug("BGP RX UPDATE Error from {}: Missing Well-known Attribute: {}",
-                  bgpSession.getRemoteAddress(), missingAttrTypeCode);
+                  bgpSession.remoteInfo().address(), missingAttrTypeCode);
 
         //
         // ERROR: Missing Well-known Attribute
@@ -1390,7 +1390,7 @@
                                 ChannelBuffer message,
                                 short origin) {
         log.debug("BGP RX UPDATE Error from {}: Invalid ORIGIN Attribute",
-                  bgpSession.getRemoteAddress());
+                  bgpSession.remoteInfo().address());
 
         //
         // ERROR: Invalid ORIGIN Attribute
@@ -1427,7 +1427,7 @@
                                 int attrFlags,
                                 ChannelBuffer message) {
         log.debug("BGP RX UPDATE Error from {}: Attribute Flags Error",
-                  bgpSession.getRemoteAddress());
+                  bgpSession.remoteInfo().address());
 
         //
         // ERROR: Attribute Flags Error
@@ -1467,7 +1467,7 @@
                                 ChannelBuffer message,
                                 Ip4Address nextHop) {
         log.debug("BGP RX UPDATE Error from {}: Invalid NEXT_HOP Attribute {}",
-                  bgpSession.getRemoteAddress(), nextHop);
+                  bgpSession.remoteInfo().address(), nextHop);
 
         //
         // ERROR: Invalid NEXT_HOP Attribute
@@ -1506,7 +1506,7 @@
                                 ChannelBuffer message) {
         log.debug("BGP RX UPDATE Error from {}: " +
                   "Unrecognized Well-known Attribute Error: {}",
-                  bgpSession.getRemoteAddress(), attrTypeCode);
+                  bgpSession.remoteInfo().address(), attrTypeCode);
 
         //
         // ERROR: Unrecognized Well-known Attribute
@@ -1545,7 +1545,7 @@
                                 int attrFlags,
                                 ChannelBuffer message) {
         log.debug("BGP RX UPDATE Error from {}: Optional Attribute Error: {}",
-                  bgpSession.getRemoteAddress(), attrTypeCode);
+                  bgpSession.remoteInfo().address(), attrTypeCode);
 
         //
         // ERROR: Optional Attribute Error
@@ -1583,7 +1583,7 @@
                                 int attrFlags,
                                 ChannelBuffer message) {
         log.debug("BGP RX UPDATE Error from {}: Attribute Length Error",
-                  bgpSession.getRemoteAddress());
+                  bgpSession.remoteInfo().address());
 
         //
         // ERROR: Attribute Length Error
@@ -1612,7 +1612,7 @@
                                 BgpSession bgpSession,
                                 ChannelHandlerContext ctx) {
         log.debug("BGP RX UPDATE Error from {}: Malformed AS Path",
-                  bgpSession.getRemoteAddress());
+                  bgpSession.remoteInfo().address());
 
         //
         // ERROR: Malformed AS_PATH
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/BgpNeighborsListCommand.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/BgpNeighborsListCommand.java
index 7fc5278..fe2a4a4 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/BgpNeighborsListCommand.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/BgpNeighborsListCommand.java
@@ -60,7 +60,7 @@
             // Print a single neighbor (if found)
             BgpSession foundBgpSession = null;
             for (BgpSession bgpSession : bgpSessions) {
-                if (bgpSession.getRemoteBgpId().toString().equals(bgpNeighbor)) {
+                if (bgpSession.remoteInfo().bgpId().toString().equals(bgpNeighbor)) {
                     foundBgpSession = bgpSession;
                     break;
                 }
@@ -99,33 +99,34 @@
      */
     private void printNeighbor(BgpSession bgpSession) {
         print(FORMAT_NEIGHBOR_LINE1,
-              bgpSession.getRemoteBgpId().toString(),
-              bgpSession.getRemoteAs(),
-              bgpSession.getLocalAs());
+              bgpSession.remoteInfo().bgpId().toString(),
+              bgpSession.remoteInfo().asNumber(),
+              bgpSession.localInfo().asNumber());
         print(FORMAT_NEIGHBOR_LINE2,
-              bgpSession.getRemoteBgpId().toString(),
-              bgpSession.getRemoteAddress().toString(),
-              bgpSession.getRemoteBgpVersion(),
-              bgpSession.getRemoteHoldtime());
+              bgpSession.remoteInfo().bgpId().toString(),
+              bgpSession.remoteInfo().address().toString(),
+              bgpSession.remoteInfo().bgpVersion(),
+              bgpSession.remoteInfo().holdtime());
         print(FORMAT_NEIGHBOR_LINE3,
-              bgpSession.getRemoteIpv4Unicast() ? "YES" : "NO",
-              bgpSession.getRemoteIpv4Multicast() ? "YES" : "NO",
-              bgpSession.getRemoteIpv6Unicast() ? "YES" : "NO",
-              bgpSession.getRemoteIpv6Multicast() ? "YES" : "NO");
+              bgpSession.remoteInfo().ipv4Unicast() ? "YES" : "NO",
+              bgpSession.remoteInfo().ipv4Multicast() ? "YES" : "NO",
+              bgpSession.remoteInfo().ipv6Unicast() ? "YES" : "NO",
+              bgpSession.remoteInfo().ipv6Multicast() ? "YES" : "NO");
         print(FORMAT_NEIGHBOR_LINE4,
-              bgpSession.getLocalBgpId().toString(),
-              bgpSession.getLocalAddress().toString(),
-              bgpSession.getLocalBgpVersion(),
-              bgpSession.getLocalHoldtime());
+              bgpSession.localInfo().bgpId().toString(),
+              bgpSession.localInfo().address().toString(),
+              bgpSession.localInfo().bgpVersion(),
+              bgpSession.localInfo().holdtime());
         print(FORMAT_NEIGHBOR_LINE5,
-              bgpSession.getLocalIpv4Unicast() ? "YES" : "NO",
-              bgpSession.getLocalIpv4Multicast() ? "YES" : "NO",
-              bgpSession.getLocalIpv6Unicast() ? "YES" : "NO",
-              bgpSession.getLocalIpv6Multicast() ? "YES" : "NO");
-        if (bgpSession.getLocalAs4OctetCapability() || bgpSession.getRemoteAs4OctetCapability()) {
+              bgpSession.localInfo().ipv4Unicast() ? "YES" : "NO",
+              bgpSession.localInfo().ipv4Multicast() ? "YES" : "NO",
+              bgpSession.localInfo().ipv6Unicast() ? "YES" : "NO",
+              bgpSession.localInfo().ipv6Multicast() ? "YES" : "NO");
+        if (bgpSession.localInfo().as4OctetCapability() ||
+            bgpSession.remoteInfo().as4OctetCapability()) {
             print(FORMAT_NEIGHBOR_LINE6,
-                  bgpSession.getLocalAs4OctetCapability() ? "Advertised" : "",
-                  bgpSession.getRemoteAs4OctetCapability() ? "Received" : "");
+                  bgpSession.localInfo().as4OctetCapability() ? "Advertised" : "",
+                  bgpSession.remoteInfo().as4OctetCapability() ? "Received" : "");
         }
     }
 
@@ -155,25 +156,27 @@
     private ObjectNode json(ObjectMapper mapper, BgpSession bgpSession) {
         ObjectNode result = mapper.createObjectNode();
 
-        result.put("remoteAddress", bgpSession.getRemoteAddress().toString());
-        result.put("remoteBgpVersion", bgpSession.getRemoteBgpVersion());
-        result.put("remoteAs", bgpSession.getRemoteAs());
-        result.put("remoteHoldtime", bgpSession.getRemoteHoldtime());
-        result.put("remoteBgpId", bgpSession.getRemoteBgpId().toString());
-        result.put("remoteIpv4Unicast", bgpSession.getRemoteIpv4Unicast());
-        result.put("remoteIpv4Multicast", bgpSession.getRemoteIpv4Multicast());
-        result.put("remoteIpv6Unicast", bgpSession.getRemoteIpv6Unicast());
-        result.put("remoteIpv6Multicast", bgpSession.getRemoteIpv6Multicast());
+        result.put("remoteAddress", bgpSession.remoteInfo().address().toString());
+        result.put("remoteBgpVersion", bgpSession.remoteInfo().bgpVersion());
+        result.put("remoteAs", bgpSession.remoteInfo().asNumber());
+        result.put("remoteAs4", bgpSession.remoteInfo().as4Number());
+        result.put("remoteHoldtime", bgpSession.remoteInfo().holdtime());
+        result.put("remoteBgpId", bgpSession.remoteInfo().bgpId().toString());
+        result.put("remoteIpv4Unicast", bgpSession.remoteInfo().ipv4Unicast());
+        result.put("remoteIpv4Multicast", bgpSession.remoteInfo().ipv4Multicast());
+        result.put("remoteIpv6Unicast", bgpSession.remoteInfo().ipv6Unicast());
+        result.put("remoteIpv6Multicast", bgpSession.remoteInfo().ipv6Multicast());
         //
-        result.put("localAddress", bgpSession.getLocalAddress().toString());
-        result.put("localBgpVersion", bgpSession.getLocalBgpVersion());
-        result.put("localAs", bgpSession.getLocalAs());
-        result.put("localHoldtime", bgpSession.getLocalHoldtime());
-        result.put("localBgpId", bgpSession.getLocalBgpId().toString());
-        result.put("localIpv4Unicast", bgpSession.getLocalIpv4Unicast());
-        result.put("localIpv4Multicast", bgpSession.getLocalIpv4Multicast());
-        result.put("localIpv6Unicast", bgpSession.getLocalIpv6Unicast());
-        result.put("localIpv6Multicast", bgpSession.getLocalIpv6Multicast());
+        result.put("localAddress", bgpSession.localInfo().address().toString());
+        result.put("localBgpVersion", bgpSession.localInfo().bgpVersion());
+        result.put("localAs", bgpSession.localInfo().asNumber());
+        result.put("localAs4", bgpSession.localInfo().as4Number());
+        result.put("localHoldtime", bgpSession.localInfo().holdtime());
+        result.put("localBgpId", bgpSession.localInfo().bgpId().toString());
+        result.put("localIpv4Unicast", bgpSession.localInfo().ipv4Unicast());
+        result.put("localIpv4Multicast", bgpSession.localInfo().ipv4Multicast());
+        result.put("localIpv6Unicast", bgpSession.localInfo().ipv6Unicast());
+        result.put("localIpv6Multicast", bgpSession.localInfo().ipv6Multicast());
 
         return result;
     }
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 037c985..a3b19df 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
@@ -71,7 +71,7 @@
         if (bgpNeighbor != null) {
             // Print the routes from a single neighbor (if found)
             for (BgpSession bgpSession : service.getBgpSessions()) {
-                if (bgpSession.getRemoteBgpId().toString().equals(bgpNeighbor)) {
+                if (bgpSession.remoteInfo().bgpId().toString().equals(bgpNeighbor)) {
                     foundBgpSession = bgpSession;
                     break;
                 }
@@ -152,7 +152,7 @@
             print(FORMAT_ROUTE_LINE1, route.prefix(), route.nextHop(),
                   Update.Origin.typeToString(route.getOrigin()),
                   route.getLocalPref(), route.getMultiExitDisc(),
-                  route.getBgpSession().getRemoteBgpId());
+                  route.getBgpSession().remoteInfo().bgpId());
             print(FORMAT_ROUTE_LINE2, asPath4Cli(route.getAsPath()));
         }
     }
@@ -245,7 +245,8 @@
 
         result.put("prefix", route.prefix().toString());
         result.put("nextHop", route.nextHop().toString());
-        result.put("bgpId", route.getBgpSession().getRemoteBgpId().toString());
+        result.put("bgpId",
+                   route.getBgpSession().remoteInfo().bgpId().toString());
         result.put("origin", Update.Origin.typeToString(route.getOrigin()));
         result.put("asPath", json(mapper, route.getAsPath()));
         result.put("localPref", route.getLocalPref());
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpRouteEntryTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpRouteEntryTest.java
index e54e506..d53eb59 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpRouteEntryTest.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpRouteEntryTest.java
@@ -51,6 +51,15 @@
     private static final Ip4Address BGP_SESSION_IP_ADDRESS3 =
         Ip4Address.valueOf("20.0.0.2");
 
+    private final BgpSessionInfo localInfo = new BgpSessionInfo();
+    private final BgpSessionInfo remoteInfo = new BgpSessionInfo();
+
+    private final BgpSessionInfo localInfo2 = new BgpSessionInfo();
+    private final BgpSessionInfo remoteInfo2 = new BgpSessionInfo();
+
+    private final BgpSessionInfo localInfo3 = new BgpSessionInfo();
+    private final BgpSessionInfo remoteInfo3 = new BgpSessionInfo();
+
     @Before
     public void setUp() throws Exception {
         // Mock objects for testing
@@ -59,20 +68,19 @@
         bgpSession3 = createMock(BgpSession.class);
 
         // Setup the BGP Sessions
-        expect(bgpSession.getRemoteBgpId())
-            .andReturn(BGP_SESSION_BGP_ID).anyTimes();
-        expect(bgpSession.getRemoteIp4Address())
-            .andReturn(BGP_SESSION_IP_ADDRESS).anyTimes();
-        //
-        expect(bgpSession2.getRemoteBgpId())
-            .andReturn(BGP_SESSION_BGP_ID2).anyTimes();
-        expect(bgpSession2.getRemoteIp4Address())
-            .andReturn(BGP_SESSION_IP_ADDRESS2).anyTimes();
-        //
-        expect(bgpSession3.getRemoteBgpId())
-            .andReturn(BGP_SESSION_BGP_ID3).anyTimes();
-        expect(bgpSession3.getRemoteIp4Address())
-            .andReturn(BGP_SESSION_IP_ADDRESS3).anyTimes();
+        remoteInfo.setIp4Address(BGP_SESSION_IP_ADDRESS);
+        remoteInfo2.setIp4Address(BGP_SESSION_IP_ADDRESS2);
+        remoteInfo3.setIp4Address(BGP_SESSION_IP_ADDRESS3);
+        remoteInfo.setBgpId(BGP_SESSION_BGP_ID);
+        remoteInfo2.setBgpId(BGP_SESSION_BGP_ID2);
+        remoteInfo3.setBgpId(BGP_SESSION_BGP_ID3);
+
+        expect(bgpSession.localInfo()).andReturn(localInfo).anyTimes();
+        expect(bgpSession.remoteInfo()).andReturn(remoteInfo).anyTimes();
+        expect(bgpSession2.localInfo()).andReturn(localInfo2).anyTimes();
+        expect(bgpSession2.remoteInfo()).andReturn(remoteInfo2).anyTimes();
+        expect(bgpSession3.localInfo()).andReturn(localInfo3).anyTimes();
+        expect(bgpSession3.remoteInfo()).andReturn(remoteInfo3).anyTimes();
 
         replay(bgpSession);
         replay(bgpSession2);
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 096605a..11a8b5e 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
@@ -179,13 +179,13 @@
             assertThat(result, is(true));
 
             for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
-                if (bgpSession.getRemoteBgpId().equals(BGP_PEER1_ID)) {
+                if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER1_ID)) {
                     bgpSession1 = bgpSession;
                 }
-                if (bgpSession.getRemoteBgpId().equals(BGP_PEER2_ID)) {
+                if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER2_ID)) {
                     bgpSession2 = bgpSession;
                 }
-                if (bgpSession.getRemoteBgpId().equals(BGP_PEER3_ID)) {
+                if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER3_ID)) {
                     bgpSession3 = bgpSession;
                 }
             }
@@ -394,7 +394,7 @@
         assertThat(bgpSession2, notNullValue());
         assertThat(bgpSession3, notNullValue());
         for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
-            long sessionAs = TestUtils.getField(bgpSession, "localAs");
+            long sessionAs = bgpSession.localInfo().asNumber();
             assertThat(sessionAs, is(TestBgpPeerChannelHandler.PEER_AS));
         }
     }
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/TestBgpPeerChannelHandler.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/TestBgpPeerChannelHandler.java
index 6b933c9..05fb5b4 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/TestBgpPeerChannelHandler.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/TestBgpPeerChannelHandler.java
@@ -59,7 +59,7 @@
         ctx.getChannel().write(message);
 
         // Prepare and transmit BGP KEEPALIVE message
-        message = prepareBgpKeepalive();
+        message = BgpKeepalive.prepareBgpKeepalive();
         ctx.getChannel().write(message);
     }
 
@@ -82,7 +82,8 @@
         message.writeShort(PEER_HOLDTIME);
         message.writeInt(bgpId.toInt());
         message.writeByte(0);                   // No Optional Parameters
-        return prepareBgpMessage(BgpConstants.BGP_TYPE_OPEN, message);
+        return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_OPEN,
+                                            message);
     }
 
     /**
@@ -155,7 +156,8 @@
         message.writeBytes(pathAttributes);
         message.writeBytes(encodedPrefixes);
 
-        return prepareBgpMessage(BgpConstants.BGP_TYPE_UPDATE, message);
+        return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_UPDATE,
+                                            message);
     }
 
     /**
@@ -214,64 +216,4 @@
 
         return message;
     }
-
-    /**
-     * Prepares BGP KEEPALIVE message.
-     *
-     * @return the message to transmit (BGP header included)
-     */
-    ChannelBuffer prepareBgpKeepalive() {
-        ChannelBuffer message =
-            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
-        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 payload 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 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;
-    }
 }