diff --git a/apps/sdnip/pom.xml b/apps/sdnip/pom.xml
index 920b5e5..925bc58 100644
--- a/apps/sdnip/pom.xml
+++ b/apps/sdnip/pom.xml
@@ -61,11 +61,6 @@
 
     <dependency>
       <groupId>org.onosproject</groupId>
-      <artifactId>onlab-thirdparty</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>org.onosproject</groupId>
       <artifactId>onlab-misc</artifactId>
     </dependency>
 
@@ -85,13 +80,13 @@
 
     <dependency>
       <groupId>org.onosproject</groupId>
-      <artifactId>onos-cli</artifactId>
+      <artifactId>onos-app-routing-api</artifactId>
       <version>${project.version}</version>
     </dependency>
 
     <dependency>
       <groupId>org.onosproject</groupId>
-      <artifactId>onos-core-dist</artifactId>
+      <artifactId>onos-cli</artifactId>
       <version>${project.version}</version>
     </dependency>
 
@@ -107,11 +102,6 @@
     </dependency>
 
     <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-    </dependency>
-
-    <dependency>
       <groupId>org.easymock</groupId>
       <artifactId>easymock</artifactId>
       <scope>test</scope>
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/FibEntry.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/FibEntry.java
deleted file mode 100644
index 988b49a..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/FibEntry.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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;
-
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
-
-/**
- * An entry in the Forwarding Information Base (FIB).
- */
-public class FibEntry {
-
-    private final IpPrefix prefix;
-    private final IpAddress nextHopIp;
-    private final MacAddress nextHopMac;
-
-    /**
-     * Creates a new FIB entry.
-     *
-     * @param prefix IP prefix of the FIB entry
-     * @param nextHopIp IP address of the next hop
-     * @param nextHopMac MAC address of the next hop
-     */
-    public FibEntry(IpPrefix prefix, IpAddress nextHopIp, MacAddress nextHopMac) {
-        this.prefix = prefix;
-        this.nextHopIp = nextHopIp;
-        this.nextHopMac = nextHopMac;
-    }
-
-    /**
-     * Returns the IP prefix of the FIB entry.
-     *
-     * @return the IP prefix
-     */
-    public IpPrefix prefix() {
-        return prefix;
-    }
-
-    /**
-     * Returns the IP address of the next hop.
-     *
-     * @return the IP address
-     */
-    public IpAddress nextHopIp() {
-        return nextHopIp;
-    }
-
-    /**
-     * Returns the MAC address of the next hop.
-     *
-     * @return the MAC address
-     */
-    public MacAddress nextHopMac() {
-        return nextHopMac;
-    }
-}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/FibListener.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/FibListener.java
deleted file mode 100644
index 13674e3..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/FibListener.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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;
-
-import java.util.Collection;
-
-/**
- * A component that is able to process Forwarding Information Base (FIB) updates.
- */
-public interface FibListener {
-
-    /**
-     * Signals the FIB component of changes to the FIB.
-     *
-     * @param updates FIB updates of the UDPATE type
-     * @param withdraws FIB updates of the WITHDRAW type
-     */
-    // TODO this interface should use only one collection when we have the new
-    // intent key API
-    void update(Collection<FibUpdate> updates, Collection<FibUpdate> withdraws);
-
-}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/FibUpdate.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/FibUpdate.java
deleted file mode 100644
index a3d8c3c..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/FibUpdate.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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;
-
-/**
- * Represents a change to the Forwarding Information Base (FIB).
- */
-public class FibUpdate {
-
-    /**
-     * Specifies the type of the FIB update.
-     */
-    public enum Type {
-        /**
-         * The update contains a new or updated FIB entry for a prefix.
-         */
-        UPDATE,
-
-        /**
-         * The update signals that a prefix should be removed from the FIB.
-         */
-        DELETE
-    }
-
-    private final Type type;
-    private final FibEntry entry;
-
-    /**
-     * Creates a new FIB update.
-     *
-     * @param type type of the update
-     * @param entry FIB entry describing the update
-     */
-    public FibUpdate(Type type, FibEntry entry) {
-        this.type = type;
-        this.entry = entry;
-    }
-
-    /**
-     * Returns the type of the update.
-     *
-     * @return update type
-     */
-    public Type type() {
-        return type;
-    }
-
-    /**
-     * Returns the FIB entry which contains update information.
-     *
-     * @return the FIB entry
-     */
-    public FibEntry entry() {
-        return entry;
-    }
-}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
index 9f3c872..698a2d6 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
@@ -36,6 +36,8 @@
 import org.onosproject.net.intent.IntentState;
 import org.onosproject.net.intent.MultiPointToSinglePointIntent;
 import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.routingapi.FibListener;
+import org.onosproject.routingapi.FibUpdate;
 import org.onosproject.sdnip.config.BgpPeer;
 import org.onosproject.sdnip.config.Interface;
 import org.onosproject.sdnip.config.SdnIpConfigurationService;
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
index 59ff346..93b442d 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
@@ -15,15 +15,11 @@
  */
 package org.onosproject.sdnip;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.IPv4;
 import org.onlab.packet.IPv6;
-import org.onlab.packet.IpAddress;
 import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
 import org.onlab.packet.IpPrefix;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.ConnectPoint;
@@ -32,7 +28,6 @@
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.intent.PointToPointIntent;
-import org.onosproject.sdnip.bgp.BgpConstants;
 import org.onosproject.sdnip.config.BgpPeer;
 import org.onosproject.sdnip.config.BgpSpeaker;
 import org.onosproject.sdnip.config.Interface;
@@ -41,6 +36,10 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
 /**
  * Manages the connectivity requirements between peers.
  */
@@ -49,6 +48,8 @@
     private static final Logger log = LoggerFactory.getLogger(
             PeerConnectivityManager.class);
 
+    private static final short BGP_PORT = 179;
+
     private final IntentSynchronizer intentSynchronizer;
     private final SdnIpConfigurationService configService;
     private final InterfaceService interfaceService;
@@ -191,7 +192,7 @@
                                  bgpdAddress,
                                  bgpdPeerAddress,
                                  null,
-                                 (short) BgpConstants.BGP_PORT);
+                                 BGP_PORT);
 
         intents.add(new PointToPointIntent(appId, selector, treatment,
                                bgpdConnectPoint, bgpdPeerConnectPoint));
@@ -200,7 +201,7 @@
         selector = buildSelector(tcpProtocol,
                                  bgpdAddress,
                                  bgpdPeerAddress,
-                                 (short) BgpConstants.BGP_PORT,
+                                 BGP_PORT,
                                  null);
 
         intents.add(new PointToPointIntent(appId, selector, treatment,
@@ -211,7 +212,7 @@
                                  bgpdPeerAddress,
                                  bgpdAddress,
                                  null,
-                                 (short) BgpConstants.BGP_PORT);
+                                 BGP_PORT);
 
         intents.add(new PointToPointIntent(appId, selector, treatment,
                                bgpdPeerConnectPoint, bgpdConnectPoint));
@@ -220,7 +221,7 @@
         selector = buildSelector(tcpProtocol,
                                  bgpdPeerAddress,
                                  bgpdAddress,
-                                 (short) BgpConstants.BGP_PORT,
+                                 BGP_PORT,
                                  null);
 
         intents.add(new PointToPointIntent(appId, selector, treatment,
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/RouteEntry.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/RouteEntry.java
deleted file mode 100644
index 3cffb7e..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/RouteEntry.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Objects;
-
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Represents a route entry for an IP prefix.
- */
-public class RouteEntry {
-    private final IpPrefix prefix;              // The IP prefix
-    private final IpAddress nextHop;            // Next-hop IP address
-
-    /**
-     * Class constructor.
-     *
-     * @param prefix the IP prefix of the route
-     * @param nextHop the next hop IP address for the route
-     */
-    public RouteEntry(IpPrefix prefix, IpAddress nextHop) {
-        this.prefix = checkNotNull(prefix);
-        this.nextHop = checkNotNull(nextHop);
-    }
-
-    /**
-     * Returns the IP version of the route.
-     *
-     * @return the IP version of the route
-     */
-    public IpAddress.Version version() {
-        return nextHop.version();
-    }
-
-    /**
-     * Returns the IP prefix of the route.
-     *
-     * @return the IP prefix of the route
-     */
-    public IpPrefix prefix() {
-        return prefix;
-    }
-
-    /**
-     * Returns the next hop IP address for the route.
-     *
-     * @return the next hop IP address for the route
-     */
-    public IpAddress nextHop() {
-        return nextHop;
-    }
-
-    /**
-     * Creates the binary string representation of an IP prefix.
-     * The prefix can be either IPv4 or IPv6.
-     * The string length is equal to the prefix length.
-     *
-     * @param ipPrefix the IP prefix to use
-     * @return the binary string representation
-     */
-    static String createBinaryString(IpPrefix ipPrefix) {
-        if (ipPrefix.prefixLength() == 0) {
-            return "";
-        }
-
-        byte[] octets = ipPrefix.address().toOctets();
-        StringBuilder result = new StringBuilder(ipPrefix.prefixLength());
-        for (int i = 0; i < ipPrefix.prefixLength(); i++) {
-            int byteOffset = i / Byte.SIZE;
-            int bitOffset = i % Byte.SIZE;
-            int mask = 1 << (Byte.SIZE - 1 - bitOffset);
-            byte value = octets[byteOffset];
-            boolean isSet = ((value & mask) != 0);
-            result.append(isSet ? "1" : "0");
-        }
-        return result.toString();
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        }
-
-        //
-        // NOTE: Subclasses are considered as change of identity, hence
-        // equals() will return false if the class type doesn't match.
-        //
-        if (other == null || getClass() != other.getClass()) {
-            return false;
-        }
-
-        RouteEntry otherRoute = (RouteEntry) other;
-        return Objects.equals(this.prefix, otherRoute.prefix) &&
-            Objects.equals(this.nextHop, otherRoute.nextHop);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(prefix, nextHop);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass())
-            .add("prefix", prefix)
-            .add("nextHop", nextHop)
-            .toString();
-    }
-}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/RouteListener.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/RouteListener.java
deleted file mode 100644
index 2d9ddc9..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/RouteListener.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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;
-
-import java.util.Collection;
-
-/**
- * An interface to receive route updates from route providers.
- */
-public interface RouteListener {
-    /**
-     * Receives a route update from a route provider.
-     *
-     * @param routeUpdates the collection with updated route information
-     */
-    public void update(Collection<RouteUpdate> routeUpdates);
-}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/RouteUpdate.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/RouteUpdate.java
deleted file mode 100644
index f63f214..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/RouteUpdate.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Objects;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Represents a change in routing information.
- */
-public class RouteUpdate {
-    private final Type type;                    // The route update type
-    private final RouteEntry routeEntry;        // The updated route entry
-
-    /**
-     * Specifies the type of a route update.
-     * <p>
-     * Route updates can either provide updated information for a route, or
-     * withdraw a previously updated route.
-     * </p>
-     */
-    public enum Type {
-        /**
-         * The update contains updated route information for a route.
-         */
-        UPDATE,
-        /**
-         * The update withdraws the route, meaning any previous information is
-         * no longer valid.
-         */
-        DELETE
-    }
-
-    /**
-     * Class constructor.
-     *
-     * @param type the type of the route update
-     * @param routeEntry the route entry with the update
-     */
-    public RouteUpdate(Type type, RouteEntry routeEntry) {
-        this.type = type;
-        this.routeEntry = checkNotNull(routeEntry);
-    }
-
-    /**
-     * Returns the type of the route update.
-     *
-     * @return the type of the update
-     */
-    public Type type() {
-        return type;
-    }
-
-    /**
-     * Returns the route entry the route update is for.
-     *
-     * @return the route entry the route update is for
-     */
-    public RouteEntry routeEntry() {
-        return routeEntry;
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (other == this) {
-            return true;
-        }
-
-        if (!(other instanceof RouteUpdate)) {
-            return false;
-        }
-
-        RouteUpdate otherUpdate = (RouteUpdate) other;
-
-        return Objects.equals(this.type, otherUpdate.type) &&
-            Objects.equals(this.routeEntry, otherUpdate.routeEntry);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(type, routeEntry);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass())
-            .add("type", type)
-            .add("routeEntry", routeEntry)
-            .toString();
-    }
-}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/Router.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/Router.java
deleted file mode 100644
index d19f298..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/Router.java
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * 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;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.SetMultimap;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import com.googlecode.concurrenttrees.common.KeyValuePair;
-import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory;
-import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree;
-import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
-import org.onosproject.net.Host;
-import org.onosproject.net.host.HostEvent;
-import org.onosproject.net.host.HostListener;
-import org.onosproject.net.host.HostService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.LinkedBlockingQueue;
-
-/**
- * This class processes route updates and maintains a Routing Information Base
- * (RIB). After route updates have been processed and next hops have been
- * resolved, FIB updates are sent to any listening FIB components.
- */
-public class Router implements RouteListener {
-
-    private static final Logger log = LoggerFactory.getLogger(Router.class);
-
-    // Route entries are stored in a radix tree.
-    // The key in this tree is the binary string of prefix of the route.
-    private InvertedRadixTree<RouteEntry> ribTable4;
-    private InvertedRadixTree<RouteEntry> ribTable6;
-
-    // Stores all incoming route updates in a queue.
-    private final BlockingQueue<Collection<RouteUpdate>> routeUpdatesQueue;
-
-    // Next-hop IP address to route entry mapping for next hops pending MAC resolution
-    private final SetMultimap<IpAddress, RouteEntry> routesWaitingOnArp;
-
-    // The IPv4 address to MAC address mapping
-    private final Map<IpAddress, MacAddress> ip2Mac;
-
-    private final FibListener fibComponent;
-    private final HostService hostService;
-    private final ExecutorService bgpUpdatesExecutor;
-    private final HostListener hostListener;
-
-    /**
-     * Class constructor.
-     *
-     * @param fibComponent the intent synchronizer
-     * @param hostService       the host service
-     */
-    public Router(FibListener fibComponent, HostService hostService) {
-        // TODO move to a listener model for adding fib listeners
-        this.fibComponent = fibComponent;
-        this.hostService = hostService;
-
-        this.hostListener = new InternalHostListener();
-
-        ribTable4 = new ConcurrentInvertedRadixTree<>(
-                new DefaultByteArrayNodeFactory());
-        ribTable6 = new ConcurrentInvertedRadixTree<>(
-                new DefaultByteArrayNodeFactory());
-        routeUpdatesQueue = new LinkedBlockingQueue<>();
-        routesWaitingOnArp = Multimaps.synchronizedSetMultimap(
-                HashMultimap.<IpAddress, RouteEntry>create());
-        ip2Mac = new ConcurrentHashMap<>();
-
-        bgpUpdatesExecutor = Executors.newSingleThreadExecutor(
-                new ThreadFactoryBuilder()
-                .setNameFormat("sdnip-bgp-updates-%d").build());
-    }
-
-    /**
-     * Starts the router.
-     */
-    public void start() {
-        this.hostService.addListener(hostListener);
-
-        bgpUpdatesExecutor.execute(new Runnable() {
-            @Override
-            public void run() {
-                doUpdatesThread();
-            }
-        });
-    }
-
-    /**
-     * Stops the router.
-     */
-    public void stop() {
-        this.hostService.removeListener(hostListener);
-
-        // Stop the thread(s)
-        bgpUpdatesExecutor.shutdownNow();
-
-        synchronized (this) {
-            // Cleanup all local state
-            ribTable4 = new ConcurrentInvertedRadixTree<>(
-                new DefaultByteArrayNodeFactory());
-            ribTable6 = new ConcurrentInvertedRadixTree<>(
-                new DefaultByteArrayNodeFactory());
-            routeUpdatesQueue.clear();
-            routesWaitingOnArp.clear();
-            ip2Mac.clear();
-        }
-    }
-
-    @Override
-    public void update(Collection<RouteUpdate> routeUpdates) {
-        try {
-            routeUpdatesQueue.put(routeUpdates);
-        } catch (InterruptedException e) {
-            log.debug("Interrupted while putting on routeUpdatesQueue", e);
-            Thread.currentThread().interrupt();
-        }
-    }
-
-    /**
-     * Thread for handling route updates.
-     */
-    private void doUpdatesThread() {
-        boolean interrupted = false;
-        try {
-            while (!interrupted) {
-                try {
-                    Collection<RouteUpdate> routeUpdates =
-                        routeUpdatesQueue.take();
-                    processRouteUpdates(routeUpdates);
-                } catch (InterruptedException e) {
-                    log.debug("Interrupted while taking from updates queue", e);
-                    interrupted = true;
-                } catch (Exception e) {
-                    log.debug("exception", e);
-                }
-            }
-        } finally {
-            if (interrupted) {
-                Thread.currentThread().interrupt();
-            }
-        }
-    }
-
-    /**
-     * Gets all IPv4 routes from the RIB.
-     *
-     * @return all IPv4 routes from the RIB
-     */
-    public Collection<RouteEntry> getRoutes4() {
-        Iterator<KeyValuePair<RouteEntry>> it =
-            ribTable4.getKeyValuePairsForKeysStartingWith("").iterator();
-
-        List<RouteEntry> routes = new LinkedList<>();
-
-        while (it.hasNext()) {
-            KeyValuePair<RouteEntry> entry = it.next();
-            routes.add(entry.getValue());
-        }
-
-        return routes;
-    }
-
-    /**
-     * Gets all IPv6 routes from the RIB.
-     *
-     * @return all IPv6 routes from the RIB
-     */
-    public Collection<RouteEntry> getRoutes6() {
-        Iterator<KeyValuePair<RouteEntry>> it =
-            ribTable6.getKeyValuePairsForKeysStartingWith("").iterator();
-
-        List<RouteEntry> routes = new LinkedList<>();
-
-        while (it.hasNext()) {
-            KeyValuePair<RouteEntry> entry = it.next();
-            routes.add(entry.getValue());
-        }
-
-        return routes;
-    }
-
-    /**
-     * Finds a route in the RIB for a prefix. The prefix can be either IPv4 or
-     * IPv6.
-     *
-     * @param prefix the prefix to use
-     * @return the route if found, otherwise null
-     */
-    RouteEntry findRibRoute(IpPrefix prefix) {
-        String binaryString = RouteEntry.createBinaryString(prefix);
-        if (prefix.version() == Ip4Address.VERSION) {
-            // IPv4
-            return ribTable4.getValueForExactKey(binaryString);
-        }
-        // IPv6
-        return ribTable6.getValueForExactKey(binaryString);
-    }
-
-    /**
-     * Adds a route to the RIB. The route can be either IPv4 or IPv6.
-     *
-     * @param routeEntry the route entry to use
-     */
-    void addRibRoute(RouteEntry routeEntry) {
-        if (routeEntry.prefix().version() == Ip4Address.VERSION) {
-            // IPv4
-            ribTable4.put(RouteEntry.createBinaryString(routeEntry.prefix()),
-                          routeEntry);
-        } else {
-            // IPv6
-            ribTable6.put(RouteEntry.createBinaryString(routeEntry.prefix()),
-                          routeEntry);
-        }
-    }
-
-    /**
-     * Removes a route for a prefix from the RIB. The prefix can be either IPv4
-     * or IPv6.
-     *
-     * @param prefix the prefix to use
-     * @return true if the route was found and removed, otherwise false
-     */
-    boolean removeRibRoute(IpPrefix prefix) {
-        if (prefix.version() == Ip4Address.VERSION) {
-            // IPv4
-            return ribTable4.remove(RouteEntry.createBinaryString(prefix));
-        }
-        // IPv6
-        return ribTable6.remove(RouteEntry.createBinaryString(prefix));
-    }
-
-    /**
-     * Processes route updates.
-     *
-     * @param routeUpdates the route updates to process
-     */
-    void processRouteUpdates(Collection<RouteUpdate> routeUpdates) {
-        synchronized (this) {
-            Collection<IpPrefix> withdrawPrefixes = new LinkedList<>();
-            Collection<FibUpdate> fibUpdates = new LinkedList<>();
-            Collection<FibUpdate> fibWithdraws = new LinkedList<>();
-
-            for (RouteUpdate update : routeUpdates) {
-                switch (update.type()) {
-                case UPDATE:
-                    FibEntry fib = processRouteAdd(update.routeEntry(),
-                                                    withdrawPrefixes);
-                    if (fib != null) {
-                        fibUpdates.add(new FibUpdate(FibUpdate.Type.UPDATE, fib));
-                    }
-
-                    break;
-                case DELETE:
-                    processRouteDelete(update.routeEntry(), withdrawPrefixes);
-
-                    break;
-                default:
-                    log.error("Unknown update Type: {}", update.type());
-                    break;
-                }
-            }
-
-            withdrawPrefixes.forEach(p -> fibWithdraws.add(new FibUpdate(
-                    FibUpdate.Type.DELETE, new FibEntry(p, null, null))));
-
-            fibComponent.update(fibUpdates, fibWithdraws);
-        }
-    }
-
-    /**
-     * Processes adding a route entry.
-     * <p>
-     * The route entry is added to the radix tree. If there was an existing
-     * next hop for this prefix, but the next hop was different, then the
-     * old route entry is deleted.
-     * </p>
-     * <p>
-     * NOTE: Currently, we don't handle routes if the next hop is within the
-     * SDN domain.
-     * </p>
-     *
-     * @param routeEntry the route entry to add
-     * @param withdrawPrefixes the collection of accumulated prefixes whose
-     * intents will be withdrawn
-     * @return the corresponding FIB entry change, or null
-     */
-    private FibEntry processRouteAdd(
-                RouteEntry routeEntry,
-                Collection<IpPrefix> withdrawPrefixes) {
-        log.debug("Processing route add: {}", routeEntry);
-
-        // Find the old next-hop if we are updating an old route entry
-        IpAddress oldNextHop = null;
-        RouteEntry oldRouteEntry = findRibRoute(routeEntry.prefix());
-        if (oldRouteEntry != null) {
-            oldNextHop = oldRouteEntry.nextHop();
-        }
-
-        // Add the new route to the RIB
-        addRibRoute(routeEntry);
-
-        if (oldNextHop != null) {
-            if (oldNextHop.equals(routeEntry.nextHop())) {
-                return null;            // No change
-            }
-            //
-            // Update an existing nexthop for the prefix.
-            // We need to remove the old flows for this prefix from the
-            // switches before the new flows are added.
-            //
-            withdrawPrefixes.add(routeEntry.prefix());
-        }
-
-        if (routeEntry.nextHop().isZero()) {
-            // Route originated by SDN domain
-            // We don't handle these at the moment
-            log.debug("Own route {} to {}",
-                      routeEntry.prefix(), routeEntry.nextHop());
-            return null;
-        }
-
-        //
-        // Find the MAC address of next hop router for this route entry.
-        // If the MAC address can not be found in ARP cache, then this prefix
-        // will be put in routesWaitingOnArp queue. Otherwise, generate
-        // a new route intent.
-        //
-
-        // Monitor the IP address for updates of the MAC address
-        hostService.startMonitoringIp(routeEntry.nextHop());
-
-        // Check if we know the MAC address of the next hop
-        MacAddress nextHopMacAddress = ip2Mac.get(routeEntry.nextHop());
-        if (nextHopMacAddress == null) {
-            Set<Host> hosts = hostService.getHostsByIp(routeEntry.nextHop());
-            if (!hosts.isEmpty()) {
-                nextHopMacAddress = hosts.iterator().next().mac();
-            }
-            if (nextHopMacAddress != null) {
-                ip2Mac.put(routeEntry.nextHop(), nextHopMacAddress);
-            }
-        }
-        if (nextHopMacAddress == null) {
-            routesWaitingOnArp.put(routeEntry.nextHop(), routeEntry);
-            return null;
-        }
-        return new FibEntry(routeEntry.prefix(), routeEntry.nextHop(),
-                             nextHopMacAddress);
-    }
-
-    /**
-     * Processes the deletion of a route entry.
-     * <p>
-     * The prefix for the routing entry is removed from radix tree.
-     * If the operation is successful, the prefix is added to the collection
-     * of prefixes whose intents that will be withdrawn.
-     * </p>
-     *
-     * @param routeEntry the route entry to delete
-     * @param withdrawPrefixes the collection of accumulated prefixes whose
-     * intents will be withdrawn
-     */
-    private void processRouteDelete(RouteEntry routeEntry,
-                                    Collection<IpPrefix> withdrawPrefixes) {
-        log.debug("Processing route delete: {}", routeEntry);
-        boolean isRemoved = removeRibRoute(routeEntry.prefix());
-
-        if (isRemoved) {
-            //
-            // Only withdraw intents if an entry was actually removed from the
-            // tree. If no entry was removed, the <prefix, nexthop> wasn't
-            // there so it's probably already been removed and we don't
-            // need to do anything.
-            //
-            withdrawPrefixes.add(routeEntry.prefix());
-        }
-
-        routesWaitingOnArp.remove(routeEntry.nextHop(), routeEntry);
-    }
-
-    /**
-     * Signals the Router that the MAC to IP mapping has potentially been
-     * updated. This has the effect of updating the MAC address for any
-     * installed prefixes if it has changed, as well as installing any pending
-     * prefixes that were waiting for MAC resolution.
-     *
-     * @param ipAddress the IP address that an event was received for
-     * @param macAddress the most recently known MAC address for the IP address
-     */
-    private void updateMac(IpAddress ipAddress, MacAddress macAddress) {
-        log.debug("Received updated MAC info: {} => {}", ipAddress,
-                  macAddress);
-
-        //
-        // We synchronize on "this" to prevent changes to the Radix tree
-        // while we're pushing intents. If the tree changes, the
-        // tree and the intents could get out of sync.
-        //
-        synchronized (this) {
-            Collection<FibUpdate> submitFibEntries = new LinkedList<>();
-
-            Set<RouteEntry> routesToPush =
-                routesWaitingOnArp.removeAll(ipAddress);
-
-            for (RouteEntry routeEntry : routesToPush) {
-                // These will always be adds
-                RouteEntry foundRouteEntry = findRibRoute(routeEntry.prefix());
-                if (foundRouteEntry != null &&
-                    foundRouteEntry.nextHop().equals(routeEntry.nextHop())) {
-                    // We only push FIB updates if the prefix is still in the
-                    // radix tree and the next hop is the same as our entry.
-                    // The prefix could have been removed while we were waiting
-                    // for the ARP, or the next hop could have changed.
-                    submitFibEntries.add(new FibUpdate(FibUpdate.Type.UPDATE,
-                                                       new FibEntry(routeEntry.prefix(),
-                                                       ipAddress, macAddress)));
-                } else {
-                    log.debug("{} has been revoked before the MAC was resolved",
-                              routeEntry);
-                }
-            }
-
-            if (!submitFibEntries.isEmpty()) {
-                fibComponent.update(submitFibEntries, Collections.emptyList());
-            }
-
-            ip2Mac.put(ipAddress, macAddress);
-        }
-    }
-
-    /**
-     * Listener for host events.
-     */
-    class InternalHostListener implements HostListener {
-        @Override
-        public void event(HostEvent event) {
-            log.debug("Received HostEvent {}", event);
-
-            Host host = event.subject();
-            switch (event.type()) {
-            case HOST_ADDED:
-                // FALLTHROUGH
-            case HOST_UPDATED:
-                for (IpAddress ipAddress : host.ipAddresses()) {
-                    updateMac(ipAddress, host.mac());
-                }
-                break;
-            case HOST_REMOVED:
-                for (IpAddress ipAddress : host.ipAddresses()) {
-                    ip2Mac.remove(ipAddress);
-                }
-                break;
-            default:
-                break;
-            }
-        }
-    }
-}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java
index 0b921ff..b375852 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java
@@ -32,14 +32,11 @@
 import org.onosproject.core.CoreService;
 import org.onosproject.net.host.HostService;
 import org.onosproject.net.intent.IntentService;
-import org.onosproject.sdnip.bgp.BgpRouteEntry;
-import org.onosproject.sdnip.bgp.BgpSession;
-import org.onosproject.sdnip.bgp.BgpSessionManager;
+import org.onosproject.routingapi.RoutingService;
 import org.onosproject.sdnip.config.SdnIpConfigurationReader;
 import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 
-import java.util.Collection;
 import java.util.Dictionary;
 
 import static org.slf4j.LoggerFactory.getLogger;
@@ -69,8 +66,11 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected LeadershipService leadershipService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected RoutingService routingService;
+
     //
-    // NOTE: Unused reference - needed to guarentee that the
+    // NOTE: Unused reference - needed to guarantee that the
     // NetworkConfigReader component is activated and the network configuration
     // is read.
     //
@@ -83,8 +83,7 @@
     private IntentSynchronizer intentSynchronizer;
     private SdnIpConfigurationReader config;
     private PeerConnectivityManager peerConnectivity;
-    private Router router;
-    private BgpSessionManager bgpSessionManager;
+
     private LeadershipEventListener leadershipEventListener =
         new InnerLeadershipEventListener();
     private ApplicationId appId;
@@ -114,23 +113,18 @@
                                                        interfaceService);
         peerConnectivity.start();
 
-        router = new Router(intentSynchronizer, hostService);
-        router.start();
+        routingService.start(intentSynchronizer);
 
         leadershipService.addListener(leadershipEventListener);
         leadershipService.runForLeadership(appId.name());
 
         log.info("Starting BGP with port {}", bgpPort);
-
-        bgpSessionManager = new BgpSessionManager(router);
-        bgpSessionManager.start(bgpPort);
+        // TODO feed port information through to the BgpService
     }
 
     @Deactivate
     protected void deactivate() {
-
-        bgpSessionManager.stop();
-        router.stop();
+        routingService.stop();
         peerConnectivity.stop();
         intentSynchronizer.stop();
 
@@ -168,31 +162,6 @@
     }
 
     @Override
-    public Collection<BgpSession> getBgpSessions() {
-        return bgpSessionManager.getBgpSessions();
-    }
-
-    @Override
-    public Collection<BgpRouteEntry> getBgpRoutes4() {
-        return bgpSessionManager.getBgpRoutes4();
-    }
-
-    @Override
-    public Collection<BgpRouteEntry> getBgpRoutes6() {
-        return bgpSessionManager.getBgpRoutes6();
-    }
-
-    @Override
-    public Collection<RouteEntry> getRoutes4() {
-        return router.getRoutes4();
-    }
-
-    @Override
-    public Collection<RouteEntry> getRoutes6() {
-        return router.getRoutes6();
-    }
-
-    @Override
     public void modifyPrimary(boolean isPrimary) {
         intentSynchronizer.leaderChanged(isPrimary);
     }
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpService.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpService.java
index aa71f02..dbb0d88 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpService.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpService.java
@@ -15,49 +15,10 @@
  */
 package org.onosproject.sdnip;
 
-import java.util.Collection;
-
-import org.onosproject.sdnip.bgp.BgpRouteEntry;
-import org.onosproject.sdnip.bgp.BgpSession;
-
 /**
  * Service interface exported by SDN-IP.
  */
 public interface SdnIpService {
-    /**
-     * Gets the BGP sessions.
-     *
-     * @return the BGP sessions
-     */
-    public Collection<BgpSession> getBgpSessions();
-
-    /**
-     * Gets the selected IPv4 BGP routes among all BGP sessions.
-     *
-     * @return the selected IPv4 BGP routes among all BGP sessions
-     */
-    public Collection<BgpRouteEntry> getBgpRoutes4();
-
-    /**
-     * Gets the selected IPv6 BGP routes among all BGP sessions.
-     *
-     * @return the selected IPv6 BGP routes among all BGP sessions
-     */
-    public Collection<BgpRouteEntry> getBgpRoutes6();
-
-    /**
-     * Gets all IPv4 routes known to SDN-IP.
-     *
-     * @return the SDN-IP IPv4 routes
-     */
-    public Collection<RouteEntry> getRoutes4();
-
-    /**
-     * Gets all IPv6 routes known to SDN-IP.
-     *
-     * @return the SDN-IP IPv6 routes
-     */
-    public Collection<RouteEntry> getRoutes6();
 
     /**
      * Changes whether this SDN-IP instance is the primary or not based on the
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpConstants.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpConstants.java
deleted file mode 100644
index b009c17..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpConstants.java
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * 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;
-
-/**
- * BGP related constants.
- */
-public final class BgpConstants {
-    /**
-     * Default constructor.
-     * <p>
-     * The constructor is private to prevent creating an instance of
-     * this utility class.
-     */
-    private BgpConstants() {
-    }
-
-    /** BGP port number (RFC 4271). */
-    public static final int BGP_PORT = 179;
-
-    /** BGP version. */
-    public static final int BGP_VERSION = 4;
-
-    /** BGP OPEN message type. */
-    public static final int BGP_TYPE_OPEN = 1;
-
-    /** BGP UPDATE message type. */
-    public static final int BGP_TYPE_UPDATE = 2;
-
-    /** BGP NOTIFICATION message type. */
-    public static final int BGP_TYPE_NOTIFICATION = 3;
-
-    /** BGP KEEPALIVE message type. */
-    public static final int BGP_TYPE_KEEPALIVE = 4;
-
-    /** BGP Header Marker field length. */
-    public static final int BGP_HEADER_MARKER_LENGTH = 16;
-
-    /** BGP Header length. */
-    public static final int BGP_HEADER_LENGTH = 19;
-
-    /** BGP message maximum length. */
-    public static final int BGP_MESSAGE_MAX_LENGTH = 4096;
-
-    /** BGP OPEN message minimum length (BGP Header included). */
-    public static final int BGP_OPEN_MIN_LENGTH = 29;
-
-    /** BGP UPDATE message minimum length (BGP Header included). */
-    public static final int BGP_UPDATE_MIN_LENGTH = 23;
-
-    /** BGP NOTIFICATION message minimum length (BGP Header included). */
-    public static final int BGP_NOTIFICATION_MIN_LENGTH = 21;
-
-    /** BGP KEEPALIVE message expected length (BGP Header included). */
-    public static final int BGP_KEEPALIVE_EXPECTED_LENGTH = 19;
-
-    /** BGP KEEPALIVE messages transmitted per Hold interval. */
-    public static final int BGP_KEEPALIVE_PER_HOLD_INTERVAL = 3;
-
-    /** BGP KEEPALIVE messages minimum Holdtime (in seconds). */
-    public static final int BGP_KEEPALIVE_MIN_HOLDTIME = 3;
-
-    /** BGP KEEPALIVE messages minimum transmission interval (in seconds). */
-    public static final int BGP_KEEPALIVE_MIN_INTERVAL = 1;
-
-    /** BGP AS 0 (zero) value. See draft-ietf-idr-as0-06.txt Internet Draft. */
-    public static final long BGP_AS_0 = 0;
-
-    /**
-     * BGP OPEN related constants.
-     */
-    public static final class Open {
-        /**
-         * Default constructor.
-         * <p>
-         * The constructor is private to prevent creating an instance of
-         * this utility class.
-         */
-        private Open() {
-        }
-
-        /**
-         * BGP OPEN: Optional Parameters related constants.
-         */
-        public static final class OptionalParameters {
-        }
-
-        /**
-         * BGP OPEN: Capabilities related constants (RFC 5492).
-         */
-        public static final class Capabilities {
-            /** BGP OPEN Optional Parameter Type: Capabilities. */
-            public static final int TYPE = 2;
-
-            /** BGP OPEN Optional Parameter minimum length. */
-            public static final int MIN_LENGTH = 2;
-
-            /**
-             * BGP OPEN: Multiprotocol Extensions Capabilities (RFC 4760).
-             */
-            public static final class MultiprotocolExtensions {
-                /** BGP OPEN Multiprotocol Extensions code. */
-                public static final int CODE = 1;
-
-                /** BGP OPEN Multiprotocol Extensions length. */
-                public static final int LENGTH = 4;
-
-                /** BGP OPEN Multiprotocol Extensions AFI: IPv4. */
-                public static final int AFI_IPV4 = 1;
-
-                /** BGP OPEN Multiprotocol Extensions AFI: IPv6. */
-                public static final int AFI_IPV6 = 2;
-
-                /** BGP OPEN Multiprotocol Extensions SAFI: unicast. */
-                public static final int SAFI_UNICAST = 1;
-
-                /** BGP OPEN Multiprotocol Extensions SAFI: multicast. */
-                public static final int SAFI_MULTICAST = 2;
-            }
-
-            /**
-             * BGP OPEN: Support for 4-octet AS Number Capability (RFC 6793).
-             */
-            public static final class As4Octet {
-                /** BGP OPEN Support for 4-octet AS Number Capability code. */
-                public static final int CODE = 65;
-
-                /** BGP OPEN 4-octet AS Number Capability length. */
-                public static final int LENGTH = 4;
-            }
-        }
-    }
-
-    /**
-     * BGP UPDATE related constants.
-     */
-    public static final class Update {
-        /**
-         * Default constructor.
-         * <p>
-         * The constructor is private to prevent creating an instance of
-         * this utility class.
-         */
-        private Update() {
-        }
-
-        /**
-         * BGP UPDATE: ORIGIN related constants.
-         */
-        public static final class Origin {
-            /**
-             * Default constructor.
-             * <p>
-             * The constructor is private to prevent creating an instance of
-             * this utility class.
-             */
-            private Origin() {
-            }
-
-            /** BGP UPDATE Attributes Type Code ORIGIN. */
-            public static final int TYPE = 1;
-
-            /** BGP UPDATE Attributes Type Code ORIGIN length. */
-            public static final int LENGTH = 1;
-
-            /** BGP UPDATE ORIGIN: IGP. */
-            public static final int IGP = 0;
-
-            /** BGP UPDATE ORIGIN: EGP. */
-            public static final int EGP = 1;
-
-            /** BGP UPDATE ORIGIN: INCOMPLETE. */
-            public static final int INCOMPLETE = 2;
-
-            /**
-             * Gets the BGP UPDATE origin type as a string.
-             *
-             * @param type the BGP UPDATE origin type
-             * @return the BGP UPDATE origin type as a string
-             */
-            public static String typeToString(int type) {
-                String typeString = "UNKNOWN";
-
-                switch (type) {
-                case IGP:
-                    typeString = "IGP";
-                    break;
-                case EGP:
-                    typeString = "EGP";
-                    break;
-                case INCOMPLETE:
-                    typeString = "INCOMPLETE";
-                    break;
-                default:
-                    break;
-                }
-                return typeString;
-            }
-        }
-
-        /**
-         * BGP UPDATE: AS_PATH related constants.
-         */
-        public static final class AsPath {
-            /**
-             * Default constructor.
-             * <p>
-             * The constructor is private to prevent creating an instance of
-             * this utility class.
-             */
-            private AsPath() {
-            }
-
-            /** BGP UPDATE Attributes Type Code AS_PATH. */
-            public static final int TYPE = 2;
-
-            /** BGP AS length. */
-            public static final int AS_LENGTH = 2;
-
-            /** BGP 4 Octet AS length (RFC 6793). */
-            public static final int AS_4OCTET_LENGTH = 4;
-
-            /** BGP UPDATE AS_PATH Type: AS_SET. */
-            public static final int AS_SET = 1;
-
-            /** BGP UPDATE AS_PATH Type: AS_SEQUENCE. */
-            public static final int AS_SEQUENCE = 2;
-
-            /** BGP UPDATE AS_PATH Type: AS_CONFED_SEQUENCE. */
-            public static final int AS_CONFED_SEQUENCE = 3;
-
-            /** BGP UPDATE AS_PATH Type: AS_CONFED_SET. */
-            public static final int AS_CONFED_SET = 4;
-
-            /**
-             * Gets the BGP AS_PATH type as a string.
-             *
-             * @param type the BGP AS_PATH type
-             * @return the BGP AS_PATH type as a string
-             */
-            public static String typeToString(int type) {
-                String typeString = "UNKNOWN";
-
-                switch (type) {
-                case AS_SET:
-                    typeString = "AS_SET";
-                    break;
-                case AS_SEQUENCE:
-                    typeString = "AS_SEQUENCE";
-                    break;
-                case AS_CONFED_SEQUENCE:
-                    typeString = "AS_CONFED_SEQUENCE";
-                    break;
-                case AS_CONFED_SET:
-                    typeString = "AS_CONFED_SET";
-                    break;
-                default:
-                    break;
-                }
-                return typeString;
-            }
-        }
-
-        /**
-         * BGP UPDATE: NEXT_HOP related constants.
-         */
-        public static final class NextHop {
-            /**
-             * Default constructor.
-             * <p>
-             * The constructor is private to prevent creating an instance of
-             * this utility class.
-             */
-            private NextHop() {
-            }
-
-            /** BGP UPDATE Attributes Type Code NEXT_HOP. */
-            public static final int TYPE = 3;
-
-            /** BGP UPDATE Attributes Type Code NEXT_HOP length. */
-            public static final int LENGTH = 4;
-        }
-
-        /**
-         * BGP UPDATE: MULTI_EXIT_DISC related constants.
-         */
-        public static final class MultiExitDisc {
-            /**
-             * Default constructor.
-             * <p>
-             * The constructor is private to prevent creating an instance of
-             * this utility class.
-             */
-            private MultiExitDisc() {
-            }
-
-            /** BGP UPDATE Attributes Type Code MULTI_EXIT_DISC. */
-            public static final int TYPE = 4;
-
-            /** BGP UPDATE Attributes Type Code MULTI_EXIT_DISC length. */
-            public static final int LENGTH = 4;
-
-            /** BGP UPDATE Attributes lowest MULTI_EXIT_DISC value. */
-            public static final int LOWEST_MULTI_EXIT_DISC = 0;
-        }
-
-        /**
-         * BGP UPDATE: LOCAL_PREF related constants.
-         */
-        public static final class LocalPref {
-            /**
-             * Default constructor.
-             * <p>
-             * The constructor is private to prevent creating an instance of
-             * this utility class.
-             */
-            private LocalPref() {
-            }
-
-            /** BGP UPDATE Attributes Type Code LOCAL_PREF. */
-            public static final int TYPE = 5;
-
-            /** BGP UPDATE Attributes Type Code LOCAL_PREF length. */
-            public static final int LENGTH = 4;
-        }
-
-        /**
-         * BGP UPDATE: ATOMIC_AGGREGATE related constants.
-         */
-        public static final class AtomicAggregate {
-            /**
-             * Default constructor.
-             * <p>
-             * The constructor is private to prevent creating an instance of
-             * this utility class.
-             */
-            private AtomicAggregate() {
-            }
-
-            /** BGP UPDATE Attributes Type Code ATOMIC_AGGREGATE. */
-            public static final int TYPE = 6;
-
-            /** BGP UPDATE Attributes Type Code ATOMIC_AGGREGATE length. */
-            public static final int LENGTH = 0;
-        }
-
-        /**
-         * BGP UPDATE: AGGREGATOR related constants.
-         */
-        public static final class Aggregator {
-            /**
-             * Default constructor.
-             * <p>
-             * The constructor is private to prevent creating an instance of
-             * this utility class.
-             */
-            private Aggregator() {
-            }
-
-            /** BGP UPDATE Attributes Type Code AGGREGATOR. */
-            public static final int TYPE = 7;
-
-            /** BGP UPDATE Attributes Type Code AGGREGATOR length. */
-            public static final int LENGTH = 6;
-        }
-
-        /**
-         * BGP UPDATE: MP_REACH_NLRI related constants.
-         */
-        public static final class MpReachNlri {
-            /**
-             * Default constructor.
-             * <p>
-             * The constructor is private to prevent creating an instance of
-             * this utility class.
-             */
-            private MpReachNlri() {
-            }
-
-            /** BGP UPDATE Attributes Type Code MP_REACH_NLRI. */
-            public static final int TYPE = 14;
-
-            /** BGP UPDATE Attributes Type Code MP_REACH_NLRI min length. */
-            public static final int MIN_LENGTH = 5;
-        }
-
-        /**
-         * BGP UPDATE: MP_UNREACH_NLRI related constants.
-         */
-        public static final class MpUnreachNlri {
-            /**
-             * Default constructor.
-             * <p>
-             * The constructor is private to prevent creating an instance of
-             * this utility class.
-             */
-            private MpUnreachNlri() {
-            }
-
-            /** BGP UPDATE Attributes Type Code MP_UNREACH_NLRI. */
-            public static final int TYPE = 15;
-
-            /** BGP UPDATE Attributes Type Code MP_UNREACH_NLRI min length. */
-            public static final int MIN_LENGTH = 3;
-        }
-    }
-
-    /**
-     * BGP NOTIFICATION related constants.
-     */
-    public static final class Notifications {
-        /**
-         * Default constructor.
-         * <p>
-         * The constructor is private to prevent creating an instance of
-         * this utility class.
-         */
-        private Notifications() {
-        }
-
-        /**
-         * BGP NOTIFICATION: Message Header Error constants.
-         */
-        public static final class MessageHeaderError {
-            /**
-             * Default constructor.
-             * <p>
-             * The constructor is private to prevent creating an instance of
-             * this utility class.
-             */
-            private MessageHeaderError() {
-            }
-
-            /** Message Header Error code. */
-            public static final int ERROR_CODE = 1;
-
-            /** Message Header Error subcode: Connection Not Synchronized. */
-            public static final int CONNECTION_NOT_SYNCHRONIZED = 1;
-
-            /** Message Header Error subcode: Bad Message Length. */
-            public static final int BAD_MESSAGE_LENGTH = 2;
-
-            /** Message Header Error subcode: Bad Message Type. */
-            public static final int BAD_MESSAGE_TYPE = 3;
-        }
-
-        /**
-         * BGP NOTIFICATION: OPEN Message Error constants.
-         */
-        public static final class OpenMessageError {
-            /**
-             * Default constructor.
-             * <p>
-             * The constructor is private to prevent creating an instance of
-             * this utility class.
-             */
-            private OpenMessageError() {
-            }
-
-            /** OPEN Message Error code. */
-            public static final int ERROR_CODE = 2;
-
-            /** OPEN Message Error subcode: Unsupported Version Number. */
-            public static final int UNSUPPORTED_VERSION_NUMBER = 1;
-
-            /** OPEN Message Error subcode: Bad PEER AS. */
-            public static final int BAD_PEER_AS = 2;
-
-            /** OPEN Message Error subcode: Unacceptable Hold Time. */
-            public static final int UNACCEPTABLE_HOLD_TIME = 6;
-        }
-
-        /**
-         * BGP NOTIFICATION: UPDATE Message Error constants.
-         */
-        public static final class UpdateMessageError {
-            /**
-             * Default constructor.
-             * <p>
-             * The constructor is private to prevent creating an instance of
-             * this utility class.
-             */
-            private UpdateMessageError() {
-            }
-
-            /** UPDATE Message Error code. */
-            public static final int ERROR_CODE = 3;
-
-            /** UPDATE Message Error subcode: Malformed Attribute List. */
-            public static final int MALFORMED_ATTRIBUTE_LIST = 1;
-
-            /** UPDATE Message Error subcode: Unrecognized Well-known Attribute. */
-            public static final int UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE = 2;
-
-            /** UPDATE Message Error subcode: Missing Well-known Attribute. */
-            public static final int MISSING_WELL_KNOWN_ATTRIBUTE = 3;
-
-           /** UPDATE Message Error subcode: Attribute Flags Error. */
-            public static final int ATTRIBUTE_FLAGS_ERROR = 4;
-
-            /** UPDATE Message Error subcode: Attribute Length Error. */
-            public static final int ATTRIBUTE_LENGTH_ERROR = 5;
-
-            /** UPDATE Message Error subcode: Invalid ORIGIN Attribute. */
-            public static final int INVALID_ORIGIN_ATTRIBUTE = 6;
-
-            /** UPDATE Message Error subcode: Invalid NEXT_HOP Attribute. */
-            public static final int INVALID_NEXT_HOP_ATTRIBUTE = 8;
-
-            /** UPDATE Message Error subcode: Optional Attribute Error. Unused. */
-            public static final int OPTIONAL_ATTRIBUTE_ERROR = 9;
-
-            /** UPDATE Message Error subcode: Invalid Network Field. */
-            public static final int INVALID_NETWORK_FIELD = 10;
-
-            /** UPDATE Message Error subcode: Malformed AS_PATH. */
-            public static final int MALFORMED_AS_PATH = 11;
-        }
-
-        /**
-         * BGP NOTIFICATION: Hold Timer Expired constants.
-         */
-        public static final class HoldTimerExpired {
-            /**
-             * Default constructor.
-             * <p>
-             * The constructor is private to prevent creating an instance of
-             * this utility class.
-             */
-            private HoldTimerExpired() {
-            }
-
-            /** Hold Timer Expired code. */
-            public static final int ERROR_CODE = 4;
-        }
-
-        /** BGP NOTIFICATION message Error subcode: Unspecific. */
-        public static final int ERROR_SUBCODE_UNSPECIFIC = 0;
-    }
-}
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
deleted file mode 100644
index 4c9b56e..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpFrameDecoder.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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.Channel;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.handler.codec.frame.FrameDecoder;
-import org.onosproject.sdnip.bgp.BgpConstants.Notifications.MessageHeaderError;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Class for handling the decoding of the BGP messages.
- */
-class BgpFrameDecoder extends FrameDecoder {
-    private static final Logger log =
-        LoggerFactory.getLogger(BgpFrameDecoder.class);
-
-    private final BgpSession bgpSession;
-
-    /**
-     * Constructor for a given BGP Session.
-     *
-     * @param bgpSession the BGP session state to use.
-     */
-    BgpFrameDecoder(BgpSession bgpSession) {
-        this.bgpSession = bgpSession;
-    }
-
-    @Override
-    protected Object decode(ChannelHandlerContext ctx,
-                            Channel channel,
-                            ChannelBuffer buf) throws Exception {
-        //
-        // NOTE: If we close the channel during the decoding, we might still
-        // see some incoming messages while the channel closing is completed.
-        //
-        if (bgpSession.isClosed()) {
-            return null;
-        }
-
-        log.trace("BGP Peer: decode(): remoteAddr = {} localAddr = {} " +
-                  "messageSize = {}",
-                  ctx.getChannel().getRemoteAddress(),
-                  ctx.getChannel().getLocalAddress(),
-                  buf.readableBytes());
-
-        // Test for minimum length of the BGP message
-        if (buf.readableBytes() < BgpConstants.BGP_HEADER_LENGTH) {
-            // No enough data received
-            return null;
-        }
-
-        //
-        // Mark the current buffer position in case we haven't received
-        // the whole message.
-        //
-        buf.markReaderIndex();
-
-        //
-        // Read and check the BGP message Marker field: it must be all ones
-        // (See RFC 4271, Section 4.1)
-        //
-        byte[] marker = new byte[BgpConstants.BGP_HEADER_MARKER_LENGTH];
-        buf.readBytes(marker);
-        for (int i = 0; i < marker.length; i++) {
-            if (marker[i] != (byte) 0xff) {
-                log.debug("BGP RX Error: invalid marker {} at position {}",
-                          marker[i], i);
-                //
-                // ERROR: Connection Not Synchronized
-                //
-                // Send NOTIFICATION and close the connection
-                int errorCode = MessageHeaderError.ERROR_CODE;
-                int errorSubcode =
-                    MessageHeaderError.CONNECTION_NOT_SYNCHRONIZED;
-                ChannelBuffer txMessage =
-                    BgpNotification.prepareBgpNotification(errorCode,
-                                                           errorSubcode,
-                                                           null);
-                ctx.getChannel().write(txMessage);
-                bgpSession.closeSession(ctx);
-                return null;
-            }
-        }
-
-        //
-        // Read and check the BGP message Length field
-        //
-        int length = buf.readUnsignedShort();
-        if ((length < BgpConstants.BGP_HEADER_LENGTH) ||
-            (length > BgpConstants.BGP_MESSAGE_MAX_LENGTH)) {
-            log.debug("BGP RX Error: invalid Length field {}. " +
-                      "Must be between {} and {}",
-                      length,
-                      BgpConstants.BGP_HEADER_LENGTH,
-                      BgpConstants.BGP_MESSAGE_MAX_LENGTH);
-            //
-            // ERROR: Bad Message Length
-            //
-            // Send NOTIFICATION and close the connection
-            ChannelBuffer txMessage =
-                BgpNotification.prepareBgpNotificationBadMessageLength(length);
-            ctx.getChannel().write(txMessage);
-            bgpSession.closeSession(ctx);
-            return null;
-        }
-
-        //
-        // Test whether the rest of the message is received:
-        // So far we have read the Marker (16 octets) and the
-        // Length (2 octets) fields.
-        //
-        int remainingMessageLen =
-            length - BgpConstants.BGP_HEADER_MARKER_LENGTH - 2;
-        if (buf.readableBytes() < remainingMessageLen) {
-            // No enough data received
-            buf.resetReaderIndex();
-            return null;
-        }
-
-        //
-        // Read the BGP message Type field, and process based on that type
-        //
-        int type = buf.readUnsignedByte();
-        remainingMessageLen--;      // Adjust after reading the type
-        ChannelBuffer message = buf.readBytes(remainingMessageLen);
-
-        //
-        // Process the remaining of the message based on the message type
-        //
-        switch (type) {
-        case BgpConstants.BGP_TYPE_OPEN:
-            BgpOpen.processBgpOpen(bgpSession, ctx, message);
-            break;
-        case BgpConstants.BGP_TYPE_UPDATE:
-            BgpUpdate.processBgpUpdate(bgpSession, ctx, message);
-            break;
-        case BgpConstants.BGP_TYPE_NOTIFICATION:
-            BgpNotification.processBgpNotification(bgpSession, ctx, message);
-            break;
-        case BgpConstants.BGP_TYPE_KEEPALIVE:
-            BgpKeepalive.processBgpKeepalive(bgpSession, ctx, message);
-            break;
-        default:
-            //
-            // ERROR: Bad Message Type
-            //
-            // Send NOTIFICATION and close the connection
-            int errorCode = MessageHeaderError.ERROR_CODE;
-            int errorSubcode = MessageHeaderError.BAD_MESSAGE_TYPE;
-            ChannelBuffer data = ChannelBuffers.buffer(1);
-            data.writeByte(type);
-            ChannelBuffer txMessage =
-                BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
-                                                       data);
-            ctx.getChannel().write(txMessage);
-            bgpSession.closeSession(ctx);
-            return null;
-        }
-        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
deleted file mode 100644
index fe9404c..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpKeepalive.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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.remoteInfo().address(),
-                      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.remoteInfo().address());
-
-        // 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
deleted file mode 100644
index 5c7053c..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpMessage.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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;
-    }
-
-    /**
-     * An exception indicating a parsing error of the BGP message.
-     */
-    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
-         */
-        BgpParseException(String message) {
-            super(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
deleted file mode 100644
index cf6bbb7..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpNotification.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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.remoteInfo().address(),
-                      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.remoteInfo().address(), 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
deleted file mode 100644
index 93ef852..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpOpen.java
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * 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.onosproject.sdnip.bgp.BgpConstants.Open.Capabilities;
-import org.onosproject.sdnip.bgp.BgpConstants.Open.Capabilities.MultiprotocolExtensions;
-import org.onosproject.sdnip.bgp.BgpConstants.Open.Capabilities.As4Octet;
-import org.onosproject.sdnip.bgp.BgpMessage.BgpParseException;
-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.remoteInfo().address(),
-                      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.remoteInfo().address(), 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.remoteInfo().setBgpVersion(remoteBgpVersion);
-
-        // Remote AS number
-        long remoteAs = message.readUnsignedShort();
-        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();
-        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.remoteInfo().address(), 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.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.remoteInfo().setBgpId(remoteBgpId);
-
-        // Parse the Optional Parameters
-        try {
-            parseOptionalParameters(bgpSession, ctx, message);
-        } catch (BgpParseException e) {
-            // ERROR: Error parsing optional parameters
-            log.debug("BGP RX OPEN Error from {}: " +
-                      "Exception parsing Optional Parameters: {}",
-                      bgpSession.remoteInfo().address(), e);
-            //
-            // ERROR: Invalid Optional Parameters: 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: Prepare the BGP OPEN message before the original local AS
-        // is overwritten by the 4-octet AS number
-        //
-        ChannelBuffer txOpenMessage = prepareBgpOpen(bgpSession.localInfo());
-
-        //
-        // Use the 4-octet AS number in lieu of the "My AS" field
-        // See RFC 6793, Section 4.1, second paragraph.
-        //
-        if (bgpSession.remoteInfo().as4OctetCapability()) {
-            long as4Number = bgpSession.remoteInfo().as4Number();
-            bgpSession.remoteInfo().setAsNumber(as4Number);
-            bgpSession.localInfo().setAsNumber(as4Number);
-        }
-
-        //
-        // 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.remoteInfo().asNumber() != 0) &&
-                (bgpSession.remoteInfo().asNumber() !=
-                 bs.remoteInfo().asNumber())) {
-                log.debug("BGP RX OPEN Error from {}: Bad Peer AS {}. " +
-                          "Expected {}",
-                          bgpSession.remoteInfo().address(),
-                          bgpSession.remoteInfo().asNumber(),
-                          bs.remoteInfo().asNumber());
-                //
-                // 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;
-            }
-        }
-
-        log.debug("BGP RX OPEN message from {}: " +
-                  "BGPv{} AS {} BGP-ID {} Holdtime {}",
-                  bgpSession.remoteInfo().address(),
-                  bgpSession.remoteInfo().bgpVersion(),
-                  bgpSession.remoteInfo().asNumber(),
-                  bgpSession.remoteInfo().bgpId(),
-                  bgpSession.remoteInfo().holdtime());
-
-        // Send my OPEN followed by KEEPALIVE
-        ctx.getChannel().write(txOpenMessage);
-        //
-        ChannelBuffer 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 localInfo the BGP Session local information to use
-     * @return the message to transmit (BGP header included)
-     */
-    static ChannelBuffer prepareBgpOpen(BgpSessionInfo localInfo) {
-        ChannelBuffer message =
-            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
-
-        //
-        // Prepare the OPEN message payload
-        //
-        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(localInfo);
-        message.writeByte(capabilitiesMessage.readableBytes());
-        message.writeBytes(capabilitiesMessage);
-
-        return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_OPEN,
-                                            message);
-    }
-
-    /**
-     * Parses BGP OPEN Optional Parameters.
-     *
-     * @param bgpSession the BGP Session to use
-     * @param ctx the Channel Handler Context
-     * @param message the message to process
-     * @throws BgpParseException
-     */
-    private static void parseOptionalParameters(BgpSession bgpSession,
-                                                ChannelHandlerContext ctx,
-                                                ChannelBuffer message)
-        throws BgpParseException {
-
-        //
-        // Get and verify the Optional Parameters Length
-        //
-        int optParamLength = message.readUnsignedByte();
-        if (optParamLength > message.readableBytes()) {
-            // ERROR: Invalid Optional Parameter Length
-            String errorMsg = "Invalid Optional Parameter Length field " +
-                optParamLength + ". Remaining Optional Parameters " +
-                message.readableBytes();
-            throw new BgpParseException(errorMsg);
-        }
-        if (optParamLength == 0) {
-            return;                     // No Optional Parameters
-        }
-
-        //
-        // Parse the Optional Parameters
-        //
-        int optParamEnd = message.readerIndex() + optParamLength;
-        while (message.readerIndex() < optParamEnd) {
-            int paramType = message.readUnsignedByte();
-            if (message.readerIndex() >= optParamEnd) {
-                // ERROR: Malformed Optional Parameters
-                String errorMsg = "Malformed Optional Parameters";
-                throw new BgpParseException(errorMsg);
-            }
-            int paramLen = message.readUnsignedByte();
-            if (message.readerIndex() + paramLen > optParamEnd) {
-                // ERROR: Malformed Optional Parameters
-                String errorMsg = "Malformed Optional Parameters";
-                throw new BgpParseException(errorMsg);
-            }
-
-            //
-            // Extract the Optional Parameter Value based on the Parameter Type
-            //
-            switch (paramType) {
-            case Capabilities.TYPE:
-                // Optional Parameter Type: Capabilities
-                if (paramLen < Capabilities.MIN_LENGTH) {
-                    // ERROR: Malformed Capability
-                    String errorMsg = "Malformed Capability Type " + paramType;
-                    throw new BgpParseException(errorMsg);
-                }
-                int capabEnd = message.readerIndex() + paramLen;
-                int capabCode = message.readUnsignedByte();
-                int capabLen = message.readUnsignedByte();
-                if (message.readerIndex() + capabLen > capabEnd) {
-                    // ERROR: Malformed Capability
-                    String errorMsg = "Malformed Capability Type " + paramType;
-                    throw new BgpParseException(errorMsg);
-                }
-
-                switch (capabCode) {
-                case MultiprotocolExtensions.CODE:
-                    // Multiprotocol Extensions Capabilities (RFC 4760)
-                    if (capabLen != MultiprotocolExtensions.LENGTH) {
-                        // ERROR: Multiprotocol Extension Length Error
-                        String errorMsg = "Multiprotocol Extension Length Error";
-                        throw new BgpParseException(errorMsg);
-                    }
-                    // Decode the AFI (2 octets) and SAFI (1 octet)
-                    int afi = message.readUnsignedShort();
-                    int reserved = message.readUnsignedByte();
-                    int safi = message.readUnsignedByte();
-                    log.debug("BGP RX OPEN Capability: AFI = {} SAFI = {}",
-                              afi, safi);
-                    //
-                    // 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.remoteInfo().setIpv4Unicast();
-                        bgpSession.localInfo().setIpv4Unicast();
-                    } else if (afi == MultiprotocolExtensions.AFI_IPV4 &&
-                               safi == MultiprotocolExtensions.SAFI_MULTICAST) {
-                        bgpSession.remoteInfo().setIpv4Multicast();
-                        bgpSession.localInfo().setIpv4Multicast();
-                    } else if (afi == MultiprotocolExtensions.AFI_IPV6 &&
-                               safi == MultiprotocolExtensions.SAFI_UNICAST) {
-                        bgpSession.remoteInfo().setIpv6Unicast();
-                        bgpSession.localInfo().setIpv6Unicast();
-                    } else if (afi == MultiprotocolExtensions.AFI_IPV6 &&
-                               safi == MultiprotocolExtensions.SAFI_MULTICAST) {
-                        bgpSession.remoteInfo().setIpv6Multicast();
-                        bgpSession.localInfo().setIpv6Multicast();
-                    } else {
-                        log.debug("BGP RX OPEN Capability: Unknown AFI = {} SAFI = {}",
-                                  afi, safi);
-                    }
-                    break;
-
-                case Capabilities.As4Octet.CODE:
-                    // Support for 4-octet AS Number Capabilities (RFC 6793)
-                    if (capabLen != Capabilities.As4Octet.LENGTH) {
-                        // ERROR: 4-octet AS Number Capability Length Error
-                        String errorMsg = "4-octet AS Number Capability Length Error";
-                        throw new BgpParseException(errorMsg);
-                    }
-                    long as4Number = message.readUnsignedInt();
-
-                    bgpSession.remoteInfo().setAs4OctetCapability();
-                    bgpSession.remoteInfo().setAs4Number(as4Number);
-
-                    //
-                    // 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);
-                    log.debug("BGP RX OPEN Capability: AS4 Number = {}",
-                              as4Number);
-                    break;
-
-                default:
-                    // Unknown Capability: ignore it
-                    log.debug("BGP RX OPEN Capability Code = {} Length = {}",
-                              capabCode, capabLen);
-                    message.readBytes(capabLen);
-                    break;
-                }
-
-                break;
-
-            default:
-                // Unknown Parameter Type: ignore it
-                log.debug("BGP RX OPEN Parameter Type = {} Length = {}",
-                          paramType, paramLen);
-                message.readBytes(paramLen);
-                break;
-            }
-        }
-    }
-
-    /**
-     * Prepares the Capabilities for the BGP OPEN message.
-     *
-     * @param localInfo the BGP Session local information to use
-     * @return the buffer with the BGP Capabilities to transmit
-     */
-    private static ChannelBuffer prepareBgpOpenCapabilities(
-                                        BgpSessionInfo localInfo) {
-        ChannelBuffer message =
-            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
-
-        //
-        // Write the Multiprotocol Extensions Capabilities
-        //
-
-        // IPv4 unicast
-        if (localInfo.ipv4Unicast()) {
-            message.writeByte(Capabilities.TYPE);               // Param type
-            message.writeByte(Capabilities.MIN_LENGTH +
-                              MultiprotocolExtensions.LENGTH);  // Param len
-            message.writeByte(MultiprotocolExtensions.CODE);    // Capab. code
-            message.writeByte(MultiprotocolExtensions.LENGTH);  // Capab. len
-            message.writeShort(MultiprotocolExtensions.AFI_IPV4);
-            message.writeByte(0);               // Reserved field
-            message.writeByte(MultiprotocolExtensions.SAFI_UNICAST);
-        }
-        // IPv4 multicast
-        if (localInfo.ipv4Multicast()) {
-            message.writeByte(Capabilities.TYPE);               // Param type
-            message.writeByte(Capabilities.MIN_LENGTH +
-                              MultiprotocolExtensions.LENGTH);  // Param len
-            message.writeByte(MultiprotocolExtensions.CODE);    // Capab. code
-            message.writeByte(MultiprotocolExtensions.LENGTH);  // Capab. len
-            message.writeShort(MultiprotocolExtensions.AFI_IPV4);
-            message.writeByte(0);               // Reserved field
-            message.writeByte(MultiprotocolExtensions.SAFI_MULTICAST);
-        }
-        // IPv6 unicast
-        if (localInfo.ipv6Unicast()) {
-            message.writeByte(Capabilities.TYPE);               // Param type
-            message.writeByte(Capabilities.MIN_LENGTH +
-                              MultiprotocolExtensions.LENGTH);  // Param len
-            message.writeByte(MultiprotocolExtensions.CODE);    // Capab. code
-            message.writeByte(MultiprotocolExtensions.LENGTH);  // Capab. len
-            message.writeShort(MultiprotocolExtensions.AFI_IPV6);
-            message.writeByte(0);               // Reserved field
-            message.writeByte(MultiprotocolExtensions.SAFI_UNICAST);
-        }
-        // IPv6 multicast
-        if (localInfo.ipv6Multicast()) {
-            message.writeByte(Capabilities.TYPE);               // Param type
-            message.writeByte(Capabilities.MIN_LENGTH +
-                              MultiprotocolExtensions.LENGTH);  // Param len
-            message.writeByte(MultiprotocolExtensions.CODE);    // Capab. code
-            message.writeByte(MultiprotocolExtensions.LENGTH);  // Capab. len
-            message.writeShort(MultiprotocolExtensions.AFI_IPV6);
-            message.writeByte(0);               // Reserved field
-            message.writeByte(MultiprotocolExtensions.SAFI_MULTICAST);
-        }
-
-        // 4 octet AS path capability
-        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) 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
deleted file mode 100644
index 3abdc79..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpRouteEntry.java
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * 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 static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.ArrayList;
-import java.util.Objects;
-
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.Ip4Address;
-import org.onosproject.sdnip.RouteEntry;
-import org.onosproject.sdnip.bgp.BgpConstants.Update;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Represents a route in BGP.
- */
-public class BgpRouteEntry extends RouteEntry {
-    private final BgpSession bgpSession; // The BGP Session the route was
-                                         // received on
-    private final byte origin;          // Route ORIGIN: IGP, EGP, INCOMPLETE
-    private final AsPath asPath;        // The AS Path
-    private final long localPref;       // The local preference for the route
-    private long multiExitDisc = Update.MultiExitDisc.LOWEST_MULTI_EXIT_DISC;
-
-    /**
-     * Class constructor.
-     *
-     * @param bgpSession the BGP Session the route was received on
-     * @param prefix the prefix of the route
-     * @param nextHop the next hop of the route
-     * @param origin the route origin: 0=IGP, 1=EGP, 2=INCOMPLETE
-     * @param asPath the AS path
-     * @param localPref the route local preference
-     */
-    public BgpRouteEntry(BgpSession bgpSession, IpPrefix prefix,
-                         IpAddress nextHop, byte origin,
-                         BgpRouteEntry.AsPath asPath, long localPref) {
-        super(prefix, nextHop);
-        this.bgpSession = checkNotNull(bgpSession);
-        this.origin = origin;
-        this.asPath = checkNotNull(asPath);
-        this.localPref = localPref;
-    }
-
-    /**
-     * Gets the BGP Session the route was received on.
-     *
-     * @return the BGP Session the route was received on
-     */
-    public BgpSession getBgpSession() {
-        return bgpSession;
-    }
-
-    /**
-     * Gets the route origin: 0=IGP, 1=EGP, 2=INCOMPLETE.
-     *
-     * @return the route origin: 0=IGP, 1=EGP, 2=INCOMPLETE
-     */
-    public byte getOrigin() {
-        return origin;
-    }
-
-    /**
-     * Gets the route AS path.
-     *
-     * @return the route AS path
-     */
-    public BgpRouteEntry.AsPath getAsPath() {
-        return asPath;
-    }
-
-    /**
-     * Gets the route local preference.
-     *
-     * @return the route local preference
-     */
-    public long getLocalPref() {
-        return localPref;
-    }
-
-    /**
-     * Gets the route MED (Multi-Exit Discriminator).
-     *
-     * @return the route MED (Multi-Exit Discriminator)
-     */
-    public long getMultiExitDisc() {
-        return multiExitDisc;
-    }
-
-    /**
-     * Sets the route MED (Multi-Exit Discriminator).
-     *
-     * @param multiExitDisc the route MED (Multi-Exit Discriminator) to set
-     */
-    void setMultiExitDisc(long multiExitDisc) {
-        this.multiExitDisc = multiExitDisc;
-    }
-
-    /**
-     * Tests whether the route is originated from the local AS.
-     * <p>
-     * The route is considered originated from the local AS if the AS Path
-     * is empty or if it begins with an AS_SET (after skipping
-     * AS_CONFED_SEQUENCE and AS_CONFED_SET).
-     * </p>
-     *
-     * @return true if the route is originated from the local AS, otherwise
-     * false
-     */
-    boolean isLocalRoute() {
-        PathSegment firstPathSegment = null;
-
-        // Find the first Path Segment by ignoring the AS_CONFED_* segments
-        for (PathSegment pathSegment : asPath.getPathSegments()) {
-            if ((pathSegment.getType() == Update.AsPath.AS_SET) ||
-                (pathSegment.getType() == Update.AsPath.AS_SEQUENCE)) {
-                firstPathSegment = pathSegment;
-                break;
-            }
-        }
-        if (firstPathSegment == null) {
-            return true;                // Local route: no path segments
-        }
-        // If the first path segment is AS_SET, the route is considered local
-        if (firstPathSegment.getType() == Update.AsPath.AS_SET) {
-            return true;
-        }
-
-        return false;                   // The route is not local
-    }
-
-    /**
-     * Gets the BGP Neighbor AS number the route was received from.
-     * <p>
-     * If the router is originated from the local AS, the return value is
-     * zero (BGP_AS_0).
-     * </p>
-     *
-     * @return the BGP Neighbor AS number the route was received from.
-     */
-    long getNeighborAs() {
-        PathSegment firstPathSegment = null;
-
-        if (isLocalRoute()) {
-            return BgpConstants.BGP_AS_0;
-        }
-
-        // Find the first Path Segment by ignoring the AS_CONFED_* segments
-        for (PathSegment pathSegment : asPath.getPathSegments()) {
-            if ((pathSegment.getType() == Update.AsPath.AS_SET) ||
-                (pathSegment.getType() == Update.AsPath.AS_SEQUENCE)) {
-                firstPathSegment = pathSegment;
-                break;
-            }
-        }
-        if (firstPathSegment == null) {
-            // NOTE: Shouldn't happen - should be captured by isLocalRoute()
-            return BgpConstants.BGP_AS_0;
-        }
-
-        if (firstPathSegment.getSegmentAsNumbers().isEmpty()) {
-            // NOTE: Shouldn't happen. Should check during the parsing.
-            return BgpConstants.BGP_AS_0;
-        }
-        return firstPathSegment.getSegmentAsNumbers().get(0);
-    }
-
-    /**
-     * Tests whether the AS Path contains a loop.
-     * <p>
-     * The test is done by comparing whether the AS Path contains the
-     * local AS number.
-     * </p>
-     *
-     * @param localAsNumber the local AS number to compare against
-     * @return true if the AS Path contains a loop, otherwise false
-     */
-    boolean hasAsPathLoop(long localAsNumber) {
-        for (PathSegment pathSegment : asPath.getPathSegments()) {
-            for (Long asNumber : pathSegment.getSegmentAsNumbers()) {
-                if (asNumber.equals(localAsNumber)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Compares this BGP route against another BGP route by using the
-     * BGP Decision Process.
-     * <p>
-     * NOTE: The comparison needs to be performed only on routes that have
-     * same IP Prefix.
-     * </p>
-     *
-     * @param other the BGP route to compare against
-     * @return true if this BGP route is better than the other BGP route
-     * or same, otherwise false
-     */
-    boolean isBetterThan(BgpRouteEntry other) {
-        if (this == other) {
-            return true;        // Return true if same route
-        }
-
-        // Compare the LOCAL_PREF values: larger is better
-        if (getLocalPref() != other.getLocalPref()) {
-            return (getLocalPref() > other.getLocalPref());
-        }
-
-        // Compare the AS number in the path: smaller is better
-        if (getAsPath().getAsPathLength() !=
-            other.getAsPath().getAsPathLength()) {
-            return getAsPath().getAsPathLength() <
-                other.getAsPath().getAsPathLength();
-        }
-
-        // Compare the Origin number: lower is better
-        if (getOrigin() != other.getOrigin()) {
-            return (getOrigin() < other.getOrigin());
-        }
-
-        // Compare the MED if the neighbor AS is same: larger is better
-        medLabel: {
-            if (isLocalRoute() || other.isLocalRoute()) {
-                // Compare MEDs for non-local routes only
-                break medLabel;
-            }
-            long thisNeighborAs = getNeighborAs();
-            if (thisNeighborAs != other.getNeighborAs()) {
-                break medLabel;             // AS number is different
-            }
-            if (thisNeighborAs == BgpConstants.BGP_AS_0) {
-                break medLabel;             // Invalid AS number
-            }
-
-            // Compare the MED
-            if (getMultiExitDisc() != other.getMultiExitDisc()) {
-                return (getMultiExitDisc() > other.getMultiExitDisc());
-            }
-        }
-
-        // Compare the peer BGP ID: lower is better
-        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().remoteInfo().ip4Address();
-        Ip4Address otherPeerAddress =
-            other.getBgpSession().remoteInfo().ip4Address();
-        if (!peerAddress.equals(otherPeerAddress)) {
-            return (peerAddress.compareTo(otherPeerAddress) < 0);
-        }
-
-        return true;            // Routes are same. Shouldn't happen?
-    }
-
-    /**
-     * A class to represent AS Path Segment.
-     */
-    public static class PathSegment {
-        // Segment type: AS_SET(1), AS_SEQUENCE(2), AS_CONFED_SEQUENCE(3),
-        // AS_CONFED_SET(4)
-        private final byte type;
-        private final ArrayList<Long> segmentAsNumbers;   // Segment AS numbers
-
-        /**
-         * Constructor.
-         *
-         * @param type the Path Segment Type: AS_SET(1), AS_SEQUENCE(2),
-         * AS_CONFED_SEQUENCE(3), AS_CONFED_SET(4)
-         * @param segmentAsNumbers the Segment AS numbers
-         */
-        PathSegment(byte type, ArrayList<Long> segmentAsNumbers) {
-            this.type = type;
-            this.segmentAsNumbers = checkNotNull(segmentAsNumbers);
-        }
-
-        /**
-         * Gets the Path Segment Type: AS_SET(1), AS_SEQUENCE(2),
-         * AS_CONFED_SEQUENCE(3), AS_CONFED_SET(4).
-         *
-         * @return the Path Segment Type: AS_SET(1), AS_SEQUENCE(2),
-         * AS_CONFED_SEQUENCE(3), AS_CONFED_SET(4)
-         */
-        public byte getType() {
-            return type;
-        }
-
-        /**
-         * Gets the Path Segment AS Numbers.
-         *
-         * @return the Path Segment AS Numbers
-         */
-        public ArrayList<Long> getSegmentAsNumbers() {
-            return segmentAsNumbers;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (this == other) {
-                return true;
-            }
-
-            if (!(other instanceof PathSegment)) {
-                return false;
-            }
-
-            PathSegment otherPathSegment = (PathSegment) other;
-            return Objects.equals(this.type, otherPathSegment.type) &&
-                Objects.equals(this.segmentAsNumbers,
-                               otherPathSegment.segmentAsNumbers);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type, segmentAsNumbers);
-        }
-
-        @Override
-        public String toString() {
-            return MoreObjects.toStringHelper(getClass())
-                .add("type", Update.AsPath.typeToString(type))
-                .add("segmentAsNumbers", this.segmentAsNumbers)
-                .toString();
-        }
-    }
-
-    /**
-     * A class to represent AS Path.
-     */
-    public static class AsPath {
-        private final ArrayList<PathSegment> pathSegments;
-        private final int asPathLength;         // Precomputed AS Path Length
-
-        /**
-         * Constructor.
-         *
-         * @param pathSegments the Path Segments of the Path
-         */
-         AsPath(ArrayList<PathSegment> pathSegments) {
-             this.pathSegments = checkNotNull(pathSegments);
-
-             //
-             // Precompute the AS Path Length:
-             // - AS_SET counts as 1
-             // - AS_SEQUENCE counts how many AS numbers are included
-             // - AS_CONFED_SEQUENCE and AS_CONFED_SET are ignored
-             //
-             int pl = 0;
-             for (PathSegment pathSegment : pathSegments) {
-                 switch (pathSegment.getType()) {
-                 case Update.AsPath.AS_SET:
-                     pl++;              // AS_SET counts as 1
-                     break;
-                 case Update.AsPath.AS_SEQUENCE:
-                     // Count each AS number
-                     pl += pathSegment.getSegmentAsNumbers().size();
-                     break;
-                 case Update.AsPath.AS_CONFED_SEQUENCE:
-                     break;             // Ignore
-                 case Update.AsPath.AS_CONFED_SET:
-                     break;             // Ignore
-                 default:
-                     // NOTE: What to do if the Path Segment type is unknown?
-                     break;
-                 }
-             }
-             asPathLength = pl;
-         }
-
-        /**
-         * Gets the AS Path Segments.
-         *
-         * @return the AS Path Segments
-         */
-        public ArrayList<PathSegment> getPathSegments() {
-            return pathSegments;
-        }
-
-        /**
-         * Gets the AS Path Length as considered by the BGP Decision Process.
-         *
-         * @return the AS Path Length as considered by the BGP Decision Process
-         */
-        int getAsPathLength() {
-            return asPathLength;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (this == other) {
-                return true;
-            }
-
-            if (!(other instanceof AsPath)) {
-                return false;
-            }
-
-            AsPath otherAsPath = (AsPath) other;
-            return Objects.equals(this.pathSegments, otherAsPath.pathSegments);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(pathSegments);
-        }
-
-        @Override
-        public String toString() {
-            return MoreObjects.toStringHelper(getClass())
-                .add("pathSegments", this.pathSegments)
-                .toString();
-        }
-    }
-
-    /**
-     * Compares whether two objects are equal.
-     * <p>
-     * NOTE: The bgpSession field is excluded from the comparison.
-     * </p>
-     *
-     * @return true if the two objects are equal, otherwise false.
-     */
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        }
-
-        //
-        // NOTE: Subclasses are considered as change of identity, hence
-        // equals() will return false if the class type doesn't match.
-        //
-        if (other == null || getClass() != other.getClass()) {
-            return false;
-        }
-
-        if (!super.equals(other)) {
-            return false;
-        }
-
-        // NOTE: The bgpSession field is excluded from the comparison
-        BgpRouteEntry otherRoute = (BgpRouteEntry) other;
-        return (this.origin == otherRoute.origin) &&
-            Objects.equals(this.asPath, otherRoute.asPath) &&
-            (this.localPref == otherRoute.localPref) &&
-            (this.multiExitDisc == otherRoute.multiExitDisc);
-    }
-
-    /**
-     * Computes the hash code.
-     * <p>
-     * NOTE: We return the base class hash code to avoid expensive computation
-     * </p>
-     *
-     * @return the object hash code
-     */
-    @Override
-    public int hashCode() {
-        return super.hashCode();
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass())
-            .add("prefix", prefix())
-            .add("nextHop", nextHop())
-            .add("bgpId", bgpSession.remoteInfo().bgpId())
-            .add("origin", Update.Origin.typeToString(origin))
-            .add("asPath", asPath)
-            .add("localPref", localPref)
-            .add("multiExitDisc", multiExitDisc)
-            .toString();
-    }
-}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpRouteSelector.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpRouteSelector.java
deleted file mode 100644
index 1569c07..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpRouteSelector.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.util.Collection;
-import java.util.LinkedList;
-
-import org.onlab.packet.IpPrefix;
-import org.onosproject.sdnip.RouteUpdate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Class to receive and process the BGP routes from each BGP Session/Peer.
- */
-class BgpRouteSelector {
-    private static final Logger log =
-        LoggerFactory.getLogger(BgpRouteSelector.class);
-
-    private BgpSessionManager bgpSessionManager;
-
-    /**
-     * Constructor.
-     *
-     * @param bgpSessionManager the BGP Session Manager to use
-     */
-    BgpRouteSelector(BgpSessionManager bgpSessionManager) {
-        this.bgpSessionManager = bgpSessionManager;
-    }
-
-    /**
-     * Processes route entry updates: added/updated and deleted route
-     * entries.
-     *
-     * @param bgpSession the BGP session the route entry updates were
-     * received on
-     * @param addedBgpRouteEntries the added/updated route entries to process
-     * @param deletedBgpRouteEntries the deleted route entries to process
-     */
-    synchronized void routeUpdates(BgpSession bgpSession,
-                        Collection<BgpRouteEntry> addedBgpRouteEntries,
-                        Collection<BgpRouteEntry> deletedBgpRouteEntries) {
-        Collection<RouteUpdate> routeUpdates = new LinkedList<>();
-        RouteUpdate routeUpdate;
-
-        if (bgpSessionManager.isShutdown()) {
-            return;         // Ignore any leftover updates if shutdown
-        }
-        // Process the deleted route entries
-        for (BgpRouteEntry bgpRouteEntry : deletedBgpRouteEntries) {
-            routeUpdate = processDeletedRoute(bgpSession, bgpRouteEntry);
-            if (routeUpdate != null) {
-                routeUpdates.add(routeUpdate);
-            }
-        }
-
-        // Process the added/updated route entries
-        for (BgpRouteEntry bgpRouteEntry : addedBgpRouteEntries) {
-            routeUpdate = processAddedRoute(bgpSession, bgpRouteEntry);
-            if (routeUpdate != null) {
-                routeUpdates.add(routeUpdate);
-            }
-        }
-        bgpSessionManager.getRouteListener().update(routeUpdates);
-    }
-
-    /**
-     * Processes an added/updated route entry.
-     *
-     * @param bgpSession the BGP session the route entry update was received on
-     * @param bgpRouteEntry the added/updated route entry
-     * @return the result route update that should be forwarded to the
-     * Route Listener, or null if no route update should be forwarded
-     */
-    private RouteUpdate processAddedRoute(BgpSession bgpSession,
-                                          BgpRouteEntry bgpRouteEntry) {
-        RouteUpdate routeUpdate;
-        BgpRouteEntry bestBgpRouteEntry =
-            bgpSessionManager.findBgpRoute(bgpRouteEntry.prefix());
-
-        //
-        // Install the new route entry if it is better than the
-        // current best route.
-        //
-        if ((bestBgpRouteEntry == null) ||
-            bgpRouteEntry.isBetterThan(bestBgpRouteEntry)) {
-            bgpSessionManager.addBgpRoute(bgpRouteEntry);
-            routeUpdate =
-                new RouteUpdate(RouteUpdate.Type.UPDATE, bgpRouteEntry);
-            return routeUpdate;
-        }
-
-        //
-        // If the route entry arrived on the same BGP Session as
-        // the current best route, then elect the next best route
-        // and install it.
-        //
-        if (bestBgpRouteEntry.getBgpSession() !=
-            bgpRouteEntry.getBgpSession()) {
-            return null;            // Nothing to do
-        }
-
-        // Find the next best route
-        bestBgpRouteEntry = findBestBgpRoute(bgpRouteEntry.prefix());
-        if (bestBgpRouteEntry == null) {
-            //
-            // TODO: Shouldn't happen. Install the new route as a
-            // pre-caution.
-            //
-            log.debug("BGP next best route for prefix {} is missing. " +
-                      "Adding the route that is currently processed.",
-                      bgpRouteEntry.prefix());
-            bestBgpRouteEntry = bgpRouteEntry;
-        }
-
-        // Install the next best route
-        bgpSessionManager.addBgpRoute(bestBgpRouteEntry);
-        routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
-                                      bestBgpRouteEntry);
-        return routeUpdate;
-    }
-
-    /**
-     * Processes a deleted route entry.
-     *
-     * @param bgpSession the BGP session the route entry update was received on
-     * @param bgpRouteEntry the deleted route entry
-     * @return the result route update that should be forwarded to the
-     * Route Listener, or null if no route update should be forwarded
-     */
-    private RouteUpdate processDeletedRoute(BgpSession bgpSession,
-                                            BgpRouteEntry bgpRouteEntry) {
-        RouteUpdate routeUpdate;
-        BgpRouteEntry bestBgpRouteEntry =
-            bgpSessionManager.findBgpRoute(bgpRouteEntry.prefix());
-
-        //
-        // Remove the route entry only if it was the best one.
-        // Install the the next best route if it exists.
-        //
-        // NOTE: We intentionally use "==" instead of method equals(),
-        // because we need to check whether this is same object.
-        //
-        if (bgpRouteEntry != bestBgpRouteEntry) {
-            return null;            // Nothing to do
-        }
-
-        //
-        // Find the next best route
-        //
-        bestBgpRouteEntry = findBestBgpRoute(bgpRouteEntry.prefix());
-        if (bestBgpRouteEntry != null) {
-            // Install the next best route
-            bgpSessionManager.addBgpRoute(bestBgpRouteEntry);
-            routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
-                                          bestBgpRouteEntry);
-            return routeUpdate;
-        }
-
-        //
-        // No route found. Remove the route entry
-        //
-        bgpSessionManager.removeBgpRoute(bgpRouteEntry.prefix());
-        routeUpdate = new RouteUpdate(RouteUpdate.Type.DELETE, bgpRouteEntry);
-        return routeUpdate;
-    }
-
-    /**
-     * Finds the best route entry among all BGP Sessions.
-     *
-     * @param prefix the prefix of the route
-     * @return the best route if found, otherwise null
-     */
-    private BgpRouteEntry findBestBgpRoute(IpPrefix prefix) {
-        BgpRouteEntry bestRoute = null;
-
-        // Iterate across all BGP Sessions and select the best route
-        for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
-            BgpRouteEntry route = bgpSession.findBgpRoute(prefix);
-            if (route == null) {
-                continue;
-            }
-            if ((bestRoute == null) || route.isBetterThan(bestRoute)) {
-                bestRoute = route;
-            }
-        }
-        return bestRoute;
-    }
-}
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
deleted file mode 100644
index ace6b53..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSession.java
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * 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.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.TimeUnit;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.channel.ExceptionEvent;
-import org.jboss.netty.channel.SimpleChannelHandler;
-import org.jboss.netty.util.HashedWheelTimer;
-import org.jboss.netty.util.Timeout;
-import org.jboss.netty.util.Timer;
-import org.jboss.netty.util.TimerTask;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.packet.Ip6Prefix;
-import org.onosproject.sdnip.bgp.BgpConstants.Notifications;
-import org.onosproject.sdnip.bgp.BgpConstants.Notifications.HoldTimerExpired;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Class for handling the BGP peer sessions.
- * There is one instance per each BGP peer session.
- */
-public class BgpSession extends SimpleChannelHandler {
-    private static final Logger log =
-        LoggerFactory.getLogger(BgpSession.class);
-
-    private final BgpSessionManager bgpSessionManager;
-
-    // Local flag to indicate the session is closed.
-    // It is used to avoid the Netty's asynchronous closing of a channel.
-    private boolean isClosed = false;
-
-    // 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();
-    private volatile Timeout keepaliveTimeout;  // Periodic KEEPALIVE
-    private volatile Timeout sessionTimeout;    // Session timeout
-
-    // BGP RIB-IN routing entries from this peer
-    private ConcurrentMap<Ip4Prefix, BgpRouteEntry> bgpRibIn4 =
-        new ConcurrentHashMap<>();
-    private ConcurrentMap<Ip6Prefix, BgpRouteEntry> bgpRibIn6 =
-        new ConcurrentHashMap<>();
-
-    /**
-     * Constructor for a given BGP Session Manager.
-     *
-     * @param bgpSessionManager the BGP Session Manager to use
-     */
-    BgpSession(BgpSessionManager bgpSessionManager) {
-        this.bgpSessionManager = bgpSessionManager;
-        this.localInfo = new BgpSessionInfo();
-        this.remoteInfo = new BgpSessionInfo();
-
-        // NOTE: We support only BGP4
-        this.localInfo.setBgpVersion(BgpConstants.BGP_VERSION);
-    }
-
-    /**
-     * Gets the BGP Session Manager.
-     *
-     * @return the BGP Session Manager
-     */
-    BgpSessionManager getBgpSessionManager() {
-        return bgpSessionManager;
-    }
-
-    /**
-     * 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
-     */
-    public Collection<BgpRouteEntry> getBgpRibIn4() {
-        return bgpRibIn4.values();
-    }
-
-    /**
-     * Gets the IPv6 BGP RIB-IN routing entries.
-     *
-     * @return the IPv6 BGP RIB-IN routing entries
-     */
-    public Collection<BgpRouteEntry> getBgpRibIn6() {
-        return bgpRibIn6.values();
-    }
-
-    /**
-     * Finds an IPv4 BGP routing entry for a prefix in the IPv4 BGP RIB-IN.
-     *
-     * @param prefix the IPv4 prefix of the route to search for
-     * @return the IPv4 BGP routing entry if found, otherwise null
-     */
-    public BgpRouteEntry findBgpRoute(Ip4Prefix prefix) {
-        return bgpRibIn4.get(prefix);
-    }
-
-    /**
-     * Finds an IPv6 BGP routing entry for a prefix in the IPv6 BGP RIB-IN.
-     *
-     * @param prefix the IPv6 prefix of the route to search for
-     * @return the IPv6 BGP routing entry if found, otherwise null
-     */
-    public BgpRouteEntry findBgpRoute(Ip6Prefix prefix) {
-        return bgpRibIn6.get(prefix);
-    }
-
-    /**
-     * Finds a BGP routing entry for a prefix in the BGP RIB-IN. The prefix
-     * can be either IPv4 or IPv6.
-     *
-     * @param prefix the IP prefix of the route to search for
-     * @return the BGP routing entry if found, otherwise null
-     */
-    public BgpRouteEntry findBgpRoute(IpPrefix prefix) {
-        if (prefix.version() == Ip4Address.VERSION) {
-            // IPv4 prefix
-            Ip4Prefix ip4Prefix = prefix.getIp4Prefix();
-            return bgpRibIn4.get(ip4Prefix);
-        }
-
-        // IPv6 prefix
-        Ip6Prefix ip6Prefix = prefix.getIp6Prefix();
-        return bgpRibIn6.get(ip6Prefix);
-    }
-
-    /**
-     * Adds a BGP route. The route can be either IPv4 or IPv6.
-     *
-     * @param bgpRouteEntry the BGP route entry to use
-     */
-    void addBgpRoute(BgpRouteEntry bgpRouteEntry) {
-        if (bgpRouteEntry.version() == Ip4Address.VERSION) {
-            // IPv4 route
-            Ip4Prefix ip4Prefix = bgpRouteEntry.prefix().getIp4Prefix();
-            bgpRibIn4.put(ip4Prefix, bgpRouteEntry);
-        } else {
-            // IPv6 route
-            Ip6Prefix ip6Prefix = bgpRouteEntry.prefix().getIp6Prefix();
-            bgpRibIn6.put(ip6Prefix, bgpRouteEntry);
-        }
-    }
-
-    /**
-     * Removes an IPv4 BGP route for a prefix.
-     *
-     * @param prefix the prefix to use
-     * @return true if the route was found and removed, otherwise false
-     */
-    boolean removeBgpRoute(Ip4Prefix prefix) {
-        return (bgpRibIn4.remove(prefix) != null);
-    }
-
-    /**
-     * Removes an IPv6 BGP route for a prefix.
-     *
-     * @param prefix the prefix to use
-     * @return true if the route was found and removed, otherwise false
-     */
-    boolean removeBgpRoute(Ip6Prefix prefix) {
-        return (bgpRibIn6.remove(prefix) != null);
-    }
-
-    /**
-     * Removes a BGP route for a prefix. The prefix can be either IPv4 or IPv6.
-     *
-     * @param prefix the prefix to use
-     * @return true if the route was found and removed, otherwise false
-     */
-    boolean removeBgpRoute(IpPrefix prefix) {
-        if (prefix.version() == Ip4Address.VERSION) {
-            return (bgpRibIn4.remove(prefix.getIp4Prefix()) != null);   // IPv4
-        }
-        return (bgpRibIn6.remove(prefix.getIp6Prefix()) != null);       // IPv6
-    }
-
-    /**
-     * Tests whether the session is closed.
-     * <p>
-     * NOTE: We use this method to avoid the Netty's asynchronous closing
-     * of a channel.
-     * </p>
-     * @return true if the session is closed
-     */
-    boolean isClosed() {
-        return isClosed;
-    }
-
-    /**
-     * Closes the session.
-     *
-     * @param ctx the Channel Handler Context
-     */
-    void closeSession(ChannelHandlerContext ctx) {
-        timer.stop();
-        closeChannel(ctx);
-    }
-
-    /**
-     * Closes the Netty channel.
-     *
-     * @param ctx the Channel Handler Context
-     */
-    void closeChannel(ChannelHandlerContext ctx) {
-        isClosed = true;
-        ctx.getChannel().close();
-    }
-
-    @Override
-    public void channelOpen(ChannelHandlerContext ctx,
-                            ChannelStateEvent channelEvent) {
-        bgpSessionManager.addSessionChannel(channelEvent.getChannel());
-    }
-
-    @Override
-    public void channelClosed(ChannelHandlerContext ctx,
-                              ChannelStateEvent channelEvent) {
-        bgpSessionManager.removeSessionChannel(channelEvent.getChannel());
-    }
-
-    @Override
-    public void channelConnected(ChannelHandlerContext ctx,
-                                 ChannelStateEvent channelEvent) {
-        localInfo.setAddress(ctx.getChannel().getLocalAddress());
-        remoteInfo.setAddress(ctx.getChannel().getRemoteAddress());
-
-        // Assign the local and remote IPv4 addresses
-        InetAddress inetAddr;
-        if (localInfo.address() instanceof InetSocketAddress) {
-            inetAddr = ((InetSocketAddress) localInfo.address()).getAddress();
-            localInfo.setIp4Address(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 {}",
-                  remoteInfo.address(), localInfo.address());
-        if (!bgpSessionManager.peerConnected(this)) {
-            log.debug("Cannot setup BGP Session Connection from {}. Closing...",
-                      remoteInfo.address());
-            ctx.getChannel().close();
-        }
-
-        //
-        // Assign the local BGP ID
-        // NOTE: This should be configuration-based
-        //
-        localInfo.setBgpId(bgpSessionManager.getMyBgpId());
-    }
-
-    @Override
-    public void channelDisconnected(ChannelHandlerContext ctx,
-                                    ChannelStateEvent channelEvent) {
-        log.debug("BGP Session Disconnected from {} on {}",
-                  ctx.getChannel().getRemoteAddress(),
-                  ctx.getChannel().getLocalAddress());
-        processChannelDisconnected();
-    }
-
-    @Override
-    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
-        log.debug("BGP Session Exception Caught from {} on {}: {}",
-                  ctx.getChannel().getRemoteAddress(),
-                  ctx.getChannel().getLocalAddress(),
-                  e);
-        processChannelDisconnected();
-    }
-
-    /**
-     * Processes the channel being disconnected.
-     */
-    private void processChannelDisconnected() {
-        //
-        // Withdraw the routes advertised by this BGP peer
-        //
-        // NOTE: We must initialize the RIB-IN before propagating the withdraws
-        // for further processing. Otherwise, the BGP Decision Process
-        // will use those routes again.
-        //
-        Collection<BgpRouteEntry> deletedRoutes4 = bgpRibIn4.values();
-        Collection<BgpRouteEntry> deletedRoutes6 = bgpRibIn6.values();
-        bgpRibIn4 = new ConcurrentHashMap<>();
-        bgpRibIn6 = new ConcurrentHashMap<>();
-
-        // Push the updates to the BGP Merged RIB
-        BgpRouteSelector bgpRouteSelector =
-            bgpSessionManager.getBgpRouteSelector();
-        Collection<BgpRouteEntry> addedRoutes = Collections.emptyList();
-        bgpRouteSelector.routeUpdates(this, addedRoutes, deletedRoutes4);
-        bgpRouteSelector.routeUpdates(this, addedRoutes, deletedRoutes6);
-
-        bgpSessionManager.peerDisconnected(this);
-    }
-
-    /**
-     * Restarts the BGP KeepaliveTimer.
-     *
-     * @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
-        }
-        keepaliveTimeout = timer.newTimeout(new TransmitKeepaliveTask(ctx),
-                                            localKeepaliveInterval,
-                                            TimeUnit.SECONDS);
-    }
-
-    /**
-     * Task class for transmitting KEEPALIVE messages.
-     */
-    private final class TransmitKeepaliveTask implements TimerTask {
-        private final ChannelHandlerContext ctx;
-
-        /**
-         * Constructor for given Channel Handler Context.
-         *
-         * @param ctx the Channel Handler Context to use
-         */
-        TransmitKeepaliveTask(ChannelHandlerContext ctx) {
-            this.ctx = ctx;
-        }
-
-        @Override
-        public void run(Timeout timeout) throws Exception {
-            if (timeout.isCancelled()) {
-                return;
-            }
-            if (!ctx.getChannel().isOpen()) {
-                return;
-            }
-
-            // Transmit the KEEPALIVE
-            ChannelBuffer txMessage = BgpKeepalive.prepareBgpKeepalive();
-            ctx.getChannel().write(txMessage);
-
-            // Restart the KEEPALIVE timer
-            restartKeepaliveTimer(ctx);
-        }
-    }
-
-    /**
-     * Restarts the BGP Session Timeout Timer.
-     *
-     * @param ctx the Channel Handler Context to use
-     */
-    void restartSessionTimeoutTimer(ChannelHandlerContext ctx) {
-        if (remoteInfo.holdtime() == 0) {
-            return;                 // Nothing to do
-        }
-        if (sessionTimeout != null) {
-            sessionTimeout.cancel();
-        }
-        sessionTimeout = timer.newTimeout(new SessionTimeoutTask(ctx),
-                                          remoteInfo.holdtime(),
-                                          TimeUnit.SECONDS);
-    }
-
-    /**
-     * Task class for BGP Session timeout.
-     */
-    private final class SessionTimeoutTask implements TimerTask {
-        private final ChannelHandlerContext ctx;
-
-        /**
-         * Constructor for given Channel Handler Context.
-         *
-         * @param ctx the Channel Handler Context to use
-         */
-        SessionTimeoutTask(ChannelHandlerContext ctx) {
-            this.ctx = ctx;
-        }
-
-        @Override
-        public void run(Timeout timeout) throws Exception {
-            if (timeout.isCancelled()) {
-                return;
-            }
-            if (!ctx.getChannel().isOpen()) {
-                return;
-            }
-
-            log.debug("BGP Session Timeout: peer {}", remoteInfo.address());
-            //
-            // ERROR: Invalid Optional Parameter Length field: Unspecific
-            //
-            // Send NOTIFICATION and close the connection
-            int errorCode = HoldTimerExpired.ERROR_CODE;
-            int errorSubcode = Notifications.ERROR_SUBCODE_UNSPECIFIC;
-            ChannelBuffer txMessage =
-                BgpNotification.prepareBgpNotification(errorCode, errorSubcode,
-                                                       null);
-            ctx.getChannel().write(txMessage);
-            closeChannel(ctx);
-        }
-    }
-}
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
deleted file mode 100644
index a492d80..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSessionInfo.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 2ca2972..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpSessionManager.java
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * 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.bootstrap.ServerBootstrap;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelException;
-import org.jboss.netty.channel.ChannelFactory;
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.channel.ChannelPipelineFactory;
-import org.jboss.netty.channel.Channels;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.channel.group.DefaultChannelGroup;
-import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.packet.Ip6Prefix;
-import org.onlab.packet.IpPrefix;
-import org.onosproject.sdnip.RouteListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.Collection;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.concurrent.Executors.newCachedThreadPool;
-import static org.onlab.util.Tools.namedThreads;
-
-/**
- * BGP Session Manager class.
- */
-public class BgpSessionManager {
-    private static final Logger log =
-            LoggerFactory.getLogger(BgpSessionManager.class);
-
-    boolean isShutdown = true;
-    private Channel serverChannel;     // Listener for incoming BGP connections
-    private ServerBootstrap serverBootstrap;
-    private ChannelGroup allChannels = new DefaultChannelGroup();
-    private ConcurrentMap<SocketAddress, BgpSession> bgpSessions =
-            new ConcurrentHashMap<>();
-    private Ip4Address myBgpId;        // Same BGP ID for all peers
-
-    private BgpRouteSelector bgpRouteSelector = new BgpRouteSelector(this);
-    private ConcurrentMap<Ip4Prefix, BgpRouteEntry> bgpRoutes4 =
-            new ConcurrentHashMap<>();
-    private ConcurrentMap<Ip6Prefix, BgpRouteEntry> bgpRoutes6 =
-            new ConcurrentHashMap<>();
-
-    private final RouteListener routeListener;
-
-    /**
-     * Constructor for given route listener.
-     *
-     * @param routeListener the route listener to use
-     */
-    public BgpSessionManager(RouteListener routeListener) {
-        this.routeListener = checkNotNull(routeListener);
-    }
-
-    /**
-     * Checks whether the BGP Session Manager is shutdown.
-     *
-     * @return true if the BGP Session Manager is shutdown, otherwise false
-     */
-    boolean isShutdown() {
-        return this.isShutdown;
-    }
-
-    /**
-     * Gets the route listener.
-     *
-     * @return the route listener to use
-     */
-    RouteListener getRouteListener() {
-        return routeListener;
-    }
-
-    /**
-     * Gets the BGP sessions.
-     *
-     * @return the BGP sessions
-     */
-    public Collection<BgpSession> getBgpSessions() {
-        return bgpSessions.values();
-    }
-
-    /**
-     * Gets the selected IPv4 BGP routes among all BGP sessions.
-     *
-     * @return the selected IPv4 BGP routes among all BGP sessions
-     */
-    public Collection<BgpRouteEntry> getBgpRoutes4() {
-        return bgpRoutes4.values();
-    }
-
-    /**
-     * Gets the selected IPv6 BGP routes among all BGP sessions.
-     *
-     * @return the selected IPv6 BGP routes among all BGP sessions
-     */
-    public Collection<BgpRouteEntry> getBgpRoutes6() {
-        return bgpRoutes6.values();
-    }
-
-    /**
-     * Finds a BGP route for a prefix. The prefix can be either IPv4 or IPv6.
-     *
-     * @param prefix the prefix to use
-     * @return the BGP route if found, otherwise null
-     */
-    BgpRouteEntry findBgpRoute(IpPrefix prefix) {
-        if (prefix.version() == Ip4Address.VERSION) {
-            return bgpRoutes4.get(prefix.getIp4Prefix());               // IPv4
-        }
-        return bgpRoutes6.get(prefix.getIp6Prefix());                   // IPv6
-    }
-
-    /**
-     * Adds a BGP route. The route can be either IPv4 or IPv6.
-     *
-     * @param bgpRouteEntry the BGP route entry to use
-     */
-    void addBgpRoute(BgpRouteEntry bgpRouteEntry) {
-        if (bgpRouteEntry.version() == Ip4Address.VERSION) {
-            bgpRoutes4.put(bgpRouteEntry.prefix().getIp4Prefix(),       // IPv4
-                           bgpRouteEntry);
-        } else {
-            bgpRoutes6.put(bgpRouteEntry.prefix().getIp6Prefix(),       // IPv6
-                           bgpRouteEntry);
-        }
-    }
-
-    /**
-     * Removes a BGP route for a prefix. The prefix can be either IPv4 or IPv6.
-     *
-     * @param prefix the prefix to use
-     * @return true if the route was found and removed, otherwise false
-     */
-    boolean removeBgpRoute(IpPrefix prefix) {
-        if (prefix.version() == Ip4Address.VERSION) {
-            return (bgpRoutes4.remove(prefix.getIp4Prefix()) != null);  // IPv4
-        }
-        return (bgpRoutes6.remove(prefix.getIp6Prefix()) != null);      // IPv6
-    }
-
-    /**
-     * Adds the channel for a BGP session.
-     *
-     * @param channel the channel to add
-     */
-    void addSessionChannel(Channel channel) {
-        allChannels.add(channel);
-    }
-
-    /**
-     * Removes the channel for a BGP session.
-     *
-     * @param channel the channel to remove
-     */
-    void removeSessionChannel(Channel channel) {
-        allChannels.remove(channel);
-    }
-
-    /**
-     * Processes the connection from a BGP peer.
-     *
-     * @param bgpSession the BGP session for the peer
-     * @return true if the connection can be established, otherwise false
-     */
-    boolean peerConnected(BgpSession bgpSession) {
-
-        // Test whether there is already a session from the same remote
-        if (bgpSessions.get(bgpSession.remoteInfo().address()) != null) {
-            return false;               // Duplicate BGP session
-        }
-        bgpSessions.put(bgpSession.remoteInfo().address(), bgpSession);
-
-        //
-        // If the first connection, set my BGP ID to the local address
-        // of the socket.
-        //
-        if (bgpSession.localInfo().address() instanceof InetSocketAddress) {
-            InetAddress inetAddr =
-                ((InetSocketAddress) bgpSession.localInfo().address()).getAddress();
-            Ip4Address ip4Address = Ip4Address.valueOf(inetAddr.getAddress());
-            updateMyBgpId(ip4Address);
-        }
-        return true;
-    }
-
-    /**
-     * Processes the disconnection from a BGP peer.
-     *
-     * @param bgpSession the BGP session for the peer
-     */
-    void peerDisconnected(BgpSession bgpSession) {
-        bgpSessions.remove(bgpSession.remoteInfo().address());
-    }
-
-    /**
-     * Conditionally updates the local BGP ID if it wasn't set already.
-     * <p/>
-     * NOTE: A BGP instance should use same BGP ID across all BGP sessions.
-     *
-     * @param ip4Address the IPv4 address to use as BGP ID
-     */
-    private synchronized void updateMyBgpId(Ip4Address ip4Address) {
-        if (myBgpId == null) {
-            myBgpId = ip4Address;
-            log.debug("BGP: My BGP ID is {}", myBgpId);
-        }
-    }
-
-    /**
-     * Gets the local BGP Identifier as an IPv4 address.
-     *
-     * @return the local BGP Identifier as an IPv4 address
-     */
-    Ip4Address getMyBgpId() {
-        return myBgpId;
-    }
-
-    /**
-     * Gets the BGP Route Selector.
-     *
-     * @return the BGP Route Selector
-     */
-    BgpRouteSelector getBgpRouteSelector() {
-        return bgpRouteSelector;
-    }
-
-    /**
-     * Starts up BGP Session Manager operation.
-     *
-     * @param listenPortNumber the port number to listen on. By default
-     *                         it should be BgpConstants.BGP_PORT (179)
-     */
-    public void start(int listenPortNumber) {
-        log.debug("BGP Session Manager start.");
-        isShutdown = false;
-
-        ChannelFactory channelFactory = new NioServerSocketChannelFactory(
-                newCachedThreadPool(namedThreads("onos-bgp-sm-boss-%d")),
-                newCachedThreadPool(namedThreads("onos-bgp-sm-worker-%d")));
-        ChannelPipelineFactory pipelineFactory = new ChannelPipelineFactory() {
-            @Override
-            public ChannelPipeline getPipeline() throws Exception {
-                // Allocate a new session per connection
-                BgpSession bgpSessionHandler =
-                        new BgpSession(BgpSessionManager.this);
-                BgpFrameDecoder bgpFrameDecoder =
-                        new BgpFrameDecoder(bgpSessionHandler);
-
-                // Setup the processing pipeline
-                ChannelPipeline pipeline = Channels.pipeline();
-                pipeline.addLast("BgpFrameDecoder", bgpFrameDecoder);
-                pipeline.addLast("BgpSession", bgpSessionHandler);
-                return pipeline;
-            }
-        };
-        InetSocketAddress listenAddress =
-                new InetSocketAddress(listenPortNumber);
-
-        serverBootstrap = new ServerBootstrap(channelFactory);
-        // serverBootstrap.setOptions("reuseAddr", true);
-        serverBootstrap.setOption("child.keepAlive", true);
-        serverBootstrap.setOption("child.tcpNoDelay", true);
-        serverBootstrap.setPipelineFactory(pipelineFactory);
-        try {
-            serverChannel = serverBootstrap.bind(listenAddress);
-            allChannels.add(serverChannel);
-        } catch (ChannelException e) {
-            log.debug("Exception binding to BGP port {}: ",
-                      listenAddress.getPort(), e);
-        }
-    }
-
-    /**
-     * Stops the BGP Session Manager operation.
-     */
-    public void stop() {
-        isShutdown = true;
-        allChannels.close().awaitUninterruptibly();
-        serverBootstrap.releaseExternalResources();
-    }
-}
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
deleted file mode 100644
index 2068324..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/BgpUpdate.java
+++ /dev/null
@@ -1,1699 +0,0 @@
-/*
- * 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.onlab.packet.Ip6Address;
-import org.onlab.packet.Ip6Prefix;
-import org.onosproject.sdnip.bgp.BgpConstants.Notifications.UpdateMessageError;
-import org.onosproject.sdnip.bgp.BgpConstants.Open.Capabilities.MultiprotocolExtensions;
-import org.onosproject.sdnip.bgp.BgpConstants.Update;
-import org.onosproject.sdnip.bgp.BgpConstants.Update.AsPath;
-import org.onosproject.sdnip.bgp.BgpMessage.BgpParseException;
-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) {
-        DecodedBgpRoutes decodedBgpRoutes = new DecodedBgpRoutes();
-
-        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.remoteInfo().address(),
-                      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.remoteInfo().address());
-
-        //
-        // 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 = parsePackedIp4Prefixes(withdrawnRoutesLength,
-                                                       message);
-        } catch (BgpParseException e) {
-            // ERROR: Invalid Network Field
-            log.debug("Exception parsing Withdrawn Prefixes from BGP peer {}: ",
-                      bgpSession.remoteInfo().bgpId(), e);
-            actionsBgpUpdateInvalidNetworkField(bgpSession, ctx);
-            return;
-        }
-        for (Ip4Prefix prefix : withdrawnPrefixes) {
-            log.debug("BGP RX UPDATE message WITHDRAWN from {}: {}",
-                      bgpSession.remoteInfo().address(), prefix);
-            BgpRouteEntry bgpRouteEntry = bgpSession.findBgpRoute(prefix);
-            if (bgpRouteEntry != null) {
-                decodedBgpRoutes.deletedUnicastRoutes4.put(prefix,
-                                                           bgpRouteEntry);
-            }
-        }
-
-        //
-        // Parse the Path Attributes
-        //
-        try {
-            parsePathAttributes(bgpSession, ctx, message, decodedBgpRoutes);
-        } catch (BgpParseException e) {
-            log.debug("Exception parsing Path Attributes from BGP peer {}: ",
-                      bgpSession.remoteInfo().bgpId(), e);
-            // NOTE: The session was already closed, so nothing else to do
-            return;
-        }
-
-        //
-        // Update the BGP RIB-IN
-        //
-        for (Ip4Prefix ip4Prefix :
-                 decodedBgpRoutes.deletedUnicastRoutes4.keySet()) {
-            bgpSession.removeBgpRoute(ip4Prefix);
-        }
-        //
-        for (BgpRouteEntry bgpRouteEntry :
-                 decodedBgpRoutes.addedUnicastRoutes4.values()) {
-            bgpSession.addBgpRoute(bgpRouteEntry);
-        }
-        //
-        for (Ip6Prefix ip6Prefix :
-                 decodedBgpRoutes.deletedUnicastRoutes6.keySet()) {
-            bgpSession.removeBgpRoute(ip6Prefix);
-        }
-        //
-        for (BgpRouteEntry bgpRouteEntry :
-                 decodedBgpRoutes.addedUnicastRoutes6.values()) {
-            bgpSession.addBgpRoute(bgpRouteEntry);
-        }
-
-        //
-        // Push the updates to the BGP Merged RIB
-        //
-        BgpRouteSelector bgpRouteSelector =
-            bgpSession.getBgpSessionManager().getBgpRouteSelector();
-        bgpRouteSelector.routeUpdates(bgpSession,
-                                decodedBgpRoutes.addedUnicastRoutes4.values(),
-                                decodedBgpRoutes.deletedUnicastRoutes4.values());
-        bgpRouteSelector.routeUpdates(bgpSession,
-                                decodedBgpRoutes.addedUnicastRoutes6.values(),
-                                decodedBgpRoutes.deletedUnicastRoutes6.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
-     * @param decodedBgpRoutes the container to store the decoded BGP Route
-     * Entries. It might already contain some route entries such as withdrawn
-     * IPv4 prefixes
-     * @throws BgpParseException
-     */
-    // CHECKSTYLE IGNORE MethodLength FOR NEXT 300 LINES
-    private static void parsePathAttributes(
-                                        BgpSession bgpSession,
-                                        ChannelHandlerContext ctx,
-                                        ChannelBuffer message,
-                                        DecodedBgpRoutes decodedBgpRoutes)
-        throws BgpParseException {
-
-        //
-        // Parsed values
-        //
-        Short origin = -1;                      // Mandatory
-        BgpRouteEntry.AsPath asPath = null;     // Mandatory
-        // Legacy NLRI (RFC 4271). Mandatory NEXT_HOP if legacy NLRI is used
-        MpNlri legacyNlri = new MpNlri(MultiprotocolExtensions.AFI_IPV4,
-                                       MultiprotocolExtensions.SAFI_UNICAST);
-        long multiExitDisc =                    // Optional
-            Update.MultiExitDisc.LOWEST_MULTI_EXIT_DISC;
-        Long localPref = null;                  // Mandatory
-        Long aggregatorAsNumber = null;         // Optional: unused
-        Ip4Address aggregatorIpAddress = null;  // Optional: unused
-        Collection<MpNlri> mpNlriReachList = new ArrayList<>();   // Optional
-        Collection<MpNlri> mpNlriUnreachList = new ArrayList<>(); // Optional
-
-        //
-        // 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;
-        }
-
-        //
-        // 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 Update.Origin.TYPE:
-                // Attribute Type Code ORIGIN
-                origin = parseAttributeTypeOrigin(bgpSession, ctx,
-                                                  attrTypeCode, attrLen,
-                                                  attrFlags, message);
-                break;
-
-            case Update.AsPath.TYPE:
-                // Attribute Type Code AS_PATH
-                asPath = parseAttributeTypeAsPath(bgpSession, ctx,
-                                                  attrTypeCode, attrLen,
-                                                  attrFlags, message);
-                break;
-
-            case Update.NextHop.TYPE:
-                // Attribute Type Code NEXT_HOP
-                legacyNlri.nextHop4 =
-                    parseAttributeTypeNextHop(bgpSession, ctx,
-                                              attrTypeCode, attrLen,
-                                              attrFlags, message);
-                break;
-
-            case Update.MultiExitDisc.TYPE:
-                // Attribute Type Code MULTI_EXIT_DISC
-                multiExitDisc =
-                    parseAttributeTypeMultiExitDisc(bgpSession, ctx,
-                                                    attrTypeCode, attrLen,
-                                                    attrFlags, message);
-                break;
-
-            case Update.LocalPref.TYPE:
-                // Attribute Type Code LOCAL_PREF
-                localPref =
-                    parseAttributeTypeLocalPref(bgpSession, ctx,
-                                                attrTypeCode, attrLen,
-                                                attrFlags, message);
-                break;
-
-            case 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 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;
-
-            case Update.MpReachNlri.TYPE:
-                // Attribute Type Code MP_REACH_NLRI
-                MpNlri mpNlriReach =
-                    parseAttributeTypeMpReachNlri(bgpSession, ctx,
-                                                  attrTypeCode,
-                                                  attrLen,
-                                                  attrFlags, message);
-                if (mpNlriReach != null) {
-                    mpNlriReachList.add(mpNlriReach);
-                }
-                break;
-
-            case Update.MpUnreachNlri.TYPE:
-                // Attribute Type Code MP_UNREACH_NLRI
-                MpNlri mpNlriUnreach =
-                    parseAttributeTypeMpUnreachNlri(bgpSession, ctx,
-                                                    attrTypeCode, attrLen,
-                                                    attrFlags, message);
-                if (mpNlriUnreach != null) {
-                    mpNlriUnreachList.add(mpNlriUnreach);
-                }
-                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.remoteInfo().address(), attrTypeCode);
-                message.skipBytes(attrLen);
-                break;
-            }
-        }
-
-        //
-        // Parse the NLRI (Network Layer Reachability Information)
-        //
-        int nlriLength = message.readableBytes();
-        try {
-            Collection<Ip4Prefix> addedPrefixes4 =
-                parsePackedIp4Prefixes(nlriLength, message);
-            // Store it inside the legacy NLRI wrapper
-            legacyNlri.nlri4 = addedPrefixes4;
-        } catch (BgpParseException e) {
-            // ERROR: Invalid Network Field
-            log.debug("Exception parsing NLRI from BGP peer {}: ",
-                      bgpSession.remoteInfo().bgpId(), e);
-            actionsBgpUpdateInvalidNetworkField(bgpSession, ctx);
-            // Rethrow the exception
-            throw e;
-        }
-
-        // Verify the Well-known Attributes
-        verifyBgpUpdateWellKnownAttributes(bgpSession, ctx, origin, asPath,
-                                           localPref, legacyNlri,
-                                           mpNlriReachList);
-
-        //
-        // Generate the deleted routes
-        //
-        for (MpNlri mpNlri : mpNlriUnreachList) {
-            BgpRouteEntry bgpRouteEntry;
-
-            // The deleted IPv4 routes
-            for (Ip4Prefix prefix : mpNlri.nlri4) {
-                bgpRouteEntry = bgpSession.findBgpRoute(prefix);
-                if (bgpRouteEntry != null) {
-                    decodedBgpRoutes.deletedUnicastRoutes4.put(prefix,
-                                                               bgpRouteEntry);
-                }
-            }
-
-            // The deleted IPv6 routes
-            for (Ip6Prefix prefix : mpNlri.nlri6) {
-                bgpRouteEntry = bgpSession.findBgpRoute(prefix);
-                if (bgpRouteEntry != null) {
-                    decodedBgpRoutes.deletedUnicastRoutes6.put(prefix,
-                                                               bgpRouteEntry);
-                }
-            }
-        }
-
-        //
-        // Generate the added routes
-        //
-        mpNlriReachList.add(legacyNlri);
-        for (MpNlri mpNlri : mpNlriReachList) {
-            BgpRouteEntry bgpRouteEntry;
-
-            // The added IPv4 routes
-            for (Ip4Prefix prefix : mpNlri.nlri4) {
-                bgpRouteEntry =
-                    new BgpRouteEntry(bgpSession, prefix, mpNlri.nextHop4,
-                                      origin.byteValue(), asPath, localPref);
-                bgpRouteEntry.setMultiExitDisc(multiExitDisc);
-                if (bgpRouteEntry.hasAsPathLoop(bgpSession.localInfo().asNumber())) {
-                    log.debug("BGP RX UPDATE message IGNORED from {}: {} " +
-                              "nextHop {}: contains AS Path loop",
-                              bgpSession.remoteInfo().address(), prefix,
-                              mpNlri.nextHop4);
-                    continue;
-                } else {
-                    log.debug("BGP RX UPDATE message ADDED from {}: {} nextHop {}",
-                              bgpSession.remoteInfo().address(), prefix,
-                              mpNlri.nextHop4);
-                }
-                // Remove from the collection of deleted routes
-                decodedBgpRoutes.deletedUnicastRoutes4.remove(prefix);
-                decodedBgpRoutes.addedUnicastRoutes4.put(prefix,
-                                                         bgpRouteEntry);
-            }
-
-            // The added IPv6 routes
-            for (Ip6Prefix prefix : mpNlri.nlri6) {
-                bgpRouteEntry =
-                    new BgpRouteEntry(bgpSession, prefix, mpNlri.nextHop6,
-                                      origin.byteValue(), asPath, localPref);
-                bgpRouteEntry.setMultiExitDisc(multiExitDisc);
-                if (bgpRouteEntry.hasAsPathLoop(bgpSession.localInfo().asNumber())) {
-                    log.debug("BGP RX UPDATE message IGNORED from {}: {} " +
-                              "nextHop {}: contains AS Path loop",
-                              bgpSession.remoteInfo().address(), prefix,
-                              mpNlri.nextHop6);
-                    continue;
-                } else {
-                    log.debug("BGP RX UPDATE message ADDED from {}: {} nextHop {}",
-                              bgpSession.remoteInfo().address(), prefix,
-                              mpNlri.nextHop6);
-                }
-                // Remove from the collection of deleted routes
-                decodedBgpRoutes.deletedUnicastRoutes6.remove(prefix);
-                decodedBgpRoutes.addedUnicastRoutes6.put(prefix,
-                                                         bgpRouteEntry);
-            }
-        }
-    }
-
-    /**
-     * 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 localPref the LOCAL_PREF required attribute
-     * @param legacyNlri the legacy NLRI. Encapsulates the NEXT_HOP well-known
-     * mandatory attribute (mandatory if legacy NLRI is used).
-     * @param mpNlriReachList the Multiprotocol NLRI attributes
-     * @throws BgpParseException
-     */
-    private static void verifyBgpUpdateWellKnownAttributes(
-                                BgpSession bgpSession,
-                                ChannelHandlerContext ctx,
-                                Short origin,
-                                BgpRouteEntry.AsPath asPath,
-                                Long localPref,
-                                MpNlri legacyNlri,
-                                Collection<MpNlri> mpNlriReachList)
-        throws BgpParseException {
-        boolean hasNlri = false;
-        boolean hasLegacyNlri = false;
-
-        //
-        // Convenience flags that are used to check for missing attributes.
-        //
-        // NOTE: The hasLegacyNlri flag is always set to true if the
-        // Multiprotocol Extensions are not enabled, even if the UPDATE
-        // message doesn't contain the legacy NLRI (per RFC 4271).
-        //
-        if (!bgpSession.mpExtensions()) {
-            hasNlri = true;
-            hasLegacyNlri = true;
-        } else {
-            if (!legacyNlri.nlri4.isEmpty()) {
-                hasNlri = true;
-                hasLegacyNlri = true;
-            }
-            if (!mpNlriReachList.isEmpty()) {
-                hasNlri = true;
-            }
-        }
-
-        //
-        // Check for Missing Well-known Attributes
-        //
-        if (hasNlri && ((origin == null) || (origin == -1))) {
-            // Missing Attribute Type Code ORIGIN
-            int type = Update.Origin.TYPE;
-            actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type);
-            String errorMsg = "Missing Well-known Attribute: ORIGIN";
-            throw new BgpParseException(errorMsg);
-        }
-        if (hasNlri && (asPath == null)) {
-            // Missing Attribute Type Code AS_PATH
-            int type = Update.AsPath.TYPE;
-            actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type);
-            String errorMsg = "Missing Well-known Attribute: AS_PATH";
-            throw new BgpParseException(errorMsg);
-        }
-        if (hasNlri && (localPref == null)) {
-            // Missing Attribute Type Code LOCAL_PREF
-            // NOTE: Required for iBGP
-            int type = Update.LocalPref.TYPE;
-            actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type);
-            String errorMsg = "Missing Well-known Attribute: LOCAL_PREF";
-            throw new BgpParseException(errorMsg);
-        }
-        if (hasLegacyNlri && (legacyNlri.nextHop4 == null)) {
-            // Missing Attribute Type Code NEXT_HOP
-            int type = Update.NextHop.TYPE;
-            actionsBgpUpdateMissingWellKnownAttribute(bgpSession, ctx, type);
-            String errorMsg = "Missing Well-known Attribute: NEXT_HOP";
-            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 Update.Origin.TYPE:
-            isWellKnown = true;
-            typeName = "ORIGIN";
-            break;
-        case Update.AsPath.TYPE:
-            isWellKnown = true;
-            typeName = "AS_PATH";
-            break;
-        case Update.NextHop.TYPE:
-            isWellKnown = true;
-            typeName = "NEXT_HOP";
-            break;
-        case Update.MultiExitDisc.TYPE:
-            isWellKnown = false;
-            typeName = "MULTI_EXIT_DISC";
-            break;
-        case Update.LocalPref.TYPE:
-            isWellKnown = true;
-            typeName = "LOCAL_PREF";
-            break;
-        case Update.AtomicAggregate.TYPE:
-            isWellKnown = true;
-            typeName = "ATOMIC_AGGREGATE";
-            break;
-        case Update.Aggregator.TYPE:
-            isWellKnown = false;
-            typeName = "AGGREGATOR";
-            break;
-        case Update.MpReachNlri.TYPE:
-            isWellKnown = false;
-            typeName = "MP_REACH_NLRI";
-            break;
-        case Update.MpUnreachNlri.TYPE:
-            isWellKnown = false;
-            typeName = "MP_UNREACH_NLRI";
-            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 != 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 Update.Origin.IGP:
-            // FALLTHROUGH
-        case Update.Origin.EGP:
-            // FALLTHROUGH
-        case 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 Update.AsPath.AS_SET:
-                // FALLTHROUGH
-            case Update.AsPath.AS_SEQUENCE:
-                // FALLTHROUGH
-            case Update.AsPath.AS_CONFED_SEQUENCE:
-                // FALLTHROUGH
-            case 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);
-            }
-
-            // 4-octet AS number handling.
-            int asPathLen;
-            if (bgpSession.isAs4OctetCapable()) {
-                asPathLen = AsPath.AS_4OCTET_LENGTH;
-            } else {
-                asPathLen = AsPath.AS_LENGTH;
-            }
-
-            // Parse the AS numbers
-            if (asPathLen * pathSegmentLength > attrLen) {
-                // ERROR: Malformed AS_PATH
-                actionsBgpUpdateMalformedAsPath(bgpSession, ctx);
-                String errorMsg = "Malformed AS Path";
-                throw new BgpParseException(errorMsg);
-            }
-            attrLen -= (asPathLen * pathSegmentLength);
-            ArrayList<Long> segmentAsNumbers = new ArrayList<>();
-            while (pathSegmentLength-- > 0) {
-                long asNumber;
-                if (asPathLen == AsPath.AS_4OCTET_LENGTH) {
-                    asNumber = message.readUnsignedInt();
-                } else {
-                    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 != 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.localInfo().ip4Address())) {
-            // 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 != 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 != 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 != 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 != 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 BGP UPDATE Attribute Type MP_REACH_NLRI.
-     *
-     * @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 MP_REACH_NLRI information if recognized, otherwise
-     * null
-     * @throws BgpParseException
-     */
-    private static MpNlri parseAttributeTypeMpReachNlri(
-                                                BgpSession bgpSession,
-                                                ChannelHandlerContext ctx,
-                                                int attrTypeCode,
-                                                int attrLen,
-                                                int attrFlags,
-                                                ChannelBuffer message)
-        throws BgpParseException {
-        int attributeEnd = message.readerIndex() + attrLen;
-
-        // Check the Attribute Length
-        if (attrLen < Update.MpReachNlri.MIN_LENGTH) {
-            // ERROR: Attribute Length Error
-            actionsBgpUpdateAttributeLengthError(
-                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
-            String errorMsg = "Attribute Length Error";
-            throw new BgpParseException(errorMsg);
-        }
-
-        message.markReaderIndex();
-        int afi = message.readUnsignedShort();
-        int safi = message.readUnsignedByte();
-        int nextHopLen = message.readUnsignedByte();
-
-        //
-        // Verify the AFI/SAFI, and skip the attribute if not recognized.
-        // NOTE: Currently, we support only IPv4/IPv6 UNICAST
-        //
-        if (((afi != MultiprotocolExtensions.AFI_IPV4) &&
-             (afi != MultiprotocolExtensions.AFI_IPV6)) ||
-            (safi != MultiprotocolExtensions.SAFI_UNICAST)) {
-            // Skip the attribute
-            message.resetReaderIndex();
-            message.skipBytes(attrLen);
-            return null;
-        }
-
-        //
-        // Verify the next-hop length
-        //
-        int expectedNextHopLen = 0;
-        switch (afi) {
-        case MultiprotocolExtensions.AFI_IPV4:
-            expectedNextHopLen = Ip4Address.BYTE_LENGTH;
-            break;
-        case MultiprotocolExtensions.AFI_IPV6:
-            expectedNextHopLen = Ip6Address.BYTE_LENGTH;
-            break;
-        default:
-            // UNREACHABLE
-            break;
-        }
-        if (nextHopLen != expectedNextHopLen) {
-            // ERROR: Optional Attribute Error
-            message.resetReaderIndex();
-            actionsBgpUpdateOptionalAttributeError(
-                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
-            String errorMsg = "Invalid next-hop network address length. " +
-                "Received " + nextHopLen + " expected " + expectedNextHopLen;
-            throw new BgpParseException(errorMsg);
-        }
-        // NOTE: We use "+ 1" to take into account the Reserved field (1 octet)
-        if (message.readerIndex() + nextHopLen + 1 >= attributeEnd) {
-            // ERROR: Optional Attribute Error
-            message.resetReaderIndex();
-            actionsBgpUpdateOptionalAttributeError(
-                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
-            String errorMsg = "Malformed next-hop network address";
-            throw new BgpParseException(errorMsg);
-        }
-
-        //
-        // Get the Next-hop address, skip the Reserved field, and get the NLRI
-        //
-        byte[] nextHopBuffer = new byte[nextHopLen];
-        message.readBytes(nextHopBuffer, 0, nextHopLen);
-        int reserved = message.readUnsignedByte();
-        MpNlri mpNlri = new MpNlri(afi, safi);
-        try {
-            switch (afi) {
-            case MultiprotocolExtensions.AFI_IPV4:
-                // The next-hop address
-                mpNlri.nextHop4 = Ip4Address.valueOf(nextHopBuffer);
-                // The NLRI
-                mpNlri.nlri4 = parsePackedIp4Prefixes(
-                                        attributeEnd - message.readerIndex(),
-                                        message);
-                break;
-            case MultiprotocolExtensions.AFI_IPV6:
-                // The next-hop address
-                mpNlri.nextHop6 = Ip6Address.valueOf(nextHopBuffer);
-                // The NLRI
-                mpNlri.nlri6 = parsePackedIp6Prefixes(
-                                        attributeEnd - message.readerIndex(),
-                                        message);
-                break;
-            default:
-                // UNREACHABLE
-                break;
-            }
-        } catch (BgpParseException e) {
-            // ERROR: Optional Attribute Error
-            message.resetReaderIndex();
-            actionsBgpUpdateOptionalAttributeError(
-                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
-            String errorMsg = "Malformed network layer reachability information";
-            throw new BgpParseException(errorMsg);
-        }
-
-        return mpNlri;
-    }
-
-    /**
-     * Parses BGP UPDATE Attribute Type MP_UNREACH_NLRI.
-     *
-     * @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 MP_UNREACH_NLRI information if recognized, otherwise
-     * null
-     * @throws BgpParseException
-     */
-    private static MpNlri parseAttributeTypeMpUnreachNlri(
-                                                BgpSession bgpSession,
-                                                ChannelHandlerContext ctx,
-                                                int attrTypeCode,
-                                                int attrLen,
-                                                int attrFlags,
-                                                ChannelBuffer message)
-        throws BgpParseException {
-        int attributeEnd = message.readerIndex() + attrLen;
-
-        // Check the Attribute Length
-        if (attrLen < Update.MpUnreachNlri.MIN_LENGTH) {
-            // ERROR: Attribute Length Error
-            actionsBgpUpdateAttributeLengthError(
-                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
-            String errorMsg = "Attribute Length Error";
-            throw new BgpParseException(errorMsg);
-        }
-
-        message.markReaderIndex();
-        int afi = message.readUnsignedShort();
-        int safi = message.readUnsignedByte();
-
-        //
-        // Verify the AFI/SAFI, and skip the attribute if not recognized.
-        // NOTE: Currently, we support only IPv4/IPv6 UNICAST
-        //
-        if (((afi != MultiprotocolExtensions.AFI_IPV4) &&
-             (afi != MultiprotocolExtensions.AFI_IPV6)) ||
-            (safi != MultiprotocolExtensions.SAFI_UNICAST)) {
-            // Skip the attribute
-            message.resetReaderIndex();
-            message.skipBytes(attrLen);
-            return null;
-        }
-
-        //
-        // Get the Withdrawn Routes
-        //
-        MpNlri mpNlri = new MpNlri(afi, safi);
-        try {
-            switch (afi) {
-            case MultiprotocolExtensions.AFI_IPV4:
-                // The Withdrawn Routes
-                mpNlri.nlri4 = parsePackedIp4Prefixes(
-                                        attributeEnd - message.readerIndex(),
-                                        message);
-                break;
-            case MultiprotocolExtensions.AFI_IPV6:
-                // The Withdrawn Routes
-                mpNlri.nlri6 = parsePackedIp6Prefixes(
-                                        attributeEnd - message.readerIndex(),
-                                        message);
-                break;
-            default:
-                // UNREACHABLE
-                break;
-            }
-        } catch (BgpParseException e) {
-            // ERROR: Optional Attribute Error
-            message.resetReaderIndex();
-            actionsBgpUpdateOptionalAttributeError(
-                bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
-            String errorMsg = "Malformed withdrawn routes";
-            throw new BgpParseException(errorMsg);
-        }
-
-        return mpNlri;
-    }
-
-    /**
-     * 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> parsePackedIp4Prefixes(
-                                                int totalLength,
-                                                ChannelBuffer message)
-        throws BgpParseException {
-        Collection<Ip4Prefix> result = new ArrayList<>();
-
-        if (totalLength == 0) {
-            return result;
-        }
-
-        // Parse the data
-        byte[] buffer = new byte[Ip4Address.BYTE_LENGTH];
-        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);
-            }
-
-            message.readBytes(buffer, 0, prefixBytelen);
-            Ip4Prefix prefix = Ip4Prefix.valueOf(Ip4Address.valueOf(buffer),
-                                                 prefixBitlen);
-            result.add(prefix);
-        }
-
-        return result;
-    }
-
-    /**
-     * Parses a message that contains encoded IPv6 network prefixes.
-     * <p>
-     * The IPv6 prefixes are encoded in the form:
-     * <Length, Prefix> where Length is the length in bits of the IPv6 prefix,
-     * and Prefix is the IPv6 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 IPv6 network prefixes
-     * @throws BgpParseException
-     */
-    private static Collection<Ip6Prefix> parsePackedIp6Prefixes(
-                                                int totalLength,
-                                                ChannelBuffer message)
-        throws BgpParseException {
-        Collection<Ip6Prefix> result = new ArrayList<>();
-
-        if (totalLength == 0) {
-            return result;
-        }
-
-        // Parse the data
-        byte[] buffer = new byte[Ip6Address.BYTE_LENGTH];
-        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);
-            }
-
-            message.readBytes(buffer, 0, prefixBytelen);
-            Ip6Prefix prefix = Ip6Prefix.valueOf(Ip6Address.valueOf(buffer),
-                                                 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.remoteInfo().address());
-
-        //
-        // 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.remoteInfo().address());
-
-        //
-        // 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.remoteInfo().address(), 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.remoteInfo().address());
-
-        //
-        // 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.remoteInfo().address());
-
-        //
-        // 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.remoteInfo().address(), nextHop);
-
-        //
-        // ERROR: Invalid NEXT_HOP 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.remoteInfo().address(), 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
-     * Optional 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 actionsBgpUpdateOptionalAttributeError(
-                                BgpSession bgpSession,
-                                ChannelHandlerContext ctx,
-                                int attrTypeCode,
-                                int attrLen,
-                                int attrFlags,
-                                ChannelBuffer message) {
-        log.debug("BGP RX UPDATE Error from {}: Optional Attribute Error: {}",
-                  bgpSession.remoteInfo().address(), attrTypeCode);
-
-        //
-        // ERROR: Optional Attribute Error
-        //
-        // Send NOTIFICATION and close the connection
-        int errorCode = UpdateMessageError.ERROR_CODE;
-        int errorSubcode =
-            UpdateMessageError.OPTIONAL_ATTRIBUTE_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
-     * 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.remoteInfo().address());
-
-        //
-        // 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.remoteInfo().address());
-
-        //
-        // 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;
-    }
-
-    /**
-     * Helper class for storing Multiprotocol Network Layer Reachability
-     * information.
-     */
-    private static final class MpNlri {
-        private final int afi;
-        private final int safi;
-        private Ip4Address nextHop4;
-        private Ip6Address nextHop6;
-        private Collection<Ip4Prefix> nlri4 = new ArrayList<>();
-        private Collection<Ip6Prefix> nlri6 = new ArrayList<>();
-
-        /**
-         * Constructor.
-         *
-         * @param afi the Address Family Identifier
-         * @param safi the Subsequent Address Family Identifier
-         */
-        private MpNlri(int afi, int safi) {
-            this.afi = afi;
-            this.safi = safi;
-        }
-    }
-
-    /**
-     * Helper class for storing decoded BGP routing information.
-     */
-    private static final class DecodedBgpRoutes {
-        private final Map<Ip4Prefix, BgpRouteEntry> addedUnicastRoutes4 =
-            new HashMap<>();
-        private final Map<Ip6Prefix, BgpRouteEntry> addedUnicastRoutes6 =
-            new HashMap<>();
-        private final Map<Ip4Prefix, BgpRouteEntry> deletedUnicastRoutes4 =
-            new HashMap<>();
-        private final Map<Ip6Prefix, BgpRouteEntry> deletedUnicastRoutes6 =
-            new HashMap<>();
-    }
-}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/package-info.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/package-info.java
deleted file mode 100644
index 9e1b5d2..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/bgp/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * Implementation of the BGP protocol.
- */
-package org.onosproject.sdnip.bgp;
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
deleted file mode 100644
index fe2a4a4..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/BgpNeighborsListCommand.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * 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.cli;
-
-import java.util.Collection;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.apache.karaf.shell.commands.Command;
-import org.apache.karaf.shell.commands.Option;
-import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.sdnip.SdnIpService;
-import org.onosproject.sdnip.bgp.BgpSession;
-
-/**
- * Command to show the BGP neighbors.
- */
-@Command(scope = "onos", name = "bgp-neighbors",
-         description = "Lists the BGP neighbors")
-public class BgpNeighborsListCommand extends AbstractShellCommand {
-    @Option(name = "-n", aliases = "--neighbor",
-            description = "BGP neighbor to display information about",
-            required = false, multiValued = false)
-    private String bgpNeighbor;
-
-    private static final String FORMAT_NEIGHBOR_LINE1 =
-        "BGP neighbor is %s, remote AS %d, local AS %d";
-    private static final String FORMAT_NEIGHBOR_LINE2 =
-        "  Remote router ID %s, IP %s, BGP version %d, Hold time %d";
-    private static final String FORMAT_NEIGHBOR_LINE3 =
-        "  Remote AFI/SAFI IPv4 Unicast %s Multicast %s, IPv6 Unicast %s Multicast %s";
-    private static final String FORMAT_NEIGHBOR_LINE4 =
-        "  Local  router ID %s, IP %s, BGP version %d, Hold time %d";
-    private static final String FORMAT_NEIGHBOR_LINE5 =
-        "  Local  AFI/SAFI IPv4 Unicast %s Multicast %s, IPv6 Unicast %s Multicast %s";
-    private static final String FORMAT_NEIGHBOR_LINE6 =
-        "  4 Octet AS Capability: %s %s";
-
-    @Override
-    protected void execute() {
-        SdnIpService service = get(SdnIpService.class);
-        Collection<BgpSession> bgpSessions = service.getBgpSessions();
-
-        if (bgpNeighbor != null) {
-            // Print a single neighbor (if found)
-            BgpSession foundBgpSession = null;
-            for (BgpSession bgpSession : bgpSessions) {
-                if (bgpSession.remoteInfo().bgpId().toString().equals(bgpNeighbor)) {
-                    foundBgpSession = bgpSession;
-                    break;
-                }
-            }
-            if (foundBgpSession != null) {
-                printNeighbor(foundBgpSession);
-            } else {
-                print("BGP neighbor %s not found", bgpNeighbor);
-            }
-            return;
-        }
-
-        // Print all neighbors
-        printNeighbors(bgpSessions);
-    }
-
-    /**
-     * Prints all BGP neighbors.
-     *
-     * @param bgpSessions the BGP sessions for the neighbors to print
-     */
-    private void printNeighbors(Collection<BgpSession> bgpSessions) {
-        if (outputJson()) {
-            print("%s", json(bgpSessions));
-        } else {
-            for (BgpSession bgpSession : bgpSessions) {
-                printNeighbor(bgpSession);
-            }
-        }
-    }
-
-    /**
-     * Prints a BGP neighbor.
-     *
-     * @param bgpSession the BGP session for the neighbor to print
-     */
-    private void printNeighbor(BgpSession bgpSession) {
-        print(FORMAT_NEIGHBOR_LINE1,
-              bgpSession.remoteInfo().bgpId().toString(),
-              bgpSession.remoteInfo().asNumber(),
-              bgpSession.localInfo().asNumber());
-        print(FORMAT_NEIGHBOR_LINE2,
-              bgpSession.remoteInfo().bgpId().toString(),
-              bgpSession.remoteInfo().address().toString(),
-              bgpSession.remoteInfo().bgpVersion(),
-              bgpSession.remoteInfo().holdtime());
-        print(FORMAT_NEIGHBOR_LINE3,
-              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.localInfo().bgpId().toString(),
-              bgpSession.localInfo().address().toString(),
-              bgpSession.localInfo().bgpVersion(),
-              bgpSession.localInfo().holdtime());
-        print(FORMAT_NEIGHBOR_LINE5,
-              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.localInfo().as4OctetCapability() ? "Advertised" : "",
-                  bgpSession.remoteInfo().as4OctetCapability() ? "Received" : "");
-        }
-    }
-
-    /**
-     * Produces a JSON array of BGP neighbors.
-     *
-     * @param bgpSessions the BGP sessions with the data
-     * @return JSON array with the neighbors
-     */
-    private JsonNode json(Collection<BgpSession> bgpSessions) {
-        ObjectMapper mapper = new ObjectMapper();
-        ArrayNode result = mapper.createArrayNode();
-
-        for (BgpSession bgpSession : bgpSessions) {
-            result.add(json(mapper, bgpSession));
-        }
-        return result;
-    }
-
-    /**
-     * Produces JSON object for a BGP neighbor.
-     *
-     * @param mapper the JSON object mapper to use
-     * @param bgpSession the BGP session with the data
-     * @return JSON object for the route
-     */
-    private ObjectNode json(ObjectMapper mapper, BgpSession bgpSession) {
-        ObjectNode result = mapper.createObjectNode();
-
-        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.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
deleted file mode 100644
index a3b19df..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/BgpRoutesListCommand.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * 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.cli;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.apache.karaf.shell.commands.Command;
-import org.apache.karaf.shell.commands.Option;
-import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.sdnip.SdnIpService;
-import org.onosproject.sdnip.bgp.BgpConstants.Update;
-import org.onosproject.sdnip.bgp.BgpRouteEntry;
-import org.onosproject.sdnip.bgp.BgpSession;
-
-/**
- * Command to show the routes learned through BGP.
- */
-@Command(scope = "onos", name = "bgp-routes",
-         description = "Lists all BGP best routes")
-public class BgpRoutesListCommand extends AbstractShellCommand {
-    @Option(name = "-s", aliases = "--summary",
-            description = "BGP routes summary",
-            required = false, multiValued = false)
-    private boolean routesSummary = false;
-
-    @Option(name = "-n", aliases = "--neighbor",
-            description = "Routes from a BGP neighbor",
-            required = false, multiValued = false)
-    private String bgpNeighbor;
-
-    private static final String FORMAT_SUMMARY_V4 =
-        "Total BGP IPv4 routes = %d";
-    private static final String FORMAT_SUMMARY_V6 =
-        "Total BGP IPv6 routes = %d";
-    private static final String FORMAT_HEADER =
-        "   Network            Next Hop        Origin LocalPref       MED BGP-ID";
-    private static final String FORMAT_ROUTE_LINE1 =
-        "   %-18s %-15s %6s %9s %9s %-15s";
-    private static final String FORMAT_ROUTE_LINE2 =
-        "                      AsPath %s";
-
-    @Override
-    protected void execute() {
-        SdnIpService service = get(SdnIpService.class);
-
-        // Print summary of the routes
-        if (routesSummary) {
-            printSummary(service.getBgpRoutes4(), service.getBgpRoutes6());
-            return;
-        }
-
-        BgpSession foundBgpSession = null;
-        if (bgpNeighbor != null) {
-            // Print the routes from a single neighbor (if found)
-            for (BgpSession bgpSession : service.getBgpSessions()) {
-                if (bgpSession.remoteInfo().bgpId().toString().equals(bgpNeighbor)) {
-                    foundBgpSession = bgpSession;
-                    break;
-                }
-            }
-            if (foundBgpSession == null) {
-                print("BGP neighbor %s not found", bgpNeighbor);
-                return;
-            }
-        }
-
-        // Print the routes
-        if (foundBgpSession != null) {
-            printRoutes(foundBgpSession.getBgpRibIn4(),
-                        foundBgpSession.getBgpRibIn6());
-        } else {
-            printRoutes(service.getBgpRoutes4(), service.getBgpRoutes6());
-        }
-    }
-
-    /**
-     * Prints summary of the routes.
-     *
-     * @param routes4 the IPv4 routes
-     * @param routes6 the IPv6 routes
-     */
-    private void printSummary(Collection<BgpRouteEntry> routes4,
-                              Collection<BgpRouteEntry> routes6) {
-        if (outputJson()) {
-            ObjectMapper mapper = new ObjectMapper();
-            ObjectNode result = mapper.createObjectNode();
-            result.put("totalRoutes4", routes4.size());
-            result.put("totalRoutes6", routes6.size());
-            print("%s", result);
-        } else {
-            print(FORMAT_SUMMARY_V4, routes4.size());
-            print(FORMAT_SUMMARY_V6, routes6.size());
-        }
-    }
-
-    /**
-     * Prints all routes.
-     *
-     * @param routes4 the IPv4 routes to print
-     * @param routes6 the IPv6 routes to print
-     */
-    private void printRoutes(Collection<BgpRouteEntry> routes4,
-                             Collection<BgpRouteEntry> routes6) {
-        if (outputJson()) {
-            ObjectMapper mapper = new ObjectMapper();
-            ObjectNode result = mapper.createObjectNode();
-            result.put("routes4", json(routes4));
-            result.put("routes6", json(routes6));
-            print("%s", result);
-        } else {
-            // The IPv4 routes
-            print(FORMAT_HEADER);
-            for (BgpRouteEntry route : routes4) {
-                printRoute(route);
-            }
-            print(FORMAT_SUMMARY_V4, routes4.size());
-            print("");                  // Empty separator line
-            // The IPv6 routes
-            print(FORMAT_HEADER);
-            for (BgpRouteEntry route : routes6) {
-                printRoute(route);
-            }
-            print(FORMAT_SUMMARY_V6, routes6.size());
-        }
-    }
-
-    /**
-     * Prints a BGP route.
-     *
-     * @param route the route to print
-     */
-    private void printRoute(BgpRouteEntry route) {
-        if (route != null) {
-            print(FORMAT_ROUTE_LINE1, route.prefix(), route.nextHop(),
-                  Update.Origin.typeToString(route.getOrigin()),
-                  route.getLocalPref(), route.getMultiExitDisc(),
-                  route.getBgpSession().remoteInfo().bgpId());
-            print(FORMAT_ROUTE_LINE2, asPath4Cli(route.getAsPath()));
-        }
-    }
-
-    /**
-     * Formats the AS Path as a string that can be shown on the CLI.
-     *
-     * @param asPath the AS Path to format
-     * @return the AS Path as a string
-     */
-    private String asPath4Cli(BgpRouteEntry.AsPath asPath) {
-        ArrayList<BgpRouteEntry.PathSegment> pathSegments =
-            asPath.getPathSegments();
-
-        if (pathSegments.isEmpty()) {
-            return "[none]";
-        }
-
-        final StringBuilder builder = new StringBuilder();
-        for (BgpRouteEntry.PathSegment pathSegment : pathSegments) {
-            String prefix = null;
-            String suffix = null;
-            switch (pathSegment.getType()) {
-            case Update.AsPath.AS_SET:
-                prefix = "[AS-Set";
-                suffix = "]";
-                break;
-            case Update.AsPath.AS_SEQUENCE:
-                break;
-            case Update.AsPath.AS_CONFED_SEQUENCE:
-                prefix = "[AS-Confed-Seq";
-                suffix = "]";
-                break;
-            case Update.AsPath.AS_CONFED_SET:
-                prefix = "[AS-Confed-Set";
-                suffix = "]";
-                break;
-            default:
-                builder.append(String.format("(type = %s)",
-                        Update.AsPath.typeToString(pathSegment.getType())));
-                break;
-            }
-
-            if (prefix != null) {
-                if (builder.length() > 0) {
-                    builder.append(" ");        // Separator
-                }
-                builder.append(prefix);
-            }
-            // Print the AS numbers
-            for (Long asn : pathSegment.getSegmentAsNumbers()) {
-                if (builder.length() > 0) {
-                    builder.append(" ");        // Separator
-                }
-                builder.append(String.format("%d", asn));
-            }
-            if (suffix != null) {
-                // No need for separator
-                builder.append(prefix);
-            }
-        }
-        return builder.toString();
-    }
-
-    /**
-     * Produces a JSON array of routes.
-     *
-     * @param routes the routes with the data
-     * @return JSON array with the routes
-     */
-    private JsonNode json(Collection<BgpRouteEntry> routes) {
-        ObjectMapper mapper = new ObjectMapper();
-        ArrayNode result = mapper.createArrayNode();
-
-        for (BgpRouteEntry route : routes) {
-            result.add(json(mapper, route));
-        }
-        return result;
-    }
-
-    /**
-     * Produces JSON object for a route.
-     *
-     * @param mapper the JSON object mapper to use
-     * @param route the route with the data
-     * @return JSON object for the route
-     */
-    private ObjectNode json(ObjectMapper mapper, BgpRouteEntry route) {
-        ObjectNode result = mapper.createObjectNode();
-
-        result.put("prefix", route.prefix().toString());
-        result.put("nextHop", route.nextHop().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());
-        result.put("multiExitDisc", route.getMultiExitDisc());
-
-        return result;
-    }
-
-    /**
-     * Produces JSON object for an AS path.
-     *
-     * @param mapper the JSON object mapper to use
-     * @param asPath the AS path with the data
-     * @return JSON object for the AS path
-     */
-    private ObjectNode json(ObjectMapper mapper, BgpRouteEntry.AsPath asPath) {
-        ObjectNode result = mapper.createObjectNode();
-        ArrayNode pathSegmentsJson = mapper.createArrayNode();
-        for (BgpRouteEntry.PathSegment pathSegment : asPath.getPathSegments()) {
-            ObjectNode pathSegmentJson = mapper.createObjectNode();
-            pathSegmentJson.put("type",
-                                Update.AsPath.typeToString(pathSegment.getType()));
-            ArrayNode segmentAsNumbersJson = mapper.createArrayNode();
-            for (Long asNumber : pathSegment.getSegmentAsNumbers()) {
-                segmentAsNumbersJson.add(asNumber);
-            }
-            pathSegmentJson.put("segmentAsNumbers", segmentAsNumbersJson);
-            pathSegmentsJson.add(pathSegmentJson);
-        }
-        result.put("pathSegments", pathSegmentsJson);
-
-        return result;
-    }
-}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/RoutesListCommand.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/RoutesListCommand.java
deleted file mode 100644
index cebbc43..0000000
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/RoutesListCommand.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.cli;
-
-import java.util.Collection;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.apache.karaf.shell.commands.Command;
-import org.apache.karaf.shell.commands.Option;
-import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.sdnip.RouteEntry;
-import org.onosproject.sdnip.SdnIpService;
-
-/**
- * Command to show the list of routes in SDN-IP's routing table.
- */
-@Command(scope = "onos", name = "routes",
-        description = "Lists all SDN-IP best routes")
-public class RoutesListCommand extends AbstractShellCommand {
-    @Option(name = "-s", aliases = "--summary",
-            description = "SDN-IP routes summary",
-            required = false, multiValued = false)
-    private boolean routesSummary = false;
-
-    private static final String FORMAT_SUMMARY_V4 =
-        "Total SDN-IP IPv4 routes = %d";
-    private static final String FORMAT_SUMMARY_V6 =
-        "Total SDN-IP IPv6 routes = %d";
-    private static final String FORMAT_HEADER =
-        "   Network            Next Hop";
-    private static final String FORMAT_ROUTE =
-        "   %-18s %-15s";
-
-    @Override
-    protected void execute() {
-        SdnIpService service = get(SdnIpService.class);
-
-        // Print summary of the routes
-        if (routesSummary) {
-            printSummary(service.getRoutes4(), service.getRoutes6());
-            return;
-        }
-
-        // Print all routes
-        printRoutes(service.getRoutes4(), service.getRoutes6());
-    }
-
-    /**
-     * Prints summary of the routes.
-     *
-     * @param routes4 the IPv4 routes
-     * @param routes6 the IPv6 routes
-     */
-    private void printSummary(Collection<RouteEntry> routes4,
-                              Collection<RouteEntry> routes6) {
-        if (outputJson()) {
-            ObjectMapper mapper = new ObjectMapper();
-            ObjectNode result = mapper.createObjectNode();
-            result.put("totalRoutes4", routes4.size());
-            result.put("totalRoutes6", routes6.size());
-            print("%s", result);
-        } else {
-            print(FORMAT_SUMMARY_V4, routes4.size());
-            print(FORMAT_SUMMARY_V6, routes6.size());
-        }
-    }
-
-    /**
-     * Prints all routes.
-     *
-     * @param routes4 the IPv4 routes to print
-     * @param routes6 the IPv6 routes to print
-     */
-    private void printRoutes(Collection<RouteEntry> routes4,
-                             Collection<RouteEntry> routes6) {
-        if (outputJson()) {
-            ObjectMapper mapper = new ObjectMapper();
-            ObjectNode result = mapper.createObjectNode();
-            result.put("routes4", json(routes4));
-            result.put("routes6", json(routes6));
-            print("%s", result);
-        } else {
-            // The IPv4 routes
-            print(FORMAT_HEADER);
-            for (RouteEntry route : routes4) {
-                printRoute(route);
-            }
-            print(FORMAT_SUMMARY_V4, routes4.size());
-            print("");                  // Empty separator line
-            // The IPv6 routes
-            print(FORMAT_HEADER);
-            for (RouteEntry route : routes6) {
-                printRoute(route);
-            }
-            print(FORMAT_SUMMARY_V6, routes6.size());
-        }
-    }
-
-    /**
-     * Prints a route.
-     *
-     * @param route the route to print
-     */
-    private void printRoute(RouteEntry route) {
-        if (route != null) {
-            print(FORMAT_ROUTE, route.prefix(), route.nextHop());
-        }
-    }
-
-    /**
-     * Produces a JSON array of routes.
-     *
-     * @param routes the routes with the data
-     * @return JSON array with the routes
-     */
-    private JsonNode json(Collection<RouteEntry> routes) {
-        ObjectMapper mapper = new ObjectMapper();
-        ArrayNode result = mapper.createArrayNode();
-
-        for (RouteEntry route : routes) {
-            result.add(json(mapper, route));
-        }
-        return result;
-    }
-
-    /**
-     * Produces JSON object for a route.
-     *
-     * @param mapper the JSON object mapper to use
-     * @param route the route with the data
-     * @return JSON object for the route
-     */
-    private ObjectNode json(ObjectMapper mapper, RouteEntry route) {
-        ObjectNode result = mapper.createObjectNode();
-
-        result.put("prefix", route.prefix().toString());
-        result.put("nextHop", route.nextHop().toString());
-
-        return result;
-    }
-}
diff --git a/apps/sdnip/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/sdnip/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index dd33f73..3be1c79 100644
--- a/apps/sdnip/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/apps/sdnip/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -17,15 +17,6 @@
 
   <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
     <command>
-      <action class="org.onosproject.sdnip.cli.BgpNeighborsListCommand"/>
-    </command>
-    <command>
-      <action class="org.onosproject.sdnip.cli.BgpRoutesListCommand"/>
-    </command>
-    <command>
-      <action class="org.onosproject.sdnip.cli.RoutesListCommand"/>
-    </command>
-    <command>
       <action class="org.onosproject.sdnip.cli.PrimaryChangeCommand"/>
     </command>
   </command-bundle>
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java
index e4808f7..d13aa2a 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java
@@ -16,9 +16,8 @@
 package org.onosproject.sdnip;
 
 import com.google.common.collect.Sets;
-import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory;
-import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree;
-import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
+import org.easymock.EasyMock;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.onlab.junit.TestUtils;
@@ -32,18 +31,12 @@
 import org.onlab.packet.VlanId;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultHost;
 import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.HostLocation;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.host.HostListener;
-import org.onosproject.net.host.HostService;
 import org.onosproject.net.host.InterfaceIpAddress;
 import org.onosproject.net.intent.AbstractIntentTest;
 import org.onosproject.net.intent.Intent;
@@ -51,10 +44,18 @@
 import org.onosproject.net.intent.IntentService;
 import org.onosproject.net.intent.IntentState;
 import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.net.provider.ProviderId;
+import org.onosproject.routingapi.FibEntry;
+import org.onosproject.routingapi.FibUpdate;
+import org.onosproject.routingapi.RouteEntry;
+import org.onosproject.sdnip.IntentSynchronizer.IntentKey;
+import org.onosproject.sdnip.config.BgpPeer;
 import org.onosproject.sdnip.config.Interface;
+import org.onosproject.sdnip.config.SdnIpConfigurationService;
 
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -71,9 +72,9 @@
  */
 public class IntentSyncTest extends AbstractIntentTest {
 
+    private SdnIpConfigurationService sdnIpConfigService;
     private InterfaceService interfaceService;
     private IntentService intentService;
-    private HostService hostService;
 
     private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
             DeviceId.deviceId("of:0000000000000001"),
@@ -87,8 +88,11 @@
             DeviceId.deviceId("of:0000000000000003"),
             PortNumber.portNumber(1));
 
+    private static final ConnectPoint SW4_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000004"),
+            PortNumber.portNumber(1));
+
     private IntentSynchronizer intentSynchronizer;
-    private Router router;
 
     private static final ApplicationId APPID = new ApplicationId() {
         @Override
@@ -106,12 +110,42 @@
     public void setUp() throws Exception {
         super.setUp();
         setUpInterfaceService();
-        setUpHostService();
+
+        setUpBgpPeers();
         intentService = createMock(IntentService.class);
 
         intentSynchronizer = new IntentSynchronizer(APPID, intentService,
-                                                    null, interfaceService);
-        router = new Router(intentSynchronizer, hostService);
+                                                    sdnIpConfigService, interfaceService);
+    }
+
+    /**
+     * Sets up BGP peers in external networks.
+     */
+    private void setUpBgpPeers() {
+
+        Map<IpAddress, BgpPeer> peers = new HashMap<>();
+
+        String peerSw1Eth1 = "192.168.10.1";
+        peers.put(IpAddress.valueOf(peerSw1Eth1),
+                  new BgpPeer("00:00:00:00:00:00:00:01", 1, peerSw1Eth1));
+
+        // Two BGP peers are connected to switch 2 port 1.
+        String peer1Sw2Eth1 = "192.168.20.1";
+        peers.put(IpAddress.valueOf(peer1Sw2Eth1),
+                  new BgpPeer("00:00:00:00:00:00:00:02", 1, peer1Sw2Eth1));
+
+        String peer2Sw2Eth1 = "192.168.20.2";
+        peers.put(IpAddress.valueOf(peer2Sw2Eth1),
+                  new BgpPeer("00:00:00:00:00:00:00:02", 1, peer2Sw2Eth1));
+
+        String peer1Sw4Eth1 = "192.168.40.1";
+        peers.put(IpAddress.valueOf(peer1Sw4Eth1),
+                  new BgpPeer("00:00:00:00:00:00:00:04", 1, peer1Sw4Eth1));
+
+        sdnIpConfigService = createMock(SdnIpConfigurationService.class);
+        expect(sdnIpConfigService.getBgpPeers()).andReturn(peers).anyTimes();
+        EasyMock.replay(sdnIpConfigService);
+
     }
 
     /**
@@ -133,80 +167,279 @@
         interfaces.add(sw1Eth1);
 
         Set<InterfaceIpAddress> interfaceIpAddresses2 = Sets.newHashSet();
-        interfaceIpAddresses2.add(new InterfaceIpAddress(
-                IpAddress.valueOf("192.168.20.101"),
-                IpPrefix.valueOf("192.168.20.0/24")));
+        interfaceIpAddresses2.add(
+                new InterfaceIpAddress(IpAddress.valueOf("192.168.20.101"),
+                                       IpPrefix.valueOf("192.168.20.0/24")));
         Interface sw2Eth1 = new Interface(SW2_ETH1,
                 interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
                 VlanId.NONE);
         interfaces.add(sw2Eth1);
 
         Set<InterfaceIpAddress> interfaceIpAddresses3 = Sets.newHashSet();
-        interfaceIpAddresses3.add(new InterfaceIpAddress(
-                IpAddress.valueOf("192.168.30.101"),
-                IpPrefix.valueOf("192.168.30.0/24")));
+        interfaceIpAddresses3.add(
+                new InterfaceIpAddress(IpAddress.valueOf("192.168.30.101"),
+                                       IpPrefix.valueOf("192.168.30.0/24")));
         Interface sw3Eth1 = new Interface(SW3_ETH1,
                 interfaceIpAddresses3, MacAddress.valueOf("00:00:00:00:00:03"),
                 VlanId.NONE);
         interfaces.add(sw3Eth1);
 
+        InterfaceIpAddress interfaceIpAddress4 =
+                new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"),
+                                       IpPrefix.valueOf("192.168.40.0/24"));
+        Interface sw4Eth1 = new Interface(SW4_ETH1,
+                                          Sets.newHashSet(interfaceIpAddress4),
+                                          MacAddress.valueOf("00:00:00:00:00:04"),
+                                          VlanId.vlanId((short) 1));
+
+        expect(interfaceService.getInterface(SW4_ETH1)).andReturn(sw4Eth1).anyTimes();
+        interfaces.add(sw4Eth1);
+
         expect(interfaceService.getInterface(SW1_ETH1)).andReturn(
                 sw1Eth1).anyTimes();
         expect(interfaceService.getInterface(SW2_ETH1)).andReturn(
                 sw2Eth1).anyTimes();
         expect(interfaceService.getInterface(SW3_ETH1)).andReturn(
                 sw3Eth1).anyTimes();
-        expect(interfaceService.getInterfaces()).andReturn(
-                interfaces).anyTimes();
+        expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
         replay(interfaceService);
     }
 
     /**
-     * Sets up the host service with details of hosts.
+     * Tests adding a FIB entry to the IntentSynchronizer.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is submitted to the IntentService.
+     *
+     * @throws TestUtilsException
      */
-    private void setUpHostService() {
-        hostService = createMock(HostService.class);
+    @Test
+    public void testFibAdd() throws TestUtilsException {
+        FibEntry fibEntry = new FibEntry(
+                Ip4Prefix.valueOf("1.1.1.0/24"),
+                Ip4Address.valueOf("192.168.10.1"),
+                MacAddress.valueOf("00:00:00:00:00:01"));
 
-        hostService.addListener(anyObject(HostListener.class));
-        expectLastCall().anyTimes();
+        // Construct a MultiPointToSinglePointIntent intent
+        TrafficSelector.Builder selectorBuilder =
+                DefaultTrafficSelector.builder();
+        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
+                fibEntry.prefix());
 
-        IpAddress host1Address = IpAddress.valueOf("192.168.10.1");
-        Host host1 = new DefaultHost(ProviderId.NONE, HostId.NONE,
-                MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE,
-                new HostLocation(SW1_ETH1, 1),
-                        Sets.newHashSet(host1Address));
+        TrafficTreatment.Builder treatmentBuilder =
+                DefaultTrafficTreatment.builder();
+        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
 
-        expect(hostService.getHostsByIp(host1Address))
-                .andReturn(Sets.newHashSet(host1)).anyTimes();
-        hostService.startMonitoringIp(host1Address);
-        expectLastCall().anyTimes();
+        Set<ConnectPoint> ingressPoints = new HashSet<>();
+        ingressPoints.add(SW2_ETH1);
+        ingressPoints.add(SW3_ETH1);
+        ingressPoints.add(SW4_ETH1);
+
+        MultiPointToSinglePointIntent intent =
+                new MultiPointToSinglePointIntent(APPID,
+                                                  selectorBuilder.build(), treatmentBuilder.build(),
+                                                  ingressPoints, SW1_ETH1);
+
+        // Setup the expected intents
+        IntentOperations.Builder builder = IntentOperations.builder(APPID);
+        builder.addSubmitOperation(intent);
+        intentService.execute(TestIntentServiceHelper.eqExceptId(
+                builder.build()));
+        replay(intentService);
+
+        intentSynchronizer.leaderChanged(true);
+        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
+
+        FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE,
+                                            fibEntry);
+        intentSynchronizer.update(Collections.singleton(fibUpdate),
+                                  Collections.emptyList());
+
+        Assert.assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
+        Intent firstIntent =
+                intentSynchronizer.getRouteIntents().iterator().next();
+        IntentKey firstIntentKey = new IntentKey(firstIntent);
+        IntentKey intentKey = new IntentKey(intent);
+        assertTrue(firstIntentKey.equals(intentKey));
+        verify(intentService);
+    }
+
+    /**
+     * Tests adding a FIB entry with to a next hop in a VLAN.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is submitted to the IntentService.
+     *
+     * @throws TestUtilsException
+     */
+    @Test
+    public void testFibAddWithVlan() throws TestUtilsException {
+        FibEntry fibEntry = new FibEntry(
+                Ip4Prefix.valueOf("3.3.3.0/24"),
+                Ip4Address.valueOf("192.168.40.1"),
+                MacAddress.valueOf("00:00:00:00:00:04"));
+
+        // Construct a MultiPointToSinglePointIntent intent
+        TrafficSelector.Builder selectorBuilder =
+                DefaultTrafficSelector.builder();
+        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4)
+                       .matchIPDst(fibEntry.prefix())
+                       .matchVlanId(VlanId.ANY);
+
+        TrafficTreatment.Builder treatmentBuilder =
+                DefaultTrafficTreatment.builder();
+        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:04"))
+                        .setVlanId(VlanId.vlanId((short) 1));
+
+        Set<ConnectPoint> ingressPoints = new HashSet<>();
+        ingressPoints.add(SW1_ETH1);
+        ingressPoints.add(SW2_ETH1);
+        ingressPoints.add(SW3_ETH1);
+
+        MultiPointToSinglePointIntent intent =
+                new MultiPointToSinglePointIntent(APPID,
+                        selectorBuilder.build(), treatmentBuilder.build(),
+                        ingressPoints, SW4_ETH1);
+
+        // Setup the expected intents
+        IntentOperations.Builder builder = IntentOperations.builder(APPID);
+        builder.addSubmitOperation(intent);
+        intentService.execute(
+                TestIntentServiceHelper.eqExceptId(builder.build()));
+        replay(intentService);
+
+        // Run the test
+        intentSynchronizer.leaderChanged(true);
+        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
+        FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
+
+        intentSynchronizer.update(Collections.singleton(fibUpdate),
+                                  Collections.emptyList());
+
+        // Verify
+        Assert.assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
+        Intent firstIntent =
+            intentSynchronizer.getRouteIntents().iterator().next();
+        IntentKey firstIntentKey = new IntentKey(firstIntent);
+        IntentKey intentKey = new IntentKey(intent);
+        assertTrue(firstIntentKey.equals(intentKey));
+        verify(intentService);
+    }
+
+    /**
+     * Tests updating a FIB entry.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is submitted to the IntentService.
+     *
+     * @throws TestUtilsException
+     */
+    @Test
+    public void testFibUpdate() throws TestUtilsException {
+        // Firstly add a route
+        testFibAdd();
+
+        Intent addedIntent =
+                intentSynchronizer.getRouteIntents().iterator().next();
+
+        // Start to construct a new route entry and new intent
+        FibEntry fibEntryUpdate = new FibEntry(
+                Ip4Prefix.valueOf("1.1.1.0/24"),
+                Ip4Address.valueOf("192.168.20.1"),
+                MacAddress.valueOf("00:00:00:00:00:02"));
+
+        // Construct a new MultiPointToSinglePointIntent intent
+        TrafficSelector.Builder selectorBuilderNew =
+                DefaultTrafficSelector.builder();
+        selectorBuilderNew.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
+                fibEntryUpdate.prefix());
+
+        TrafficTreatment.Builder treatmentBuilderNew =
+                DefaultTrafficTreatment.builder();
+        treatmentBuilderNew.setEthDst(MacAddress.valueOf("00:00:00:00:00:02"));
 
 
-        IpAddress host2Address = IpAddress.valueOf("192.168.20.1");
-        Host host2 = new DefaultHost(ProviderId.NONE, HostId.NONE,
-                MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE,
-                new HostLocation(SW2_ETH1, 1),
-                        Sets.newHashSet(host2Address));
+        Set<ConnectPoint> ingressPointsNew = new HashSet<>();
+        ingressPointsNew.add(SW1_ETH1);
+        ingressPointsNew.add(SW3_ETH1);
+        ingressPointsNew.add(SW4_ETH1);
 
-        expect(hostService.getHostsByIp(host2Address))
-                .andReturn(Sets.newHashSet(host2)).anyTimes();
-        hostService.startMonitoringIp(host2Address);
-        expectLastCall().anyTimes();
+        MultiPointToSinglePointIntent intentNew =
+                new MultiPointToSinglePointIntent(APPID,
+                                                  selectorBuilderNew.build(),
+                                                  treatmentBuilderNew.build(),
+                                                  ingressPointsNew, SW2_ETH1);
 
+        // Set up test expectation
+        reset(intentService);
+        // Setup the expected intents
+        IntentOperations.Builder builder = IntentOperations.builder(APPID);
+        builder.addWithdrawOperation(addedIntent.id());
+        intentService.execute(TestIntentServiceHelper.eqExceptId(
+                builder.build()));
+        builder = IntentOperations.builder(APPID);
+        builder.addSubmitOperation(intentNew);
+        intentService.execute(TestIntentServiceHelper.eqExceptId(
+                builder.build()));
+        replay(intentService);
 
-        IpAddress host3Address = IpAddress.valueOf("192.168.30.1");
-        Host host3 = new DefaultHost(ProviderId.NONE, HostId.NONE,
-                MacAddress.valueOf("00:00:00:00:00:03"), VlanId.NONE,
-                new HostLocation(SW3_ETH1, 1),
-                        Sets.newHashSet(host3Address));
+        // Call the update() method in IntentSynchronizer class
+        intentSynchronizer.leaderChanged(true);
+        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
+        FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE,
+                                                  fibEntryUpdate);
+        intentSynchronizer.update(Collections.singletonList(fibUpdate),
+                                  Collections.emptyList());
 
-        expect(hostService.getHostsByIp(host3Address))
-                .andReturn(Sets.newHashSet(host3)).anyTimes();
-        hostService.startMonitoringIp(host3Address);
-        expectLastCall().anyTimes();
+        // Verify
+        Assert.assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
+        Intent firstIntent =
+                intentSynchronizer.getRouteIntents().iterator().next();
+        IntentKey firstIntentKey = new IntentKey(firstIntent);
+        IntentKey intentNewKey = new IntentKey(intentNew);
+        assertTrue(firstIntentKey.equals(intentNewKey));
+        verify(intentService);
+    }
 
+    /**
+     * Tests deleting a FIB entry.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is withdrawn from the IntentService.
+     *
+     * @throws TestUtilsException
+     */
+    @Test
+    public void testFibDelete() throws TestUtilsException {
+        // Firstly add a route
+        testFibAdd();
 
-        replay(hostService);
+        Intent addedIntent =
+                intentSynchronizer.getRouteIntents().iterator().next();
+
+        // Construct the existing route entry
+        FibEntry fibEntry = new FibEntry(
+                Ip4Prefix.valueOf("1.1.1.0/24"), null, null);
+
+        // Set up expectation
+        reset(intentService);
+        // Setup the expected intents
+        IntentOperations.Builder builder = IntentOperations.builder(APPID);
+        builder.addWithdrawOperation(addedIntent.id());
+        intentService.execute(TestIntentServiceHelper.eqExceptId(
+                builder.build()));
+        replay(intentService);
+
+        // Call the update() method in IntentSynchronizer class
+        intentSynchronizer.leaderChanged(true);
+        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
+        FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.DELETE, fibEntry);
+        intentSynchronizer.update(Collections.emptyList(),
+                                  Collections.singletonList(fibUpdate));
+
+        // Verify
+        Assert.assertEquals(intentSynchronizer.getRouteIntents().size(), 0);
+        verify(intentService);
     }
 
     /**
@@ -287,25 +520,7 @@
         MultiPointToSinglePointIntent intent6 = intentBuilder(
                 routeEntry6.prefix(), "00:00:00:00:00:01",  SW1_ETH1);
 
-        // Set up the ribTable field in Router class and routeIntents fields
-        // in IntentSynchronizer class
-        InvertedRadixTree<RouteEntry> ribTable =
-                new ConcurrentInvertedRadixTree<>(
-                new DefaultByteArrayNodeFactory());
-        ribTable.put(RouteEntry.createBinaryString(routeEntry1.prefix()),
-                     routeEntry1);
-        ribTable.put(RouteEntry.createBinaryString(routeEntry3.prefix()),
-                     routeEntry3);
-        ribTable.put(RouteEntry.createBinaryString(routeEntry4Update.prefix()),
-                     routeEntry4Update);
-        ribTable.put(RouteEntry.createBinaryString(routeEntry5.prefix()),
-                     routeEntry5);
-        ribTable.put(RouteEntry.createBinaryString(routeEntry6.prefix()),
-                     routeEntry6);
-        ribTable.put(RouteEntry.createBinaryString(routeEntry7.prefix()),
-                     routeEntry7);
-        TestUtils.setField(router, "ribTable4", ribTable);
-
+        // Set up the routeIntents field in IntentSynchronizer class
         ConcurrentHashMap<IpPrefix, MultiPointToSinglePointIntent>
             routeIntents =  new ConcurrentHashMap<>();
         routeIntents.put(routeEntry1.prefix(), intent1);
@@ -353,20 +568,9 @@
 
         // Start the test
         intentSynchronizer.leaderChanged(true);
-        /*
-        TestUtils.callMethod(intentSynchronizer, "synchronizeIntents",
-                             new Class<?>[] {});
-        */
         intentSynchronizer.synchronizeIntents();
 
         // Verify
-        assertEquals(router.getRoutes4().size(), 6);
-        assertTrue(router.getRoutes4().contains(routeEntry1));
-        assertTrue(router.getRoutes4().contains(routeEntry3));
-        assertTrue(router.getRoutes4().contains(routeEntry4Update));
-        assertTrue(router.getRoutes4().contains(routeEntry5));
-        assertTrue(router.getRoutes4().contains(routeEntry6));
-
         assertEquals(intentSynchronizer.getRouteIntents().size(), 6);
         assertTrue(intentSynchronizer.getRouteIntents().contains(intent1));
         assertTrue(intentSynchronizer.getRouteIntents().contains(intent3));
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
index 5311a72..298972d 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
@@ -41,7 +41,6 @@
 import org.onosproject.net.intent.IntentOperations;
 import org.onosproject.net.intent.IntentService;
 import org.onosproject.net.intent.PointToPointIntent;
-import org.onosproject.sdnip.bgp.BgpConstants;
 import org.onosproject.sdnip.config.BgpPeer;
 import org.onosproject.sdnip.config.BgpSpeaker;
 import org.onosproject.sdnip.config.Interface;
@@ -302,7 +301,7 @@
      */
     private void setUpBgpIntents() {
 
-        Short bgpPort = Short.valueOf((short) BgpConstants.BGP_PORT);
+        Short bgpPort = 179;
 
         // Start to build intents between BGP speaker1 and BGP peer1
         bgpPathintentConstructor(
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/RouteEntryTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/RouteEntryTest.java
deleted file mode 100644
index b977917..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/RouteEntryTest.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * 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;
-
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Test;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-
-/**
- * Unit tests for the RouteEntry class.
- */
-public class RouteEntryTest {
-    /**
-     * Tests valid class constructor.
-     */
-    @Test
-    public void testConstructor() {
-        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
-        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
-
-        RouteEntry routeEntry = new RouteEntry(prefix, nextHop);
-        assertThat(routeEntry.toString(),
-                   is("RouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8}"));
-    }
-
-    /**
-     * Tests invalid class constructor for null IPv4 prefix.
-     */
-    @Test(expected = NullPointerException.class)
-    public void testInvalidConstructorNullPrefix() {
-        Ip4Prefix prefix = null;
-        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
-
-        new RouteEntry(prefix, nextHop);
-    }
-
-    /**
-     * Tests invalid class constructor for null IPv4 next-hop.
-     */
-    @Test(expected = NullPointerException.class)
-    public void testInvalidConstructorNullNextHop() {
-        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
-        Ip4Address nextHop = null;
-
-        new RouteEntry(prefix, nextHop);
-    }
-
-    /**
-     * Tests getting the fields of a route entry.
-     */
-    @Test
-    public void testGetFields() {
-        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
-        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
-
-        RouteEntry routeEntry = new RouteEntry(prefix, nextHop);
-        assertThat(routeEntry.prefix(), is(prefix));
-        assertThat(routeEntry.nextHop(), is(nextHop));
-    }
-
-    /**
-     * Tests creating a binary string from IPv4 prefix.
-     */
-    @Test
-    public void testCreateBinaryString() {
-        Ip4Prefix prefix;
-
-        prefix = Ip4Prefix.valueOf("0.0.0.0/0");
-        assertThat(RouteEntry.createBinaryString(prefix), is(""));
-
-        prefix = Ip4Prefix.valueOf("192.168.166.0/22");
-        assertThat(RouteEntry.createBinaryString(prefix),
-                   is("1100000010101000101001"));
-
-        prefix = Ip4Prefix.valueOf("192.168.166.0/23");
-        assertThat(RouteEntry.createBinaryString(prefix),
-                   is("11000000101010001010011"));
-
-        prefix = Ip4Prefix.valueOf("192.168.166.0/24");
-        assertThat(RouteEntry.createBinaryString(prefix),
-                   is("110000001010100010100110"));
-
-        prefix = Ip4Prefix.valueOf("130.162.10.1/25");
-        assertThat(RouteEntry.createBinaryString(prefix),
-                   is("1000001010100010000010100"));
-
-        prefix = Ip4Prefix.valueOf("255.255.255.255/32");
-        assertThat(RouteEntry.createBinaryString(prefix),
-                   is("11111111111111111111111111111111"));
-    }
-
-    /**
-     * Tests equality of {@link RouteEntry}.
-     */
-    @Test
-    public void testEquality() {
-        Ip4Prefix prefix1 = Ip4Prefix.valueOf("1.2.3.0/24");
-        Ip4Address nextHop1 = Ip4Address.valueOf("5.6.7.8");
-        RouteEntry routeEntry1 = new RouteEntry(prefix1, nextHop1);
-
-        Ip4Prefix prefix2 = Ip4Prefix.valueOf("1.2.3.0/24");
-        Ip4Address nextHop2 = Ip4Address.valueOf("5.6.7.8");
-        RouteEntry routeEntry2 = new RouteEntry(prefix2, nextHop2);
-
-        assertThat(routeEntry1, is(routeEntry2));
-    }
-
-    /**
-     * Tests non-equality of {@link RouteEntry}.
-     */
-    @Test
-    public void testNonEquality() {
-        Ip4Prefix prefix1 = Ip4Prefix.valueOf("1.2.3.0/24");
-        Ip4Address nextHop1 = Ip4Address.valueOf("5.6.7.8");
-        RouteEntry routeEntry1 = new RouteEntry(prefix1, nextHop1);
-
-        Ip4Prefix prefix2 = Ip4Prefix.valueOf("1.2.3.0/25");      // Different
-        Ip4Address nextHop2 = Ip4Address.valueOf("5.6.7.8");
-        RouteEntry routeEntry2 = new RouteEntry(prefix2, nextHop2);
-
-        Ip4Prefix prefix3 = Ip4Prefix.valueOf("1.2.3.0/24");
-        Ip4Address nextHop3 = Ip4Address.valueOf("5.6.7.9");      // Different
-        RouteEntry routeEntry3 = new RouteEntry(prefix3, nextHop3);
-
-        assertThat(routeEntry1, is(not(routeEntry2)));
-        assertThat(routeEntry1, is(not(routeEntry3)));
-    }
-
-    /**
-     * Tests object string representation.
-     */
-    @Test
-    public void testToString() {
-        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
-        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
-        RouteEntry routeEntry = new RouteEntry(prefix, nextHop);
-
-        assertThat(routeEntry.toString(),
-                   is("RouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8}"));
-    }
-}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/RouterAsyncArpTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/RouterAsyncArpTest.java
deleted file mode 100644
index 4d14228..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/RouterAsyncArpTest.java
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * 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;
-
-import com.google.common.collect.Sets;
-import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory;
-import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree;
-import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.junit.TestUtils;
-import org.onlab.junit.TestUtils.TestUtilsException;
-import org.onlab.packet.Ethernet;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultHost;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.HostLocation;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.host.HostEvent;
-import org.onosproject.net.host.HostService;
-import org.onosproject.net.host.InterfaceIpAddress;
-import org.onosproject.net.intent.AbstractIntentTest;
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentOperations;
-import org.onosproject.net.intent.IntentService;
-import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.net.provider.ProviderId;
-import org.onosproject.sdnip.IntentSynchronizer.IntentKey;
-import org.onosproject.sdnip.Router.InternalHostListener;
-import org.onosproject.sdnip.config.BgpPeer;
-import org.onosproject.sdnip.config.Interface;
-import org.onosproject.sdnip.config.SdnIpConfigurationService;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import static org.easymock.EasyMock.*;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-/**
- * This class tests adding a route, updating a route, deleting a route, and
- * the ARP module answers the MAC address asynchronously.
- */
-public class RouterAsyncArpTest extends AbstractIntentTest {
-
-    private SdnIpConfigurationService sdnIpConfigService;
-    private InterfaceService interfaceService;
-    private IntentService intentService;
-    private HostService hostService;
-
-    private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000001"),
-            PortNumber.portNumber(1));
-
-    private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000002"),
-            PortNumber.portNumber(1));
-
-    private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000003"),
-            PortNumber.portNumber(1));
-
-    private IntentSynchronizer intentSynchronizer;
-    private Router router;
-    private InternalHostListener internalHostListener;
-
-    private static final ApplicationId APPID = new ApplicationId() {
-        @Override
-        public short id() {
-            return 1;
-        }
-
-        @Override
-        public String name() {
-            return "SDNIP";
-        }
-    };
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        setUpSdnIpConfigService();
-        setUpInterfaceService();
-        hostService = createMock(HostService.class);
-        intentService = createMock(IntentService.class);
-
-        intentSynchronizer = new IntentSynchronizer(APPID, intentService,
-                                                    sdnIpConfigService,
-                                                    interfaceService);
-        router = new Router(intentSynchronizer, hostService);
-        internalHostListener = router.new InternalHostListener();
-    }
-
-    /**
-     * Sets up SdnIpConfigService.
-     */
-    private void setUpSdnIpConfigService() {
-
-        sdnIpConfigService = createMock(SdnIpConfigurationService.class);
-
-        Map<IpAddress, BgpPeer> peers = new HashMap<>();
-
-        String peerSw1Eth1 = "192.168.10.1";
-        peers.put(IpAddress.valueOf(peerSw1Eth1),
-                new BgpPeer("00:00:00:00:00:00:00:01", 1, peerSw1Eth1));
-
-        // Two BGP peers are connected to switch 2 port 1.
-        String peer1Sw2Eth1 = "192.168.20.1";
-        peers.put(IpAddress.valueOf(peer1Sw2Eth1),
-                new BgpPeer("00:00:00:00:00:00:00:02", 1, peer1Sw2Eth1));
-
-        String peer2Sw2Eth1 = "192.168.20.2";
-        peers.put(IpAddress.valueOf(peer2Sw2Eth1),
-                new BgpPeer("00:00:00:00:00:00:00:02", 1, peer2Sw2Eth1));
-
-        expect(sdnIpConfigService.getBgpPeers()).andReturn(peers).anyTimes();
-        replay(sdnIpConfigService);
-    }
-
-    /**
-     * Sets up InterfaceService.
-     */
-    private void setUpInterfaceService() {
-
-        interfaceService = createMock(InterfaceService.class);
-
-        Set<Interface> interfaces = Sets.newHashSet();
-
-        Set<InterfaceIpAddress> interfaceIpAddresses1 = Sets.newHashSet();
-        interfaceIpAddresses1.add(new InterfaceIpAddress(
-                IpAddress.valueOf("192.168.10.101"),
-                IpPrefix.valueOf("192.168.10.0/24")));
-        Interface sw1Eth1 = new Interface(SW1_ETH1,
-                interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"),
-                VlanId.NONE);
-        interfaces.add(sw1Eth1);
-
-        Set<InterfaceIpAddress> interfaceIpAddresses2 = Sets.newHashSet();
-        interfaceIpAddresses2.add(new InterfaceIpAddress(
-                IpAddress.valueOf("192.168.20.101"),
-                IpPrefix.valueOf("192.168.20.0/24")));
-        Interface sw2Eth1 = new Interface(SW2_ETH1,
-                interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
-                VlanId.NONE);
-        interfaces.add(sw2Eth1);
-
-        Set<InterfaceIpAddress> interfaceIpAddresses3 = Sets.newHashSet();
-        interfaceIpAddresses3.add(new InterfaceIpAddress(
-                IpAddress.valueOf("192.168.30.101"),
-                IpPrefix.valueOf("192.168.30.0/24")));
-        Interface sw3Eth1 = new Interface(SW3_ETH1,
-                interfaceIpAddresses3, MacAddress.valueOf("00:00:00:00:00:03"),
-                VlanId.NONE);
-        interfaces.add(sw3Eth1);
-
-        expect(interfaceService.getInterface(SW1_ETH1)).andReturn(sw1Eth1).anyTimes();
-        expect(interfaceService.getInterface(SW2_ETH1)).andReturn(sw2Eth1).anyTimes();
-        expect(interfaceService.getInterface(SW3_ETH1)).andReturn(sw3Eth1).anyTimes();
-        expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
-        replay(interfaceService);
-    }
-
-    /**
-     * This method tests adding a route entry.
-     */
-    @Test
-    public void testRouteAdd() throws TestUtilsException {
-
-        // Construct a route entry
-        RouteEntry routeEntry = new RouteEntry(
-                Ip4Prefix.valueOf("1.1.1.0/24"),
-                Ip4Address.valueOf("192.168.10.1"));
-
-        // Construct a route intent
-        MultiPointToSinglePointIntent intent = staticIntentBuilder();
-
-        // Set up test expectation
-        reset(hostService);
-        expect(hostService.getHostsByIp(anyObject(IpAddress.class))).andReturn(
-                new HashSet<Host>()).anyTimes();
-        hostService.startMonitoringIp(IpAddress.valueOf("192.168.10.1"));
-        replay(hostService);
-
-        reset(intentService);
-        IntentOperations.Builder builder = IntentOperations.builder(APPID);
-        builder.addSubmitOperation(intent);
-        intentService.execute(TestIntentServiceHelper.eqExceptId(
-                                builder.build()));
-        replay(intentService);
-
-        // Call the processRouteUpdates() method in Router class
-        intentSynchronizer.leaderChanged(true);
-        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
-        RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
-                                                  routeEntry);
-        router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate));
-
-        Host host = new DefaultHost(ProviderId.NONE, HostId.NONE,
-                MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE,
-                new HostLocation(
-                        SW1_ETH1.deviceId(),
-                        SW1_ETH1.port(), 1),
-                        Sets.newHashSet(IpAddress.valueOf("192.168.10.1")));
-        internalHostListener.event(
-                new HostEvent(HostEvent.Type.HOST_ADDED, host));
-
-        // Verify
-        assertEquals(router.getRoutes4().size(), 1);
-        assertTrue(router.getRoutes4().contains(routeEntry));
-        assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
-        Intent firstIntent =
-            intentSynchronizer.getRouteIntents().iterator().next();
-        IntentKey firstIntentKey = new IntentKey(firstIntent);
-        IntentKey intentKey = new IntentKey(intent);
-        assertTrue(firstIntentKey.equals(intentKey));
-        verify(intentService);
-        verify(hostService);
-
-    }
-
-    /**
-     * This method tests updating a route entry.
-     *
-     * @throws TestUtilsException
-     */
-    @Test
-    public void testRouteUpdate() throws TestUtilsException {
-
-        // Construct the existing route entry
-        RouteEntry routeEntry = new RouteEntry(
-                Ip4Prefix.valueOf("1.1.1.0/24"),
-                Ip4Address.valueOf("192.168.10.1"));
-
-        // Construct the existing MultiPointToSinglePointIntent intent
-        MultiPointToSinglePointIntent intent = staticIntentBuilder();
-
-        // Set up the ribTable field of Router class with existing route, and
-        // routeIntents field with the corresponding existing intent
-        setRibTableField(routeEntry);
-        setRouteIntentsField(routeEntry, intent);
-
-        // Start to construct a new route entry and new intent
-        RouteEntry routeEntryUpdate = new RouteEntry(
-                Ip4Prefix.valueOf("1.1.1.0/24"),
-                Ip4Address.valueOf("192.168.20.1"));
-
-        // Construct a new MultiPointToSinglePointIntent intent
-        TrafficSelector.Builder selectorBuilderNew =
-                DefaultTrafficSelector.builder();
-        selectorBuilderNew.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
-                routeEntryUpdate.prefix());
-
-        TrafficTreatment.Builder treatmentBuilderNew =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilderNew.setEthDst(MacAddress.valueOf("00:00:00:00:00:02"));
-
-        Set<ConnectPoint> ingressPointsNew = new HashSet<ConnectPoint>();
-        ingressPointsNew.add(SW1_ETH1);
-        ingressPointsNew.add(SW3_ETH1);
-
-        MultiPointToSinglePointIntent intentNew =
-                new MultiPointToSinglePointIntent(APPID,
-                        selectorBuilderNew.build(),
-                        treatmentBuilderNew.build(),
-                        ingressPointsNew, SW2_ETH1);
-
-        // Set up test expectation
-        reset(hostService);
-        expect(hostService.getHostsByIp(anyObject(IpAddress.class))).andReturn(
-                new HashSet<Host>()).anyTimes();
-        hostService.startMonitoringIp(IpAddress.valueOf("192.168.20.1"));
-        replay(hostService);
-
-        reset(intentService);
-        IntentOperations.Builder builder = IntentOperations.builder(APPID);
-        builder.addWithdrawOperation(intent.id());
-        intentService.execute(TestIntentServiceHelper.eqExceptId(
-                                builder.build()));
-        builder = IntentOperations.builder(APPID);
-        builder.addSubmitOperation(intentNew);
-        intentService.execute(TestIntentServiceHelper.eqExceptId(
-                                builder.build()));
-        replay(intentService);
-
-        // Call the processRouteUpdates() method in Router class
-        intentSynchronizer.leaderChanged(true);
-        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
-        RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
-                                                  routeEntryUpdate);
-        router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate));
-
-        Host host = new DefaultHost(ProviderId.NONE, HostId.NONE,
-                MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE,
-                new HostLocation(
-                        SW2_ETH1.deviceId(),
-                        SW2_ETH1.port(), 1),
-                        Sets.newHashSet(IpAddress.valueOf("192.168.20.1")));
-        internalHostListener.event(
-                new HostEvent(HostEvent.Type.HOST_ADDED, host));
-
-        // Verify
-        assertEquals(router.getRoutes4().size(), 1);
-        assertTrue(router.getRoutes4().contains(routeEntryUpdate));
-        assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
-        Intent firstIntent =
-            intentSynchronizer.getRouteIntents().iterator().next();
-        IntentKey firstIntentKey = new IntentKey(firstIntent);
-        IntentKey intentNewKey = new IntentKey(intentNew);
-        assertTrue(firstIntentKey.equals(intentNewKey));
-        verify(intentService);
-        verify(hostService);
-    }
-
-    /**
-     * This method tests deleting a route entry.
-     */
-    @Test
-    public void testRouteDelete() throws TestUtilsException {
-
-        // Construct the existing route entry
-        RouteEntry routeEntry = new RouteEntry(
-                Ip4Prefix.valueOf("1.1.1.0/24"),
-                Ip4Address.valueOf("192.168.10.1"));
-
-        // Construct the existing MultiPointToSinglePointIntent intent
-        MultiPointToSinglePointIntent intent = staticIntentBuilder();
-
-        // Set up the ribTable field of Router class with existing route, and
-        // routeIntents field with the corresponding existing intent
-        setRibTableField(routeEntry);
-        setRouteIntentsField(routeEntry, intent);
-
-        // Set up expectation
-        reset(intentService);
-        IntentOperations.Builder builder = IntentOperations.builder(APPID);
-        builder.addWithdrawOperation(intent.id());
-        intentService.execute(TestIntentServiceHelper.eqExceptId(
-                                builder.build()));
-        replay(intentService);
-
-        // Call the processRouteUpdates() method in Router class
-        intentSynchronizer.leaderChanged(true);
-        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
-        RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.DELETE,
-                                                  routeEntry);
-        router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate));
-
-        // Verify
-        assertEquals(router.getRoutes4().size(), 0);
-        assertEquals(intentSynchronizer.getRouteIntents().size(), 0);
-        verify(intentService);
-    }
-
-    /**
-     * Constructs a static MultiPointToSinglePointIntent.
-     */
-    private MultiPointToSinglePointIntent staticIntentBuilder() {
-
-        TrafficSelector.Builder selectorBuilder =
-                DefaultTrafficSelector.builder();
-        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
-                IpPrefix.valueOf("1.1.1.0/24"));
-
-        TrafficTreatment.Builder treatmentBuilder =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
-
-        Set<ConnectPoint> ingressPoints = new HashSet<ConnectPoint>();
-        ingressPoints.add(SW2_ETH1);
-        ingressPoints.add(SW3_ETH1);
-
-        MultiPointToSinglePointIntent intent =
-                new MultiPointToSinglePointIntent(APPID,
-                        selectorBuilder.build(), treatmentBuilder.build(),
-                        ingressPoints, SW1_ETH1);
-
-        return intent;
-    }
-
-    /**
-     * Sets ribTable Field in Router class.
-     *
-     * @throws TestUtilsException
-     */
-    private void setRibTableField(RouteEntry routeEntry)
-            throws TestUtilsException {
-
-        InvertedRadixTree<RouteEntry> ribTable =
-                new ConcurrentInvertedRadixTree<>(
-                new DefaultByteArrayNodeFactory());
-        ribTable.put(RouteEntry.createBinaryString(routeEntry.prefix()),
-                     routeEntry);
-        TestUtils.setField(router, "ribTable4", ribTable);
-    }
-
-    /**
-     * Sets routeIntentsField in IntentSynchronizer class.
-     *
-     * @throws TestUtilsException
-     */
-    private void setRouteIntentsField(RouteEntry routeEntry,
-            MultiPointToSinglePointIntent intent)
-            throws TestUtilsException {
-
-        ConcurrentHashMap<IpPrefix, MultiPointToSinglePointIntent>
-            routeIntents =  new ConcurrentHashMap<>();
-        routeIntents.put(routeEntry.prefix(), intent);
-        TestUtils.setField(intentSynchronizer, "routeIntents", routeIntents);
-    }
-}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/RouterTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/RouterTest.java
deleted file mode 100644
index a7b4cce..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/RouterTest.java
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * 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;
-
-import com.google.common.collect.Sets;
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.junit.TestUtils;
-import org.onlab.junit.TestUtils.TestUtilsException;
-import org.onlab.packet.Ethernet;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultHost;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.HostLocation;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.host.HostListener;
-import org.onosproject.net.host.HostService;
-import org.onosproject.net.host.InterfaceIpAddress;
-import org.onosproject.net.intent.AbstractIntentTest;
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentOperations;
-import org.onosproject.net.intent.IntentService;
-import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.net.provider.ProviderId;
-import org.onosproject.sdnip.IntentSynchronizer.IntentKey;
-import org.onosproject.sdnip.config.BgpPeer;
-import org.onosproject.sdnip.config.Interface;
-import org.onosproject.sdnip.config.SdnIpConfigurationService;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import static org.easymock.EasyMock.*;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-/**
- * This class tests adding a route, updating a route, deleting a route,
- * and adding a route whose next hop is the local BGP speaker.
- * <p/>
- * ARP module answers the MAC address synchronously.
- */
-public class RouterTest extends AbstractIntentTest {
-
-    private SdnIpConfigurationService sdnIpConfigService;
-    private InterfaceService interfaceService;
-    private IntentService intentService;
-    private HostService hostService;
-
-    private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000001"),
-            PortNumber.portNumber(1));
-
-    private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000002"),
-            PortNumber.portNumber(1));
-
-    private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000003"),
-            PortNumber.portNumber(1));
-
-    private static final ConnectPoint SW4_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000004"),
-            PortNumber.portNumber(1));
-
-    private static final ApplicationId APPID = new ApplicationId() {
-        @Override
-        public short id() {
-            return 1;
-        }
-
-        @Override
-        public String name() {
-            return "SDNIP";
-        }
-    };
-
-    private IntentSynchronizer intentSynchronizer;
-    private Router router;
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        setUpBgpPeers();
-
-        setUpInterfaceService();
-        setUpHostService();
-
-        intentService = createMock(IntentService.class);
-
-        intentSynchronizer = new IntentSynchronizer(APPID, intentService,
-                                                    sdnIpConfigService,
-                                                    interfaceService);
-        router = new Router(intentSynchronizer, hostService);
-    }
-
-    /**
-     * Sets up BGP peers in external networks.
-     */
-    private void setUpBgpPeers() {
-
-        Map<IpAddress, BgpPeer> peers = new HashMap<>();
-
-        String peerSw1Eth1 = "192.168.10.1";
-        peers.put(IpAddress.valueOf(peerSw1Eth1),
-                new BgpPeer("00:00:00:00:00:00:00:01", 1, peerSw1Eth1));
-
-        // Two BGP peers are connected to switch 2 port 1.
-        String peer1Sw2Eth1 = "192.168.20.1";
-        peers.put(IpAddress.valueOf(peer1Sw2Eth1),
-                new BgpPeer("00:00:00:00:00:00:00:02", 1, peer1Sw2Eth1));
-
-        String peer2Sw2Eth1 = "192.168.20.2";
-        peers.put(IpAddress.valueOf(peer2Sw2Eth1),
-                new BgpPeer("00:00:00:00:00:00:00:02", 1, peer2Sw2Eth1));
-
-        String peer1Sw4Eth1 = "192.168.40.1";
-        peers.put(IpAddress.valueOf(peer1Sw4Eth1),
-                new BgpPeer("00:00:00:00:00:00:00:04", 1, peer1Sw4Eth1));
-
-        sdnIpConfigService = createMock(SdnIpConfigurationService.class);
-        expect(sdnIpConfigService.getBgpPeers()).andReturn(peers).anyTimes();
-        replay(sdnIpConfigService);
-
-    }
-
-    /**
-     * Sets up logical interfaces, which emulate the configured interfaces
-     * in SDN-IP application.
-     */
-    private void setUpInterfaceService() {
-        interfaceService = createMock(InterfaceService.class);
-
-        Set<Interface> interfaces = Sets.newHashSet();
-
-        InterfaceIpAddress ia1 =
-            new InterfaceIpAddress(IpAddress.valueOf("192.168.10.101"),
-                                   IpPrefix.valueOf("192.168.10.0/24"));
-        Interface sw1Eth1 = new Interface(SW1_ETH1,
-                Sets.newHashSet(ia1),
-                MacAddress.valueOf("00:00:00:00:00:01"),
-                VlanId.NONE);
-
-        expect(interfaceService.getInterface(SW1_ETH1)).andReturn(sw1Eth1).anyTimes();
-        interfaces.add(sw1Eth1);
-
-        InterfaceIpAddress ia2 =
-            new InterfaceIpAddress(IpAddress.valueOf("192.168.20.101"),
-                                   IpPrefix.valueOf("192.168.20.0/24"));
-        Interface sw2Eth1 = new Interface(SW2_ETH1,
-                Sets.newHashSet(ia2),
-                MacAddress.valueOf("00:00:00:00:00:02"),
-                VlanId.NONE);
-
-        expect(interfaceService.getInterface(SW2_ETH1)).andReturn(sw2Eth1).anyTimes();
-        interfaces.add(sw2Eth1);
-
-        InterfaceIpAddress ia3 =
-            new InterfaceIpAddress(IpAddress.valueOf("192.168.30.101"),
-                                   IpPrefix.valueOf("192.168.30.0/24"));
-        Interface sw3Eth1 = new Interface(SW3_ETH1,
-                Sets.newHashSet(ia3),
-                MacAddress.valueOf("00:00:00:00:00:03"),
-                VlanId.NONE);
-
-        expect(interfaceService.getInterface(SW3_ETH1)).andReturn(sw3Eth1).anyTimes();
-        interfaces.add(sw3Eth1);
-
-        InterfaceIpAddress ia4 =
-                new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"),
-                                       IpPrefix.valueOf("192.168.40.0/24"));
-            Interface sw4Eth1 = new Interface(SW4_ETH1,
-                    Sets.newHashSet(ia4),
-                    MacAddress.valueOf("00:00:00:00:00:04"),
-                    VlanId.vlanId((short) 1));
-
-            expect(interfaceService.getInterface(SW4_ETH1)).andReturn(sw4Eth1).anyTimes();
-            interfaces.add(sw4Eth1);
-
-        expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
-
-        replay(interfaceService);
-    }
-
-    /**
-     * Sets up the host service with details of some hosts.
-     */
-    private void setUpHostService() {
-        hostService = createMock(HostService.class);
-
-        hostService.addListener(anyObject(HostListener.class));
-        expectLastCall().anyTimes();
-
-        IpAddress host1Address = IpAddress.valueOf("192.168.10.1");
-        Host host1 = new DefaultHost(ProviderId.NONE, HostId.NONE,
-                MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE,
-                new HostLocation(SW1_ETH1, 1),
-                Sets.newHashSet(host1Address));
-
-        expect(hostService.getHostsByIp(host1Address))
-                .andReturn(Sets.newHashSet(host1)).anyTimes();
-        hostService.startMonitoringIp(host1Address);
-        expectLastCall().anyTimes();
-
-
-        IpAddress host2Address = IpAddress.valueOf("192.168.20.1");
-        Host host2 = new DefaultHost(ProviderId.NONE, HostId.NONE,
-                MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE,
-                new HostLocation(SW2_ETH1, 1),
-                Sets.newHashSet(host2Address));
-
-        expect(hostService.getHostsByIp(host2Address))
-                .andReturn(Sets.newHashSet(host2)).anyTimes();
-        hostService.startMonitoringIp(host2Address);
-        expectLastCall().anyTimes();
-
-        // Next hop on a VLAN
-        IpAddress host3Address = IpAddress.valueOf("192.168.40.1");
-        Host host3 = new DefaultHost(ProviderId.NONE, HostId.NONE,
-                MacAddress.valueOf("00:00:00:00:00:03"), VlanId.vlanId((short) 1),
-                new HostLocation(SW4_ETH1, 1),
-                Sets.newHashSet(host3Address));
-
-        expect(hostService.getHostsByIp(host3Address))
-                .andReturn(Sets.newHashSet(host3)).anyTimes();
-        hostService.startMonitoringIp(host3Address);
-        expectLastCall().anyTimes();
-
-
-        replay(hostService);
-    }
-
-    /**
-     * This method tests adding a route entry.
-     */
-    @Test
-    public void testRouteAdd() throws TestUtilsException {
-        // Construct a route entry
-        RouteEntry routeEntry = new RouteEntry(
-                Ip4Prefix.valueOf("1.1.1.0/24"),
-                Ip4Address.valueOf("192.168.10.1"));
-
-        // Construct a MultiPointToSinglePointIntent intent
-        TrafficSelector.Builder selectorBuilder =
-                DefaultTrafficSelector.builder();
-        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
-                routeEntry.prefix());
-
-        TrafficTreatment.Builder treatmentBuilder =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
-
-        Set<ConnectPoint> ingressPoints = new HashSet<ConnectPoint>();
-        ingressPoints.add(SW2_ETH1);
-        ingressPoints.add(SW3_ETH1);
-        ingressPoints.add(SW4_ETH1);
-
-        MultiPointToSinglePointIntent intent =
-                new MultiPointToSinglePointIntent(APPID,
-                        selectorBuilder.build(), treatmentBuilder.build(),
-                        ingressPoints, SW1_ETH1);
-
-        // Set up test expectation
-        reset(intentService);
-        // Setup the expected intents
-        IntentOperations.Builder builder = IntentOperations.builder(APPID);
-        builder.addSubmitOperation(intent);
-        intentService.execute(TestIntentServiceHelper.eqExceptId(
-                                builder.build()));
-        replay(intentService);
-
-        // Call the processRouteUpdates() method in Router class
-        intentSynchronizer.leaderChanged(true);
-        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
-        RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
-                                                  routeEntry);
-        router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate));
-
-        // Verify
-        assertEquals(router.getRoutes4().size(), 1);
-        assertTrue(router.getRoutes4().contains(routeEntry));
-        assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
-        Intent firstIntent =
-            intentSynchronizer.getRouteIntents().iterator().next();
-        IntentKey firstIntentKey = new IntentKey(firstIntent);
-        IntentKey intentKey = new IntentKey(intent);
-        assertTrue(firstIntentKey.equals(intentKey));
-        verify(intentService);
-    }
-
-    /**
-     * This method tests adding a route entry.
-     */
-    @Test
-    public void testRouteAddWithVlan() throws TestUtilsException {
-        // Construct a route entry
-        RouteEntry routeEntry = new RouteEntry(
-                Ip4Prefix.valueOf("3.3.3.0/24"),
-                Ip4Address.valueOf("192.168.40.1"));
-
-        // Construct a MultiPointToSinglePointIntent intent
-        TrafficSelector.Builder selectorBuilder =
-                DefaultTrafficSelector.builder();
-        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4)
-                       .matchIPDst(routeEntry.prefix())
-                       .matchVlanId(VlanId.ANY);
-
-        TrafficTreatment.Builder treatmentBuilder =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:03"))
-                        .setVlanId(VlanId.vlanId((short) 1));
-
-        Set<ConnectPoint> ingressPoints = new HashSet<ConnectPoint>();
-        ingressPoints.add(SW1_ETH1);
-        ingressPoints.add(SW2_ETH1);
-        ingressPoints.add(SW3_ETH1);
-
-        MultiPointToSinglePointIntent intent =
-                new MultiPointToSinglePointIntent(APPID,
-                        selectorBuilder.build(), treatmentBuilder.build(),
-                        ingressPoints, SW4_ETH1);
-
-        // Set up test expectation
-        reset(intentService);
-        // Setup the expected intents
-        IntentOperations.Builder builder = IntentOperations.builder(APPID);
-        builder.addSubmitOperation(intent);
-        intentService.execute(TestIntentServiceHelper.eqExceptId(
-                                builder.build()));
-        replay(intentService);
-
-        // Call the processRouteUpdates() method in Router class
-        intentSynchronizer.leaderChanged(true);
-        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
-        RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
-                                                  routeEntry);
-        router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate));
-
-        // Verify
-        assertEquals(router.getRoutes4().size(), 1);
-        assertTrue(router.getRoutes4().contains(routeEntry));
-        assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
-        Intent firstIntent =
-            intentSynchronizer.getRouteIntents().iterator().next();
-        IntentKey firstIntentKey = new IntentKey(firstIntent);
-        IntentKey intentKey = new IntentKey(intent);
-        assertTrue(firstIntentKey.equals(intentKey));
-        verify(intentService);
-    }
-
-    /**
-     * This method tests updating a route entry.
-     *
-     * @throws TestUtilsException
-     */
-    @Test
-    public void testRouteUpdate() throws TestUtilsException {
-        // Firstly add a route
-        testRouteAdd();
-
-        Intent addedIntent =
-            intentSynchronizer.getRouteIntents().iterator().next();
-
-        // Start to construct a new route entry and new intent
-        RouteEntry routeEntryUpdate = new RouteEntry(
-                Ip4Prefix.valueOf("1.1.1.0/24"),
-                Ip4Address.valueOf("192.168.20.1"));
-
-        // Construct a new MultiPointToSinglePointIntent intent
-        TrafficSelector.Builder selectorBuilderNew =
-                DefaultTrafficSelector.builder();
-        selectorBuilderNew.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
-                routeEntryUpdate.prefix());
-
-        TrafficTreatment.Builder treatmentBuilderNew =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilderNew.setEthDst(MacAddress.valueOf("00:00:00:00:00:02"));
-
-
-        Set<ConnectPoint> ingressPointsNew = new HashSet<ConnectPoint>();
-        ingressPointsNew.add(SW1_ETH1);
-        ingressPointsNew.add(SW3_ETH1);
-        ingressPointsNew.add(SW4_ETH1);
-
-        MultiPointToSinglePointIntent intentNew =
-                new MultiPointToSinglePointIntent(APPID,
-                        selectorBuilderNew.build(),
-                        treatmentBuilderNew.build(),
-                        ingressPointsNew, SW2_ETH1);
-
-        // Set up test expectation
-        reset(intentService);
-        // Setup the expected intents
-        IntentOperations.Builder builder = IntentOperations.builder(APPID);
-        builder.addWithdrawOperation(addedIntent.id());
-        intentService.execute(TestIntentServiceHelper.eqExceptId(
-                                builder.build()));
-        builder = IntentOperations.builder(APPID);
-        builder.addSubmitOperation(intentNew);
-        intentService.execute(TestIntentServiceHelper.eqExceptId(
-                                builder.build()));
-        replay(intentService);
-
-        // Call the processRouteUpdates() method in Router class
-        intentSynchronizer.leaderChanged(true);
-        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
-        RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
-                                                  routeEntryUpdate);
-        router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate));
-
-        // Verify
-        assertEquals(router.getRoutes4().size(), 1);
-        assertTrue(router.getRoutes4().contains(routeEntryUpdate));
-        assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
-        Intent firstIntent =
-            intentSynchronizer.getRouteIntents().iterator().next();
-        IntentKey firstIntentKey = new IntentKey(firstIntent);
-        IntentKey intentNewKey = new IntentKey(intentNew);
-        assertTrue(firstIntentKey.equals(intentNewKey));
-        verify(intentService);
-    }
-
-    /**
-     * This method tests deleting a route entry.
-     */
-    @Test
-    public void testRouteDelete() throws TestUtilsException {
-        // Firstly add a route
-        testRouteAdd();
-
-        Intent addedIntent =
-            intentSynchronizer.getRouteIntents().iterator().next();
-
-        // Construct the existing route entry
-        RouteEntry routeEntry = new RouteEntry(
-                Ip4Prefix.valueOf("1.1.1.0/24"),
-                Ip4Address.valueOf("192.168.10.1"));
-
-        // Set up expectation
-        reset(intentService);
-        // Setup the expected intents
-        IntentOperations.Builder builder = IntentOperations.builder(APPID);
-        builder.addWithdrawOperation(addedIntent.id());
-        intentService.execute(TestIntentServiceHelper.eqExceptId(
-                                builder.build()));
-        replay(intentService);
-
-        // Call the processRouteUpdates() method in Router class
-        intentSynchronizer.leaderChanged(true);
-        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
-        RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.DELETE,
-                                                  routeEntry);
-        router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate));
-
-        // Verify
-        assertEquals(router.getRoutes4().size(), 0);
-        assertEquals(intentSynchronizer.getRouteIntents().size(), 0);
-        verify(intentService);
-    }
-
-    /**
-     * This method tests when the next hop of a route is the local BGP speaker.
-     *
-     * @throws TestUtilsException
-     */
-    @Test
-    public void testLocalRouteAdd() throws TestUtilsException {
-        // Construct a route entry, the next hop is the local BGP speaker
-        RouteEntry routeEntry = new RouteEntry(
-                Ip4Prefix.valueOf("1.1.1.0/24"),
-                Ip4Address.valueOf("0.0.0.0"));
-
-        // Reset intentService to check whether the submit method is called
-        reset(intentService);
-        replay(intentService);
-
-        // Call the processRouteUpdates() method in Router class
-        intentSynchronizer.leaderChanged(true);
-        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
-        RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
-                                                  routeEntry);
-        router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate));
-
-        // Verify
-        assertEquals(router.getRoutes4().size(), 1);
-        assertTrue(router.getRoutes4().contains(routeEntry));
-        assertEquals(intentSynchronizer.getRouteIntents().size(), 0);
-        verify(intentService);
-    }
-}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpTest.java
deleted file mode 100644
index 157c73f..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpTest.java
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * 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;
-
-import com.google.common.collect.Sets;
-import org.easymock.IAnswer;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.onlab.junit.IntegrationTest;
-import org.onlab.junit.TestUtils;
-import org.onlab.junit.TestUtils.TestUtilsException;
-import org.onlab.packet.Ethernet;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.host.HostService;
-import org.onosproject.net.host.InterfaceIpAddress;
-import org.onosproject.net.intent.AbstractIntentTest;
-import org.onosproject.net.intent.IntentService;
-import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.sdnip.config.BgpPeer;
-import org.onosproject.sdnip.config.Interface;
-import org.onosproject.sdnip.config.SdnIpConfigurationService;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import static org.easymock.EasyMock.*;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-/**
- * Integration tests for the SDN-IP application.
- * <p/>
- * The tests are very coarse-grained. They feed route updates in to
- * {@link Router} (simulating routes learnt from iBGP module inside SDN-IP
- * application), then they check that the correct intents are created and
- * submitted to the intent service. The entire route processing logic of
- * Router class is tested.
- */
-@Category(IntegrationTest.class)
-public class SdnIpTest extends AbstractIntentTest {
-    private static final int MAC_ADDRESS_LENGTH = 6;
-    private static final int MIN_PREFIX_LENGTH = 1;
-    private static final int MAX_PREFIX_LENGTH = 32;
-
-    private IntentSynchronizer intentSynchronizer;
-    static Router router;
-
-    private SdnIpConfigurationService sdnIpConfigService;
-    private InterfaceService interfaceService;
-    private HostService hostService;
-    private IntentService intentService;
-
-    private Map<IpAddress, BgpPeer> bgpPeers;
-
-    private Random random;
-
-    static final ConnectPoint SW1_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000001"),
-            PortNumber.portNumber(1));
-
-    static final ConnectPoint SW2_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000002"),
-            PortNumber.portNumber(1));
-
-    static final ConnectPoint SW3_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000003"),
-            PortNumber.portNumber(1));
-
-    private static final ApplicationId APPID = new ApplicationId() {
-        @Override
-        public short id() {
-            return 1;
-        }
-
-        @Override
-        public String name() {
-            return "SDNIP";
-        }
-    };
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        setUpInterfaceService();
-        setUpSdnIpConfigService();
-
-        hostService = new TestHostService();
-        intentService = createMock(IntentService.class);
-        random = new Random();
-
-        intentSynchronizer = new IntentSynchronizer(APPID, intentService,
-                                                    sdnIpConfigService,
-                                                    interfaceService);
-        router = new Router(intentSynchronizer, hostService);
-    }
-
-    /**
-     * Sets up InterfaceService and virtual {@link Interface}s.
-     */
-    private void setUpInterfaceService() {
-
-        interfaceService = createMock(InterfaceService.class);
-
-        Set<Interface> interfaces = Sets.newHashSet();
-
-        Set<InterfaceIpAddress> interfaceIpAddresses1 = Sets.newHashSet();
-        interfaceIpAddresses1.add(new InterfaceIpAddress(
-                IpAddress.valueOf("192.168.10.101"),
-                IpPrefix.valueOf("192.168.10.0/24")));
-        Interface sw1Eth1 = new Interface(SW1_ETH1,
-                interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"),
-                VlanId.NONE);
-        interfaces.add(sw1Eth1);
-
-        Set<InterfaceIpAddress> interfaceIpAddresses2 = Sets.newHashSet();
-        interfaceIpAddresses2.add(new InterfaceIpAddress(
-                IpAddress.valueOf("192.168.20.101"),
-                IpPrefix.valueOf("192.168.20.0/24")));
-        Interface sw2Eth1 = new Interface(SW2_ETH1,
-                interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
-                VlanId.NONE);
-        interfaces.add(sw2Eth1);
-
-        Set<InterfaceIpAddress> interfaceIpAddresses3 = Sets.newHashSet();
-        interfaceIpAddresses3.add(new InterfaceIpAddress(
-                IpAddress.valueOf("192.168.30.101"),
-                IpPrefix.valueOf("192.168.30.0/24")));
-        Interface sw3Eth1 = new Interface(SW3_ETH1,
-                interfaceIpAddresses3, MacAddress.valueOf("00:00:00:00:00:03"),
-                VlanId.NONE);
-        interfaces.add(sw3Eth1);
-
-        expect(interfaceService.getInterface(SW1_ETH1)).andReturn(
-                sw1Eth1).anyTimes();
-        expect(interfaceService.getInterface(SW2_ETH1)).andReturn(
-                sw2Eth1).anyTimes();
-        expect(interfaceService.getInterface(SW3_ETH1)).andReturn(
-                sw3Eth1).anyTimes();
-
-        expect(interfaceService.getInterfaces()).andReturn(
-                interfaces).anyTimes();
-        replay(interfaceService);
-    }
-
-    /**
-     * Sets up SdnIpConfigService and BGP peers in external networks.
-     */
-    private void setUpSdnIpConfigService() {
-
-        sdnIpConfigService = createMock(SdnIpConfigurationService.class);
-
-        bgpPeers = new HashMap<>();
-
-        String peerSw1Eth1 = "192.168.10.1";
-        bgpPeers.put(IpAddress.valueOf(peerSw1Eth1),
-                new BgpPeer("00:00:00:00:00:00:00:01", 1, peerSw1Eth1));
-
-        String peer1Sw2Eth1 = "192.168.20.1";
-        bgpPeers.put(IpAddress.valueOf(peer1Sw2Eth1),
-                new BgpPeer("00:00:00:00:00:00:00:02", 1, peer1Sw2Eth1));
-
-        String peer2Sw2Eth1 = "192.168.30.1";
-        bgpPeers.put(IpAddress.valueOf(peer2Sw2Eth1),
-                new BgpPeer("00:00:00:00:00:00:00:03", 1, peer2Sw2Eth1));
-
-        expect(sdnIpConfigService.getBgpPeers()).andReturn(bgpPeers).anyTimes();
-        replay(sdnIpConfigService);
-    }
-
-    /**
-     * Tests adding a set of routes into {@link Router}.
-     * <p/>
-     * Random routes are generated and fed in to the route processing
-     * logic (via processRouteAdd in Router class). We check that the correct
-     * intents are generated and submitted to our mock intent service.
-     *
-     * @throws InterruptedException if interrupted while waiting on a latch
-     * @throws TestUtilsException if exceptions when using TestUtils
-     */
-    @Test
-    public void testAddRoutes() throws InterruptedException, TestUtilsException {
-        int numRoutes = 100;
-
-        final CountDownLatch latch = new CountDownLatch(numRoutes);
-
-        List<RouteUpdate> routeUpdates = generateRouteUpdates(numRoutes);
-
-        // Set up expectation
-        reset(intentService);
-
-        for (RouteUpdate update : routeUpdates) {
-            IpAddress nextHopAddress = update.routeEntry().nextHop();
-
-            // Find out the egress ConnectPoint
-            ConnectPoint egressConnectPoint = getConnectPoint(nextHopAddress);
-
-            MultiPointToSinglePointIntent intent = getIntentForUpdate(update,
-                    generateMacAddress(nextHopAddress),
-                    egressConnectPoint);
-            intentService.submit(TestIntentServiceHelper.eqExceptId(intent));
-
-            expectLastCall().andAnswer(new IAnswer<Object>() {
-                @Override
-                public Object answer() throws Throwable {
-                    latch.countDown();
-                    return null;
-                }
-            }).once();
-        }
-
-        replay(intentService);
-
-        intentSynchronizer.leaderChanged(true);
-        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
-
-        // Add route updates
-        router.processRouteUpdates(routeUpdates);
-
-        latch.await(5000, TimeUnit.MILLISECONDS);
-
-        assertEquals(router.getRoutes4().size(), numRoutes);
-        assertEquals(intentSynchronizer.getRouteIntents().size(),
-                     numRoutes);
-
-        verify(intentService);
-    }
-
-    /**
-     * Tests adding then deleting a set of routes from {@link Router}.
-     * <p/>
-     * Random routes are generated and fed in to the route processing
-     * logic (via processRouteAdd in Router class), and we check that the
-     * correct intents are generated. We then delete the entire set of routes
-     * (by feeding updates to processRouteDelete), and check that the correct
-     * intents are withdrawn from the intent service.
-     *
-     * @throws InterruptedException if interrupted while waiting on a latch
-     * @throws TestUtilsException exceptions when using TestUtils
-     */
-    @Test
-    public void testDeleteRoutes() throws InterruptedException, TestUtilsException {
-        int numRoutes = 100;
-        List<RouteUpdate> routeUpdates = generateRouteUpdates(numRoutes);
-
-        final CountDownLatch installCount = new CountDownLatch(numRoutes);
-        final CountDownLatch deleteCount = new CountDownLatch(numRoutes);
-
-        // Set up expectation
-        reset(intentService);
-
-        for (RouteUpdate update : routeUpdates) {
-            IpAddress nextHopAddress = update.routeEntry().nextHop();
-
-            // Find out the egress ConnectPoint
-            ConnectPoint egressConnectPoint = getConnectPoint(nextHopAddress);
-            MultiPointToSinglePointIntent intent = getIntentForUpdate(update,
-                    generateMacAddress(nextHopAddress),
-                    egressConnectPoint);
-            intentService.submit(TestIntentServiceHelper.eqExceptId(intent));
-            expectLastCall().andAnswer(new IAnswer<Object>() {
-                @Override
-                public Object answer() throws Throwable {
-                    installCount.countDown();
-                    return null;
-                }
-            }).once();
-            intentService.withdraw(TestIntentServiceHelper.eqExceptId(intent));
-            expectLastCall().andAnswer(new IAnswer<Object>() {
-                @Override
-                public Object answer() throws Throwable {
-                    deleteCount.countDown();
-                    return null;
-                }
-            }).once();
-        }
-
-        replay(intentService);
-
-        intentSynchronizer.leaderChanged(true);
-        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
-
-        // Send the add updates first
-        router.processRouteUpdates(routeUpdates);
-
-        // Give some time to let the intents be submitted
-        installCount.await(5000, TimeUnit.MILLISECONDS);
-
-        // Send the DELETE updates
-        List<RouteUpdate> deleteRouteUpdates = new ArrayList<>();
-        for (RouteUpdate update : routeUpdates) {
-            RouteUpdate deleteUpdate = new RouteUpdate(RouteUpdate.Type.DELETE,
-                                                       update.routeEntry());
-            deleteRouteUpdates.add(deleteUpdate);
-        }
-        router.processRouteUpdates(deleteRouteUpdates);
-
-        deleteCount.await(5000, TimeUnit.MILLISECONDS);
-
-        assertEquals(0, router.getRoutes4().size());
-        assertEquals(0, intentSynchronizer.getRouteIntents().size());
-        verify(intentService);
-    }
-
-    /**
-     * This methods generates random route updates.
-     *
-     * @param numRoutes the number of route updates to generate
-     * @return a list of route update
-     */
-    private List<RouteUpdate> generateRouteUpdates(int numRoutes) {
-        List<RouteUpdate> routeUpdates = new ArrayList<>(numRoutes);
-
-        Set<Ip4Prefix> prefixes = new HashSet<>();
-
-        for (int i = 0; i < numRoutes; i++) {
-            Ip4Prefix prefix;
-            do {
-                // Generate a random prefix length between MIN_PREFIX_LENGTH
-                // and MAX_PREFIX_LENGTH
-                int prefixLength = random.nextInt(
-                        (MAX_PREFIX_LENGTH - MIN_PREFIX_LENGTH) + 1)
-                        + MIN_PREFIX_LENGTH;
-                prefix =
-                    Ip4Prefix.valueOf(Ip4Address.valueOf(random.nextInt()),
-                                      prefixLength);
-                // We have to ensure we don't generate the same prefix twice
-                // (this is quite easy to happen with small prefix lengths).
-            } while (prefixes.contains(prefix));
-
-            prefixes.add(prefix);
-
-            // Randomly select a peer to use as the next hop
-            BgpPeer nextHop = null;
-            int peerNumber = random.nextInt(sdnIpConfigService.getBgpPeers()
-                    .size());
-            int j = 0;
-            for (BgpPeer peer : sdnIpConfigService.getBgpPeers().values()) {
-                if (j++ == peerNumber) {
-                    nextHop = peer;
-                    break;
-                }
-            }
-
-            assertNotNull(nextHop);
-
-            RouteUpdate update =
-                new RouteUpdate(RouteUpdate.Type.UPDATE,
-                        new RouteEntry(prefix,
-                                       nextHop.ipAddress().getIp4Address()));
-
-            routeUpdates.add(update);
-        }
-
-        return routeUpdates;
-    }
-
-    /**
-     * Generates the MultiPointToSinglePointIntent that should be
-     * submitted/withdrawn for a particular RouteUpdate.
-     *
-     * @param update the RouteUpdate to generate an intent for
-     * @param nextHopMac a MAC address to use as the dst-mac for the intent
-     * @param egressConnectPoint the outgoing ConnectPoint for the intent
-     * @return the generated intent
-     */
-    private MultiPointToSinglePointIntent getIntentForUpdate(RouteUpdate update,
-            MacAddress nextHopMac, ConnectPoint egressConnectPoint) {
-        IpPrefix ip4Prefix = update.routeEntry().prefix();
-
-        TrafficSelector.Builder selectorBuilder =
-                DefaultTrafficSelector.builder();
-
-        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ip4Prefix);
-
-        TrafficTreatment.Builder treatmentBuilder =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilder.setEthDst(nextHopMac);
-
-        Set<ConnectPoint> ingressPoints = new HashSet<ConnectPoint>();
-        for (Interface intf : interfaceService.getInterfaces()) {
-            if (!intf.connectPoint().equals(egressConnectPoint)) {
-                ConnectPoint srcPort = intf.connectPoint();
-                ingressPoints.add(srcPort);
-            }
-        }
-
-        MultiPointToSinglePointIntent intent =
-                new MultiPointToSinglePointIntent(APPID,
-                selectorBuilder.build(), treatmentBuilder.build(),
-                ingressPoints, egressConnectPoint);
-
-        return intent;
-    }
-
-    /**
-     * Generates a MAC address based on an IP address.
-     * For the test we need MAC addresses but the actual values don't have any
-     * meaning, so we'll just generate them based on the IP address. This means
-     * we have a deterministic mapping from IP address to MAC address.
-     *
-     * @param ipAddress IP address used to generate a MAC address
-     * @return generated MAC address
-     */
-    static MacAddress generateMacAddress(IpAddress ipAddress) {
-        byte[] macAddress = new byte[MAC_ADDRESS_LENGTH];
-        ByteBuffer bb = ByteBuffer.wrap(macAddress);
-
-        // Put the IP address bytes into the lower four bytes of the MAC
-        // address. Leave the first two bytes set to 0.
-        bb.position(2);
-        bb.put(ipAddress.toOctets());
-
-        return MacAddress.valueOf(bb.array());
-    }
-
-    /**
-     * Finds out the ConnectPoint for a BGP peer address.
-     *
-     * @param bgpPeerAddress the BGP peer address.
-     */
-    private ConnectPoint getConnectPoint(IpAddress bgpPeerAddress) {
-        ConnectPoint connectPoint = null;
-
-        for (BgpPeer bgpPeer: bgpPeers.values()) {
-            if (bgpPeer.ipAddress().equals(bgpPeerAddress)) {
-                connectPoint = bgpPeer.connectPoint();
-                break;
-            }
-        }
-        return connectPoint;
-    }
-}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/TestHostService.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/TestHostService.java
deleted file mode 100644
index 7e84f8e..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/TestHostService.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * 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;
-
-import java.util.HashSet;
-import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultHost;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.HostLocation;
-import org.onosproject.net.host.HostEvent;
-import org.onosproject.net.host.HostListener;
-import org.onosproject.net.host.HostService;
-import org.onosproject.net.host.PortAddresses;
-import org.onosproject.net.provider.ProviderId;
-import org.onosproject.sdnip.Router.InternalHostListener;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-
-import com.google.common.collect.Sets;
-
-/**
- * Test version of the HostService which is used to simulate delays in
- * receiving ARP replies, as you would see in a real system due to the time
- * it takes to proxy ARP packets to/from the host. Requests are asynchronous,
- * and replies may come back to the requestor in a different order than the
- * requests were sent, which again you would expect to see in a real system.
- */
-public class TestHostService implements HostService {
-
-    /**
-     * The maximum possible delay before an ARP reply is received.
-     */
-    private static final int MAX_ARP_REPLY_DELAY = 30; // milliseconds
-
-    /**
-     * The probability that we already have the MAC address cached when the
-     * caller calls {@link #getHostsByIp(IpAddress ipAddress)}.
-     */
-    private static final float MAC_ALREADY_KNOWN_PROBABILITY = 0.3f;
-
-    private final ScheduledExecutorService replyTaskExecutor;
-    private final Random random;
-
-    /**
-     * Class constructor.
-     */
-    public TestHostService() {
-        replyTaskExecutor = Executors.newSingleThreadScheduledExecutor();
-        random = new Random();
-    }
-
-    /**
-     * Task used to reply to ARP requests from a different thread. Replies
-     * usually come on a different thread in the real system, so we need to
-     * ensure we test this behavior.
-     */
-    private class ReplyTask implements Runnable {
-        private HostListener listener;
-        private IpAddress ipAddress;
-
-        /**
-         * Class constructor.
-         *
-         * @param listener the client who requests and waits the MAC address
-         * @param ipAddress the target IP address of the request
-         */
-        public ReplyTask(InternalHostListener listener,
-                IpAddress ipAddress) {
-            this.listener = listener;
-            this.ipAddress = ipAddress;
-        }
-
-        @Override
-        public void run() {
-            Host host = getHostsByIp(ipAddress).iterator().next();
-            HostEvent hostevent =
-                    new HostEvent(HostEvent.Type.HOST_ADDED, host);
-            listener.event(hostevent);
-        }
-    }
-
-    @Override
-    public Set<Host> getHostsByIp(IpAddress ipAddress) {
-        float replyChance = random.nextFloat();
-
-        // We don't care what the attachment point is in the test,
-        // so for all the hosts, we use a same ConnectPoint.
-        Host host = new DefaultHost(ProviderId.NONE, HostId.NONE,
-                SdnIpTest.generateMacAddress(ipAddress), VlanId.NONE,
-                new HostLocation(SdnIpTest.SW1_ETH1, 1),
-                Sets.newHashSet(ipAddress));
-
-        if (replyChance < MAC_ALREADY_KNOWN_PROBABILITY) {
-            // Some percentage of the time we already know the MAC address, so
-            // we reply directly when the requestor asks for the MAC address
-            return Sets.newHashSet(host);
-        }
-        return new HashSet<Host>();
-    }
-
-    @Override
-    public void startMonitoringIp(IpAddress ipAddress) {
-
-        // Randomly select an amount of time to delay the reply coming back to
-        int delay = random.nextInt(MAX_ARP_REPLY_DELAY);
-        ReplyTask replyTask = new ReplyTask(
-                (SdnIpTest.router.new InternalHostListener()), ipAddress);
-        replyTaskExecutor.schedule(replyTask, delay, TimeUnit.MILLISECONDS);
-    }
-
-    @Override
-    public int getHostCount() {
-        return 0;
-    }
-
-    @Override
-    public Iterable<Host> getHosts() {
-        return null;
-    }
-
-    @Override
-    public Host getHost(HostId hostId) {
-        return null;
-    }
-
-    @Override
-    public Set<Host> getHostsByVlan(VlanId vlanId) {
-        return null;
-    }
-
-    @Override
-    public Set<Host> getHostsByMac(MacAddress mac) {
-        return null;
-    }
-
-    @Override
-    public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
-        return null;
-    }
-
-    @Override
-    public Set<Host> getConnectedHosts(DeviceId deviceId) {
-        return null;
-    }
-
-    @Override
-    public void stopMonitoringIp(IpAddress ip) {
-
-    }
-
-    @Override
-    public void requestMac(IpAddress ip) {
-
-    }
-
-    @Override
-    public Set<PortAddresses> getAddressBindings() {
-        return null;
-    }
-
-    @Override
-    public Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint) {
-        return null;
-    }
-
-    @Override
-    public void addListener(HostListener listener) {
-
-    }
-
-    @Override
-    public void removeListener(HostListener listener) {
-
-    }
-
-}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/AsPathTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/AsPathTest.java
deleted file mode 100644
index 481ca43..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/AsPathTest.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * 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 static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertThat;
-
-import java.util.ArrayList;
-
-import org.junit.Test;
-
-/**
- * Unit tests for the BgpRouteEntry.AsPath class.
- */
-public class AsPathTest {
-    /**
-     * Generates Path Segments.
-     *
-     * @return the generated Path Segments
-     */
-    private ArrayList<BgpRouteEntry.PathSegment> generatePathSegments() {
-        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
-        byte pathSegmentType;
-        ArrayList<Long> segmentAsNumbers;
-        BgpRouteEntry.PathSegment pathSegment;
-
-        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE;
-        segmentAsNumbers = new ArrayList<>();
-        segmentAsNumbers.add((long) 1);
-        segmentAsNumbers.add((long) 2);
-        segmentAsNumbers.add((long) 3);
-        pathSegment =
-            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
-        pathSegments.add(pathSegment);
-        //
-        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SET;
-        segmentAsNumbers = new ArrayList<>();
-        segmentAsNumbers.add((long) 4);
-        segmentAsNumbers.add((long) 5);
-        segmentAsNumbers.add((long) 6);
-        pathSegment =
-            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
-        pathSegments.add(pathSegment);
-        //
-        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
-        segmentAsNumbers = new ArrayList<>();
-        segmentAsNumbers.add((long) 7);
-        segmentAsNumbers.add((long) 8);
-        segmentAsNumbers.add((long) 9);
-        pathSegment =
-            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
-        pathSegments.add(pathSegment);
-        //
-        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SET;
-        segmentAsNumbers = new ArrayList<>();
-        segmentAsNumbers.add((long) 10);
-        segmentAsNumbers.add((long) 11);
-        segmentAsNumbers.add((long) 12);
-        pathSegment =
-            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
-        pathSegments.add(pathSegment);
-
-        return pathSegments;
-    }
-
-    /**
-     * Generates an AS Path.
-     *
-     * @return a generated AS Path
-     */
-    private BgpRouteEntry.AsPath generateAsPath() {
-        ArrayList<BgpRouteEntry.PathSegment> pathSegments =
-            generatePathSegments();
-        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
-
-        return asPath;
-    }
-
-    /**
-     * Tests valid class constructor.
-     */
-    @Test
-    public void testConstructor() {
-        BgpRouteEntry.AsPath asPath = generateAsPath();
-
-        String expectedString =
-            "AsPath{pathSegments=[" +
-            "PathSegment{type=AS_CONFED_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " +
-            "PathSegment{type=AS_CONFED_SET, segmentAsNumbers=[4, 5, 6]}, " +
-            "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[7, 8, 9]}, " +
-            "PathSegment{type=AS_SET, segmentAsNumbers=[10, 11, 12]}]}";
-        assertThat(asPath.toString(), is(expectedString));
-    }
-
-    /**
-     * Tests invalid class constructor for null Path Segments.
-     */
-    @Test(expected = NullPointerException.class)
-    public void testInvalidConstructorNullPathSegments() {
-        ArrayList<BgpRouteEntry.PathSegment> pathSegments = null;
-        new BgpRouteEntry.AsPath(pathSegments);
-    }
-
-    /**
-     * Tests getting the fields of an AS Path.
-     */
-    @Test
-    public void testGetFields() {
-        // Create the fields to compare against
-        ArrayList<BgpRouteEntry.PathSegment> pathSegments =
-            generatePathSegments();
-
-        // Generate the entry to test
-        BgpRouteEntry.AsPath asPath = generateAsPath();
-
-        assertThat(asPath.getPathSegments(), is(pathSegments));
-    }
-
-    /**
-     * Tests getting the AS Path Length.
-     */
-    @Test
-    public void testGetAsPathLength() {
-        //
-        // NOTE:
-        //  - AS_CONFED_SEQUENCE and AS_CONFED_SET are excluded
-        //  - AS_SET counts as a single hop
-        //
-        BgpRouteEntry.AsPath asPath = generateAsPath();
-        assertThat(asPath.getAsPathLength(), is(4));
-
-        // Create an empty AS Path
-        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
-        asPath = new BgpRouteEntry.AsPath(pathSegments);
-        assertThat(asPath.getAsPathLength(), is(0));
-    }
-
-    /**
-     * Tests equality of {@link BgpRouteEntry.AsPath}.
-     */
-    @Test
-    public void testEquality() {
-        BgpRouteEntry.AsPath asPath1 = generateAsPath();
-        BgpRouteEntry.AsPath asPath2 = generateAsPath();
-
-        assertThat(asPath1, is(asPath2));
-    }
-
-    /**
-     * Tests non-equality of {@link BgpRouteEntry.AsPath}.
-     */
-    @Test
-    public void testNonEquality() {
-        BgpRouteEntry.AsPath asPath1 = generateAsPath();
-
-        // Setup AS Path 2
-        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
-        byte pathSegmentType;
-        ArrayList<Long> segmentAsNumbers;
-        BgpRouteEntry.PathSegment pathSegment;
-
-        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SEQUENCE;
-        segmentAsNumbers = new ArrayList<>();
-        segmentAsNumbers.add((long) 1);
-        segmentAsNumbers.add((long) 2);
-        segmentAsNumbers.add((long) 3);
-        pathSegment =
-            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
-        pathSegments.add(pathSegment);
-        //
-        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_CONFED_SET;
-        segmentAsNumbers = new ArrayList<>();
-        segmentAsNumbers.add((long) 4);
-        segmentAsNumbers.add((long) 5);
-        segmentAsNumbers.add((long) 6);
-        pathSegment =
-            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
-        pathSegments.add(pathSegment);
-        //
-        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
-        segmentAsNumbers = new ArrayList<>();
-        segmentAsNumbers.add((long) 7);
-        segmentAsNumbers.add((long) 8);
-        segmentAsNumbers.add((long) 9);
-        pathSegment =
-            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
-        pathSegments.add(pathSegment);
-        //
-        pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SET;
-        segmentAsNumbers = new ArrayList<>();
-        segmentAsNumbers.add((long) 10);
-        segmentAsNumbers.add((long) 111);                       // Different
-        segmentAsNumbers.add((long) 12);
-        pathSegment =
-            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
-        pathSegments.add(pathSegment);
-        //
-        BgpRouteEntry.AsPath asPath2 = new BgpRouteEntry.AsPath(pathSegments);
-
-        assertThat(asPath1, is(not(asPath2)));
-    }
-
-    /**
-     * Tests object string representation.
-     */
-    @Test
-    public void testToString() {
-        BgpRouteEntry.AsPath asPath = generateAsPath();
-
-        String expectedString =
-            "AsPath{pathSegments=[" +
-            "PathSegment{type=AS_CONFED_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " +
-            "PathSegment{type=AS_CONFED_SET, segmentAsNumbers=[4, 5, 6]}, " +
-            "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[7, 8, 9]}, " +
-            "PathSegment{type=AS_SET, segmentAsNumbers=[10, 11, 12]}]}";
-        assertThat(asPath.toString(), is(expectedString));
-    }
-}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpRouteEntryTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpRouteEntryTest.java
deleted file mode 100644
index d53eb59..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpRouteEntryTest.java
+++ /dev/null
@@ -1,521 +0,0 @@
-/*
- * 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 static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertThat;
-
-import java.util.ArrayList;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-
-/**
- * Unit tests for the BgpRouteEntry class.
- */
-public class BgpRouteEntryTest {
-    private BgpSession bgpSession;
-    private static final Ip4Address BGP_SESSION_BGP_ID =
-        Ip4Address.valueOf("10.0.0.1");
-    private static final Ip4Address BGP_SESSION_IP_ADDRESS =
-        Ip4Address.valueOf("20.0.0.1");
-
-    private BgpSession bgpSession2;
-    private static final Ip4Address BGP_SESSION_BGP_ID2 =
-        Ip4Address.valueOf("10.0.0.2");
-    private static final Ip4Address BGP_SESSION_IP_ADDRESS2 =
-        Ip4Address.valueOf("20.0.0.1");
-
-    private BgpSession bgpSession3;
-    private static final Ip4Address BGP_SESSION_BGP_ID3 =
-        Ip4Address.valueOf("10.0.0.1");
-    private static final Ip4Address BGP_SESSION_IP_ADDRESS3 =
-        Ip4Address.valueOf("20.0.0.2");
-
-    private final BgpSessionInfo localInfo = new BgpSessionInfo();
-    private final BgpSessionInfo remoteInfo = new BgpSessionInfo();
-
-    private final BgpSessionInfo localInfo2 = new BgpSessionInfo();
-    private final BgpSessionInfo remoteInfo2 = new BgpSessionInfo();
-
-    private final BgpSessionInfo localInfo3 = new BgpSessionInfo();
-    private final BgpSessionInfo remoteInfo3 = new BgpSessionInfo();
-
-    @Before
-    public void setUp() throws Exception {
-        // Mock objects for testing
-        bgpSession = createMock(BgpSession.class);
-        bgpSession2 = createMock(BgpSession.class);
-        bgpSession3 = createMock(BgpSession.class);
-
-        // Setup the BGP Sessions
-        remoteInfo.setIp4Address(BGP_SESSION_IP_ADDRESS);
-        remoteInfo2.setIp4Address(BGP_SESSION_IP_ADDRESS2);
-        remoteInfo3.setIp4Address(BGP_SESSION_IP_ADDRESS3);
-        remoteInfo.setBgpId(BGP_SESSION_BGP_ID);
-        remoteInfo2.setBgpId(BGP_SESSION_BGP_ID2);
-        remoteInfo3.setBgpId(BGP_SESSION_BGP_ID3);
-
-        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);
-        replay(bgpSession3);
-    }
-
-    /**
-     * Generates a BGP Route Entry.
-     *
-     * @return a generated BGP Route Entry
-     */
-    private BgpRouteEntry generateBgpRouteEntry() {
-        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
-        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
-        byte origin = BgpConstants.Update.Origin.IGP;
-        // Setup the AS Path
-        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
-        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
-        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
-        segmentAsNumbers1.add((long) 1);
-        segmentAsNumbers1.add((long) 2);
-        segmentAsNumbers1.add((long) 3);
-        BgpRouteEntry.PathSegment pathSegment1 =
-            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
-        pathSegments.add(pathSegment1);
-        //
-        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
-        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
-        segmentAsNumbers2.add((long) 4);
-        segmentAsNumbers2.add((long) 5);
-        segmentAsNumbers2.add((long) 6);
-        BgpRouteEntry.PathSegment pathSegment2 =
-            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
-        pathSegments.add(pathSegment2);
-        //
-        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
-        //
-        long localPref = 100;
-        long multiExitDisc = 20;
-
-        BgpRouteEntry bgpRouteEntry =
-            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
-                              localPref);
-        bgpRouteEntry.setMultiExitDisc(multiExitDisc);
-
-        return bgpRouteEntry;
-    }
-
-    /**
-     * Tests valid class constructor.
-     */
-    @Test
-    public void testConstructor() {
-        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
-
-        String expectedString =
-            "BgpRouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8, " +
-            "bgpId=10.0.0.1, origin=IGP, asPath=AsPath{pathSegments=" +
-            "[PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " +
-            "PathSegment{type=AS_SET, segmentAsNumbers=[4, 5, 6]}]}, " +
-            "localPref=100, multiExitDisc=20}";
-        assertThat(bgpRouteEntry.toString(), is(expectedString));
-    }
-
-    /**
-     * Tests invalid class constructor for null BGP Session.
-     */
-    @Test(expected = NullPointerException.class)
-    public void testInvalidConstructorNullBgpSession() {
-        BgpSession bgpSessionNull = null;
-        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
-        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
-        byte origin = BgpConstants.Update.Origin.IGP;
-        // Setup the AS Path
-        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
-        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
-        //
-        long localPref = 100;
-
-        new BgpRouteEntry(bgpSessionNull, prefix, nextHop, origin, asPath,
-                    localPref);
-    }
-
-    /**
-     * Tests invalid class constructor for null AS Path.
-     */
-    @Test(expected = NullPointerException.class)
-    public void testInvalidConstructorNullAsPath() {
-        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
-        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
-        byte origin = BgpConstants.Update.Origin.IGP;
-        BgpRouteEntry.AsPath asPath = null;
-        long localPref = 100;
-
-        new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
-                    localPref);
-    }
-
-    /**
-     * Tests getting the fields of a BGP route entry.
-     */
-    @Test
-    public void testGetFields() {
-        // Create the fields to compare against
-        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
-        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
-        byte origin = BgpConstants.Update.Origin.IGP;
-        // Setup the AS Path
-        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
-        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
-        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
-        segmentAsNumbers1.add((long) 1);
-        segmentAsNumbers1.add((long) 2);
-        segmentAsNumbers1.add((long) 3);
-        BgpRouteEntry.PathSegment pathSegment1 =
-            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
-        pathSegments.add(pathSegment1);
-        //
-        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
-        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
-        segmentAsNumbers2.add((long) 4);
-        segmentAsNumbers2.add((long) 5);
-        segmentAsNumbers2.add((long) 6);
-        BgpRouteEntry.PathSegment pathSegment2 =
-            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
-        pathSegments.add(pathSegment2);
-        //
-        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
-        //
-        long localPref = 100;
-        long multiExitDisc = 20;
-
-        // Generate the entry to test
-        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
-
-        assertThat(bgpRouteEntry.prefix(), is(prefix));
-        assertThat(bgpRouteEntry.nextHop(), is(nextHop));
-        assertThat(bgpRouteEntry.getBgpSession(), is(bgpSession));
-        assertThat(bgpRouteEntry.getOrigin(), is(origin));
-        assertThat(bgpRouteEntry.getAsPath(), is(asPath));
-        assertThat(bgpRouteEntry.getLocalPref(), is(localPref));
-        assertThat(bgpRouteEntry.getMultiExitDisc(), is(multiExitDisc));
-    }
-
-    /**
-     * Tests whether a BGP route entry is a local route.
-     */
-    @Test
-    public void testIsLocalRoute() {
-        //
-        // Test non-local route
-        //
-        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
-        assertThat(bgpRouteEntry.isLocalRoute(), is(false));
-
-        //
-        // Test local route with AS Path that begins with AS_SET
-        //
-        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
-        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
-        byte origin = BgpConstants.Update.Origin.IGP;
-        // Setup the AS Path
-        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
-        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SET;
-        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
-        segmentAsNumbers1.add((long) 1);
-        segmentAsNumbers1.add((long) 2);
-        segmentAsNumbers1.add((long) 3);
-        BgpRouteEntry.PathSegment pathSegment1 =
-            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
-        pathSegments.add(pathSegment1);
-        //
-        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
-        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
-        segmentAsNumbers2.add((long) 4);
-        segmentAsNumbers2.add((long) 5);
-        segmentAsNumbers2.add((long) 6);
-        BgpRouteEntry.PathSegment pathSegment2 =
-            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
-        pathSegments.add(pathSegment2);
-        //
-        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
-        //
-        long localPref = 100;
-        long multiExitDisc = 20;
-        //
-        bgpRouteEntry =
-            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
-                              localPref);
-        bgpRouteEntry.setMultiExitDisc(multiExitDisc);
-        assertThat(bgpRouteEntry.isLocalRoute(), is(true));
-
-        //
-        // Test local route with empty AS Path
-        //
-        pathSegments = new ArrayList<>();
-        asPath = new BgpRouteEntry.AsPath(pathSegments);
-        bgpRouteEntry =
-            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
-                              localPref);
-        bgpRouteEntry.setMultiExitDisc(multiExitDisc);
-        assertThat(bgpRouteEntry.isLocalRoute(), is(true));
-    }
-
-    /**
-     * Tests getting the BGP Neighbor AS number for a route.
-     */
-    @Test
-    public void testGetNeighborAs() {
-        //
-        // Get neighbor AS for non-local route
-        //
-        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
-        assertThat(bgpRouteEntry.getNeighborAs(), is((long) 1));
-
-        //
-        // Get neighbor AS for a local route
-        //
-        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
-        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
-        byte origin = BgpConstants.Update.Origin.IGP;
-        // Setup the AS Path
-        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
-        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
-        //
-        long localPref = 100;
-        long multiExitDisc = 20;
-        //
-        bgpRouteEntry =
-            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
-                              localPref);
-        bgpRouteEntry.setMultiExitDisc(multiExitDisc);
-        assertThat(bgpRouteEntry.getNeighborAs(), is(BgpConstants.BGP_AS_0));
-    }
-
-    /**
-     * Tests whether a BGP route entry has AS Path loop.
-     */
-    @Test
-    public void testHasAsPathLoop() {
-        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
-
-        // Test for loops: test each AS number in the interval [1, 6]
-        for (int i = 1; i <= 6; i++) {
-            assertThat(bgpRouteEntry.hasAsPathLoop(i), is(true));
-        }
-
-        // Test for non-loops
-        assertThat(bgpRouteEntry.hasAsPathLoop(500), is(false));
-    }
-
-    /**
-     * Tests the BGP Decision Process comparison of BGP routes.
-     */
-    @Test
-    public void testBgpDecisionProcessComparison() {
-        BgpRouteEntry bgpRouteEntry1 = generateBgpRouteEntry();
-        BgpRouteEntry bgpRouteEntry2 = generateBgpRouteEntry();
-
-        //
-        // Compare two routes that are same
-        //
-        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
-        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(true));
-
-        //
-        // Compare two routes with different LOCAL_PREF
-        //
-        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
-        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
-        byte origin = BgpConstants.Update.Origin.IGP;
-        // Setup the AS Path
-        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
-        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
-        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
-        segmentAsNumbers1.add((long) 1);
-        segmentAsNumbers1.add((long) 2);
-        segmentAsNumbers1.add((long) 3);
-        BgpRouteEntry.PathSegment pathSegment1 =
-            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
-        pathSegments.add(pathSegment1);
-        //
-        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
-        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
-        segmentAsNumbers2.add((long) 4);
-        segmentAsNumbers2.add((long) 5);
-        segmentAsNumbers2.add((long) 6);
-        BgpRouteEntry.PathSegment pathSegment2 =
-            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
-        pathSegments.add(pathSegment2);
-        //
-        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
-        //
-        long localPref = 50;                                    // Different
-        long multiExitDisc = 20;
-        bgpRouteEntry2 =
-            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
-                              localPref);
-        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
-        //
-        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
-        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
-        localPref = bgpRouteEntry1.getLocalPref();              // Restore
-
-        //
-        // Compare two routes with different AS_PATH length
-        //
-        ArrayList<BgpRouteEntry.PathSegment> pathSegments2 = new ArrayList<>();
-        pathSegments2.add(pathSegment1);
-        // Different AS Path
-        BgpRouteEntry.AsPath asPath2 = new BgpRouteEntry.AsPath(pathSegments2);
-        bgpRouteEntry2 =
-            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath2,
-                              localPref);
-        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
-        //
-        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(false));
-        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(true));
-
-        //
-        // Compare two routes with different ORIGIN
-        //
-        origin = BgpConstants.Update.Origin.EGP;                // Different
-        bgpRouteEntry2 =
-            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
-                              localPref);
-        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
-        //
-        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
-        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
-        origin = bgpRouteEntry1.getOrigin();                    // Restore
-
-        //
-        // Compare two routes with different MULTI_EXIT_DISC
-        //
-        multiExitDisc = 10;                                     // Different
-        bgpRouteEntry2 =
-            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
-                              localPref);
-        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
-        //
-        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
-        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
-        multiExitDisc = bgpRouteEntry1.getMultiExitDisc();      // Restore
-
-        //
-        // Compare two routes with different BGP ID
-        //
-        bgpRouteEntry2 =
-            new BgpRouteEntry(bgpSession2, prefix, nextHop, origin, asPath,
-                              localPref);
-        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
-        //
-        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
-        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
-
-        //
-        // Compare two routes with different BGP address
-        //
-        bgpRouteEntry2 =
-            new BgpRouteEntry(bgpSession3, prefix, nextHop, origin, asPath,
-                              localPref);
-        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
-        //
-        assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
-        assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
-    }
-
-    /**
-     * Tests equality of {@link BgpRouteEntry}.
-     */
-    @Test
-    public void testEquality() {
-        BgpRouteEntry bgpRouteEntry1 = generateBgpRouteEntry();
-        BgpRouteEntry bgpRouteEntry2 = generateBgpRouteEntry();
-
-        assertThat(bgpRouteEntry1, is(bgpRouteEntry2));
-    }
-
-    /**
-     * Tests non-equality of {@link BgpRouteEntry}.
-     */
-    @Test
-    public void testNonEquality() {
-        BgpRouteEntry bgpRouteEntry1 = generateBgpRouteEntry();
-
-        // Setup BGP Route 2
-        Ip4Prefix prefix = Ip4Prefix.valueOf("1.2.3.0/24");
-        Ip4Address nextHop = Ip4Address.valueOf("5.6.7.8");
-        byte origin = BgpConstants.Update.Origin.IGP;
-        // Setup the AS Path
-        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
-        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
-        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
-        segmentAsNumbers1.add((long) 1);
-        segmentAsNumbers1.add((long) 2);
-        segmentAsNumbers1.add((long) 3);
-        BgpRouteEntry.PathSegment pathSegment1 =
-            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
-        pathSegments.add(pathSegment1);
-        //
-        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
-        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
-        segmentAsNumbers2.add((long) 4);
-        segmentAsNumbers2.add((long) 5);
-        segmentAsNumbers2.add((long) 6);
-        BgpRouteEntry.PathSegment pathSegment2 =
-            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
-        pathSegments.add(pathSegment2);
-        //
-        BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
-        //
-        long localPref = 500;                                   // Different
-        long multiExitDisc = 20;
-        BgpRouteEntry bgpRouteEntry2 =
-            new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
-                              localPref);
-        bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
-
-        assertThat(bgpRouteEntry1, is(not(bgpRouteEntry2)));
-    }
-
-    /**
-     * Tests object string representation.
-     */
-    @Test
-    public void testToString() {
-        BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
-
-        String expectedString =
-            "BgpRouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8, " +
-            "bgpId=10.0.0.1, origin=IGP, asPath=AsPath{pathSegments=" +
-            "[PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}, " +
-            "PathSegment{type=AS_SET, segmentAsNumbers=[4, 5, 6]}]}, " +
-            "localPref=100, multiExitDisc=20}";
-        assertThat(bgpRouteEntry.toString(), is(expectedString));
-    }
-}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpSessionManagerTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpSessionManagerTest.java
deleted file mode 100644
index 7ae8658..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpSessionManagerTest.java
+++ /dev/null
@@ -1,877 +0,0 @@
-/*
- * 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 static org.hamcrest.Matchers.hasSize;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.junit.Assert.assertThat;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import org.hamcrest.Description;
-import org.hamcrest.TypeSafeMatcher;
-import org.jboss.netty.bootstrap.ClientBootstrap;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelFactory;
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.channel.ChannelPipelineFactory;
-import org.jboss.netty.channel.Channels;
-import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.junit.TestUtils;
-import org.onlab.junit.TestUtils.TestUtilsException;
-import org.onosproject.sdnip.RouteListener;
-import org.onosproject.sdnip.RouteUpdate;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-
-import com.google.common.net.InetAddresses;
-
-/**
- * Unit tests for the BgpSessionManager class.
- */
-public class BgpSessionManagerTest {
-    private static final Ip4Address IP_LOOPBACK_ID =
-        Ip4Address.valueOf("127.0.0.1");
-    private static final Ip4Address BGP_PEER1_ID =
-        Ip4Address.valueOf("10.0.0.1");
-    private static final Ip4Address BGP_PEER2_ID =
-        Ip4Address.valueOf("10.0.0.2");
-    private static final Ip4Address BGP_PEER3_ID =
-        Ip4Address.valueOf("10.0.0.3");
-    private static final Ip4Address NEXT_HOP1_ROUTER =
-        Ip4Address.valueOf("10.20.30.41");
-    private static final Ip4Address NEXT_HOP2_ROUTER =
-        Ip4Address.valueOf("10.20.30.42");
-    private static final Ip4Address NEXT_HOP3_ROUTER =
-        Ip4Address.valueOf("10.20.30.43");
-
-    private static final long DEFAULT_LOCAL_PREF = 10;
-    private static final long BETTER_LOCAL_PREF = 20;
-    private static final long DEFAULT_MULTI_EXIT_DISC = 20;
-    private static final long BETTER_MULTI_EXIT_DISC = 30;
-
-    BgpRouteEntry.AsPath asPathShort;
-    BgpRouteEntry.AsPath asPathLong;
-
-    // Timeout waiting for a message to be received
-    private static final int MESSAGE_TIMEOUT_MS = 5000; // 5s
-
-    // The BGP Session Manager to test
-    private BgpSessionManager bgpSessionManager;
-
-    // Remote Peer state
-    private final Collection<TestBgpPeer> peers = new LinkedList<>();
-    TestBgpPeer peer1;
-    TestBgpPeer peer2;
-    TestBgpPeer peer3;
-
-    // Local BGP per-peer session state
-    BgpSession bgpSession1;
-    BgpSession bgpSession2;
-    BgpSession bgpSession3;
-
-    // The socket that the remote peers should connect to
-    private InetSocketAddress connectToSocket;
-
-    private final DummyRouteListener dummyRouteListener =
-        new DummyRouteListener();
-
-    /**
-     * Dummy implementation for the RouteListener interface.
-     */
-    private class DummyRouteListener implements RouteListener {
-        @Override
-        public void update(Collection<RouteUpdate> routeUpdate) {
-            // Nothing to do
-        }
-    }
-
-    /**
-     * A class to capture the state for a BGP peer.
-     */
-    private final class TestBgpPeer {
-        private final Ip4Address peerId;
-        private ClientBootstrap peerBootstrap;
-        private TestBgpPeerChannelHandler peerChannelHandler;
-        private TestBgpPeerFrameDecoder peerFrameDecoder =
-            new TestBgpPeerFrameDecoder();
-
-        /**
-         * Constructor.
-         *
-         * @param peerId the peer ID
-         */
-        private TestBgpPeer(Ip4Address peerId) {
-            this.peerId = peerId;
-            peerChannelHandler = new TestBgpPeerChannelHandler(peerId);
-        }
-
-        /**
-         * Starts up the BGP peer and connects it to the tested SDN-IP
-         * instance.
-         *
-         * @param connectToSocket the socket to connect to
-         */
-        private void connect(InetSocketAddress connectToSocket)
-            throws InterruptedException {
-            //
-            // Setup the BGP Peer, i.e., the "remote" BGP router that will
-            // initiate the BGP connection, send BGP UPDATE messages, etc.
-            //
-            ChannelFactory channelFactory =
-                new NioClientSocketChannelFactory(
-                        Executors.newCachedThreadPool(),
-                        Executors.newCachedThreadPool());
-            ChannelPipelineFactory pipelineFactory =
-                new ChannelPipelineFactory() {
-                    @Override
-                    public ChannelPipeline getPipeline() throws Exception {
-                        // Setup the transmitting pipeline
-                        ChannelPipeline pipeline = Channels.pipeline();
-                        pipeline.addLast("TestBgpPeerFrameDecoder",
-                                         peerFrameDecoder);
-                        pipeline.addLast("TestBgpPeerChannelHandler",
-                                         peerChannelHandler);
-                        return pipeline;
-                    }
-                };
-
-            peerBootstrap = new ClientBootstrap(channelFactory);
-            peerBootstrap.setOption("child.keepAlive", true);
-            peerBootstrap.setOption("child.tcpNoDelay", true);
-            peerBootstrap.setPipelineFactory(pipelineFactory);
-            peerBootstrap.connect(connectToSocket);
-
-            boolean result;
-            // Wait until the OPEN message is received
-            result = peerFrameDecoder.receivedOpenMessageLatch.await(
-                MESSAGE_TIMEOUT_MS,
-                TimeUnit.MILLISECONDS);
-            assertThat(result, is(true));
-            // Wait until the KEEPALIVE message is received
-            result = peerFrameDecoder.receivedKeepaliveMessageLatch.await(
-                MESSAGE_TIMEOUT_MS,
-                TimeUnit.MILLISECONDS);
-            assertThat(result, is(true));
-
-            for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
-                if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER1_ID)) {
-                    bgpSession1 = bgpSession;
-                }
-                if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER2_ID)) {
-                    bgpSession2 = bgpSession;
-                }
-                if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER3_ID)) {
-                    bgpSession3 = bgpSession;
-                }
-            }
-        }
-    }
-
-    /**
-     * Class that implements a matcher for BgpRouteEntry by considering
-     * the BGP peer the entry was received from.
-     */
-    private static final class BgpRouteEntryAndPeerMatcher
-        extends TypeSafeMatcher<Collection<BgpRouteEntry>> {
-        private final BgpRouteEntry bgpRouteEntry;
-
-        private BgpRouteEntryAndPeerMatcher(BgpRouteEntry bgpRouteEntry) {
-            this.bgpRouteEntry = bgpRouteEntry;
-        }
-
-        @Override
-        public boolean matchesSafely(Collection<BgpRouteEntry> entries) {
-            for (BgpRouteEntry entry : entries) {
-                if (bgpRouteEntry.equals(entry) &&
-                    bgpRouteEntry.getBgpSession() == entry.getBgpSession()) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public void describeTo(Description description) {
-            description.appendText("BGP route entry lookup for entry \"").
-                appendText(bgpRouteEntry.toString()).
-                appendText("\"");
-        }
-    }
-
-    /**
-     * A helper method used for testing whether a collection of
-     * BGP route entries contains an entry from a specific BGP peer.
-     *
-     * @param bgpRouteEntry the BGP route entry to test
-     * @return an instance of BgpRouteEntryAndPeerMatcher that implements
-     * the matching logic
-     */
-    private static BgpRouteEntryAndPeerMatcher hasBgpRouteEntry(
-        BgpRouteEntry bgpRouteEntry) {
-        return new BgpRouteEntryAndPeerMatcher(bgpRouteEntry);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        peer1 = new TestBgpPeer(BGP_PEER1_ID);
-        peer2 = new TestBgpPeer(BGP_PEER2_ID);
-        peer3 = new TestBgpPeer(BGP_PEER3_ID);
-        peers.clear();
-        peers.add(peer1);
-        peers.add(peer2);
-        peers.add(peer3);
-
-        //
-        // Setup the BGP Session Manager to test, and start listening for BGP
-        // connections.
-        //
-        bgpSessionManager = new BgpSessionManager(dummyRouteListener);
-        // NOTE: We use port 0 to bind on any available port
-        bgpSessionManager.start(0);
-
-        // Get the port number the BGP Session Manager is listening on
-        Channel serverChannel = TestUtils.getField(bgpSessionManager,
-                                                   "serverChannel");
-        SocketAddress socketAddress = serverChannel.getLocalAddress();
-        InetSocketAddress inetSocketAddress =
-            (InetSocketAddress) socketAddress;
-        InetAddress connectToAddress = InetAddresses.forString("127.0.0.1");
-        connectToSocket = new InetSocketAddress(connectToAddress,
-                                                inetSocketAddress.getPort());
-
-        //
-        // Setup the AS Paths
-        //
-        ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
-        byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
-        ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
-        segmentAsNumbers1.add((long) 65010);
-        segmentAsNumbers1.add((long) 65020);
-        segmentAsNumbers1.add((long) 65030);
-        BgpRouteEntry.PathSegment pathSegment1 =
-            new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
-        pathSegments.add(pathSegment1);
-        asPathShort = new BgpRouteEntry.AsPath(new ArrayList(pathSegments));
-        //
-        byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
-        ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
-        segmentAsNumbers2.add((long) 65041);
-        segmentAsNumbers2.add((long) 65042);
-        segmentAsNumbers2.add((long) 65043);
-        BgpRouteEntry.PathSegment pathSegment2 =
-            new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
-        pathSegments.add(pathSegment2);
-        //
-        asPathLong = new BgpRouteEntry.AsPath(pathSegments);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        bgpSessionManager.stop();
-        bgpSessionManager = null;
-    }
-
-    /**
-     * Gets BGP RIB-IN routes by waiting until they are received.
-     * <p>
-     * NOTE: We keep checking once every 10ms the number of received routes,
-     * up to 5 seconds.
-     * </p>
-     *
-     * @param bgpSession the BGP session that is expected to receive the
-     * routes
-     * @param expectedRoutes the expected number of routes
-     * @return the BGP RIB-IN routes as received within the expected
-     * time interval
-     */
-    private Collection<BgpRouteEntry> waitForBgpRibIn(BgpSession bgpSession,
-                                                      long expectedRoutes)
-        throws InterruptedException {
-        Collection<BgpRouteEntry> bgpRibIn = bgpSession.getBgpRibIn4();
-
-        final int maxChecks = 500;              // Max wait of 5 seconds
-        for (int i = 0; i < maxChecks; i++) {
-            if (bgpRibIn.size() == expectedRoutes) {
-                break;
-            }
-            Thread.sleep(10);
-            bgpRibIn = bgpSession.getBgpRibIn4();
-        }
-
-        return bgpRibIn;
-    }
-
-    /**
-     * Gets BGP merged routes by waiting until they are received.
-     * <p>
-     * NOTE: We keep checking once every 10ms the number of received routes,
-     * up to 5 seconds.
-     * </p>
-     *
-     * @param expectedRoutes the expected number of routes
-     * @return the BGP Session Manager routes as received within the expected
-     * time interval
-     */
-    private Collection<BgpRouteEntry> waitForBgpRoutes(long expectedRoutes)
-        throws InterruptedException {
-        Collection<BgpRouteEntry> bgpRoutes =
-            bgpSessionManager.getBgpRoutes4();
-
-        final int maxChecks = 500;              // Max wait of 5 seconds
-        for (int i = 0; i < maxChecks; i++) {
-            if (bgpRoutes.size() == expectedRoutes) {
-                break;
-            }
-            Thread.sleep(10);
-            bgpRoutes = bgpSessionManager.getBgpRoutes4();
-        }
-
-        return bgpRoutes;
-    }
-
-    /**
-     * Gets a merged BGP route by waiting until it is received.
-     * <p>
-     * NOTE: We keep checking once every 10ms whether the route is received,
-     * up to 5 seconds.
-     * </p>
-     *
-     * @param expectedRoute the expected route
-     * @return the merged BGP route if received within the expected time
-     * interval, otherwise null
-     */
-    private BgpRouteEntry waitForBgpRoute(BgpRouteEntry expectedRoute)
-        throws InterruptedException {
-        Collection<BgpRouteEntry> bgpRoutes =
-            bgpSessionManager.getBgpRoutes4();
-
-        final int maxChecks = 500;              // Max wait of 5 seconds
-        for (int i = 0; i < maxChecks; i++) {
-            for (BgpRouteEntry bgpRouteEntry : bgpRoutes) {
-                if (bgpRouteEntry.equals(expectedRoute) &&
-                    bgpRouteEntry.getBgpSession() ==
-                    expectedRoute.getBgpSession()) {
-                    return bgpRouteEntry;
-                }
-            }
-            Thread.sleep(10);
-            bgpRoutes = bgpSessionManager.getBgpRoutes4();
-        }
-
-        return null;
-    }
-
-    /**
-     * Tests that the BGP OPEN messages have been exchanged, followed by
-     * KEEPALIVE.
-     * <p>
-     * The BGP Peer opens the sessions and transmits OPEN Message, eventually
-     * followed by KEEPALIVE. The tested BGP listener should respond by
-     * OPEN Message, followed by KEEPALIVE.
-     * </p>
-     *
-     * @throws TestUtilsException TestUtils error
-     */
-    @Test
-    public void testExchangedBgpOpenMessages()
-            throws InterruptedException, TestUtilsException {
-        // Initiate the connections
-        peer1.connect(connectToSocket);
-        peer2.connect(connectToSocket);
-        peer3.connect(connectToSocket);
-
-        //
-        // Test the fields from the BGP OPEN message:
-        // BGP version, AS number, BGP ID
-        //
-        for (TestBgpPeer peer : peers) {
-            assertThat(peer.peerFrameDecoder.remoteInfo.bgpVersion(),
-                       is(BgpConstants.BGP_VERSION));
-            assertThat(peer.peerFrameDecoder.remoteInfo.bgpId(),
-                       is(IP_LOOPBACK_ID));
-            assertThat(peer.peerFrameDecoder.remoteInfo.asNumber(),
-                       is(TestBgpPeerChannelHandler.PEER_AS));
-        }
-
-        //
-        // Test that the BgpSession instances have been created
-        //
-        assertThat(bgpSessionManager.getMyBgpId(), is(IP_LOOPBACK_ID));
-        assertThat(bgpSessionManager.getBgpSessions(), hasSize(3));
-        assertThat(bgpSession1, notNullValue());
-        assertThat(bgpSession2, notNullValue());
-        assertThat(bgpSession3, notNullValue());
-        for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
-            long sessionAs = bgpSession.localInfo().asNumber();
-            assertThat(sessionAs, is(TestBgpPeerChannelHandler.PEER_AS));
-        }
-    }
-
-
-    /**
-     * Tests that the BGP OPEN with Capability messages have been exchanged,
-     * followed by KEEPALIVE.
-     * <p>
-     * The BGP Peer opens the sessions and transmits OPEN Message, eventually
-     * followed by KEEPALIVE. The tested BGP listener should respond by
-     * OPEN Message, followed by KEEPALIVE.
-     * </p>
-     *
-     * @throws TestUtilsException TestUtils error
-     */
-    @Test
-    public void testExchangedBgpOpenCapabilityMessages()
-            throws InterruptedException, TestUtilsException {
-        //
-        // Setup the BGP Capabilities for all peers
-        //
-        for (TestBgpPeer peer : peers) {
-            peer.peerChannelHandler.localInfo.setIpv4Unicast();
-            peer.peerChannelHandler.localInfo.setIpv4Multicast();
-            peer.peerChannelHandler.localInfo.setIpv6Unicast();
-            peer.peerChannelHandler.localInfo.setIpv6Multicast();
-            peer.peerChannelHandler.localInfo.setAs4OctetCapability();
-            peer.peerChannelHandler.localInfo.setAs4Number(
-                TestBgpPeerChannelHandler.PEER_AS4);
-        }
-
-        // Initiate the connections
-        peer1.connect(connectToSocket);
-        peer2.connect(connectToSocket);
-        peer3.connect(connectToSocket);
-
-        //
-        // Test the fields from the BGP OPEN message:
-        // BGP version, BGP ID
-        //
-        for (TestBgpPeer peer : peers) {
-            assertThat(peer.peerFrameDecoder.remoteInfo.bgpVersion(),
-                       is(BgpConstants.BGP_VERSION));
-            assertThat(peer.peerFrameDecoder.remoteInfo.bgpId(),
-                       is(IP_LOOPBACK_ID));
-        }
-
-        //
-        // Test that the BgpSession instances have been created,
-        // and contain the appropriate BGP session information.
-        //
-        assertThat(bgpSessionManager.getMyBgpId(), is(IP_LOOPBACK_ID));
-        assertThat(bgpSessionManager.getBgpSessions(), hasSize(3));
-        assertThat(bgpSession1, notNullValue());
-        assertThat(bgpSession2, notNullValue());
-        assertThat(bgpSession3, notNullValue());
-        for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
-            BgpSessionInfo localInfo = bgpSession.localInfo();
-            assertThat(localInfo.ipv4Unicast(), is(true));
-            assertThat(localInfo.ipv4Multicast(), is(true));
-            assertThat(localInfo.ipv6Unicast(), is(true));
-            assertThat(localInfo.ipv6Multicast(), is(true));
-            assertThat(localInfo.as4OctetCapability(), is(true));
-            assertThat(localInfo.asNumber(),
-                       is(TestBgpPeerChannelHandler.PEER_AS4));
-            assertThat(localInfo.as4Number(),
-                       is(TestBgpPeerChannelHandler.PEER_AS4));
-        }
-    }
-
-    /**
-     * Tests that the BGP UPDATE messages have been received and processed.
-     */
-    @Test
-    public void testProcessedBgpUpdateMessages() throws InterruptedException {
-        ChannelBuffer message;
-        BgpRouteEntry bgpRouteEntry;
-        Collection<BgpRouteEntry> bgpRibIn1;
-        Collection<BgpRouteEntry> bgpRibIn2;
-        Collection<BgpRouteEntry> bgpRibIn3;
-        Collection<BgpRouteEntry> bgpRoutes;
-
-        // Initiate the connections
-        peer1.connect(connectToSocket);
-        peer2.connect(connectToSocket);
-        peer3.connect(connectToSocket);
-
-        // Prepare routes to add/delete
-        Collection<Ip4Prefix> addedRoutes = new LinkedList<>();
-        Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>();
-
-        //
-        // Add and delete some routes
-        //
-        addedRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0"));
-        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
-        addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
-        addedRoutes.add(Ip4Prefix.valueOf("40.0.0.0/24"));
-        addedRoutes.add(Ip4Prefix.valueOf("50.0.0.0/32"));
-        withdrawnRoutes.add(Ip4Prefix.valueOf("60.0.0.0/8"));
-        withdrawnRoutes.add(Ip4Prefix.valueOf("70.0.0.0/16"));
-        withdrawnRoutes.add(Ip4Prefix.valueOf("80.0.0.0/24"));
-        withdrawnRoutes.add(Ip4Prefix.valueOf("90.0.0.0/32"));
-        // Write the routes
-        message = peer1.peerChannelHandler.prepareBgpUpdate(
-                        NEXT_HOP1_ROUTER,
-                        DEFAULT_LOCAL_PREF,
-                        DEFAULT_MULTI_EXIT_DISC,
-                        asPathLong,
-                        addedRoutes,
-                        withdrawnRoutes);
-        peer1.peerChannelHandler.savedCtx.getChannel().write(message);
-        //
-        // Check that the routes have been received, processed and stored
-        //
-        bgpRibIn1 = waitForBgpRibIn(bgpSession1, 5);
-        assertThat(bgpRibIn1, hasSize(5));
-        bgpRoutes = waitForBgpRoutes(5);
-        assertThat(bgpRoutes, hasSize(5));
-        //
-        bgpRouteEntry =
-            new BgpRouteEntry(bgpSession1,
-                              Ip4Prefix.valueOf("0.0.0.0/0"),
-                              NEXT_HOP1_ROUTER,
-                              (byte) BgpConstants.Update.Origin.IGP,
-                              asPathLong,
-                              DEFAULT_LOCAL_PREF);
-        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
-        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
-        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
-        //
-        bgpRouteEntry =
-            new BgpRouteEntry(bgpSession1,
-                              Ip4Prefix.valueOf("20.0.0.0/8"),
-                              NEXT_HOP1_ROUTER,
-                              (byte) BgpConstants.Update.Origin.IGP,
-                              asPathLong,
-                              DEFAULT_LOCAL_PREF);
-        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
-        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
-        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
-        //
-        bgpRouteEntry =
-            new BgpRouteEntry(bgpSession1,
-                              Ip4Prefix.valueOf("30.0.0.0/16"),
-                              NEXT_HOP1_ROUTER,
-                              (byte) BgpConstants.Update.Origin.IGP,
-                              asPathLong,
-                              DEFAULT_LOCAL_PREF);
-        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
-        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
-        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
-        //
-        bgpRouteEntry =
-            new BgpRouteEntry(bgpSession1,
-                              Ip4Prefix.valueOf("40.0.0.0/24"),
-                              NEXT_HOP1_ROUTER,
-                              (byte) BgpConstants.Update.Origin.IGP,
-                              asPathLong,
-                              DEFAULT_LOCAL_PREF);
-        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
-        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
-        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
-        //
-        bgpRouteEntry =
-            new BgpRouteEntry(bgpSession1,
-                              Ip4Prefix.valueOf("50.0.0.0/32"),
-                              NEXT_HOP1_ROUTER,
-                              (byte) BgpConstants.Update.Origin.IGP,
-                              asPathLong,
-                              DEFAULT_LOCAL_PREF);
-        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
-        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
-        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
-
-        //
-        // Delete some routes
-        //
-        addedRoutes = new LinkedList<>();
-        withdrawnRoutes = new LinkedList<>();
-        withdrawnRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0"));
-        withdrawnRoutes.add(Ip4Prefix.valueOf("50.0.0.0/32"));
-        // Write the routes
-        message = peer1.peerChannelHandler.prepareBgpUpdate(
-                        NEXT_HOP1_ROUTER,
-                        DEFAULT_LOCAL_PREF,
-                        DEFAULT_MULTI_EXIT_DISC,
-                        asPathLong,
-                        addedRoutes,
-                        withdrawnRoutes);
-        peer1.peerChannelHandler.savedCtx.getChannel().write(message);
-        //
-        // Check that the routes have been received, processed and stored
-        //
-        bgpRibIn1 = waitForBgpRibIn(bgpSession1, 3);
-        assertThat(bgpRibIn1, hasSize(3));
-        bgpRoutes = waitForBgpRoutes(3);
-        assertThat(bgpRoutes, hasSize(3));
-        //
-        bgpRouteEntry =
-            new BgpRouteEntry(bgpSession1,
-                              Ip4Prefix.valueOf("20.0.0.0/8"),
-                              NEXT_HOP1_ROUTER,
-                              (byte) BgpConstants.Update.Origin.IGP,
-                              asPathLong,
-                              DEFAULT_LOCAL_PREF);
-        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
-        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
-        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
-        //
-        bgpRouteEntry =
-            new BgpRouteEntry(bgpSession1,
-                              Ip4Prefix.valueOf("30.0.0.0/16"),
-                              NEXT_HOP1_ROUTER,
-                              (byte) BgpConstants.Update.Origin.IGP,
-                              asPathLong,
-                              DEFAULT_LOCAL_PREF);
-        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
-        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
-        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
-        //
-        bgpRouteEntry =
-            new BgpRouteEntry(bgpSession1,
-                              Ip4Prefix.valueOf("40.0.0.0/24"),
-                              NEXT_HOP1_ROUTER,
-                              (byte) BgpConstants.Update.Origin.IGP,
-                              asPathLong,
-                              DEFAULT_LOCAL_PREF);
-        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
-        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
-        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
-
-
-        // Close the channels and test there are no routes
-        peer1.peerChannelHandler.closeChannel();
-        peer2.peerChannelHandler.closeChannel();
-        peer3.peerChannelHandler.closeChannel();
-        bgpRoutes = waitForBgpRoutes(0);
-        assertThat(bgpRoutes, hasSize(0));
-    }
-
-    /**
-     * Tests the BGP route preference.
-     */
-    @Test
-    public void testBgpRoutePreference() throws InterruptedException {
-        ChannelBuffer message;
-        BgpRouteEntry bgpRouteEntry;
-        Collection<BgpRouteEntry> bgpRibIn1;
-        Collection<BgpRouteEntry> bgpRibIn2;
-        Collection<BgpRouteEntry> bgpRibIn3;
-        Collection<BgpRouteEntry> bgpRoutes;
-        Collection<Ip4Prefix> addedRoutes = new LinkedList<>();
-        Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>();
-
-        // Initiate the connections
-        peer1.connect(connectToSocket);
-        peer2.connect(connectToSocket);
-        peer3.connect(connectToSocket);
-
-        //
-        // Setup the initial set of routes to Peer1
-        //
-        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
-        addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
-        // Write the routes
-        message = peer1.peerChannelHandler.prepareBgpUpdate(
-                        NEXT_HOP1_ROUTER,
-                        DEFAULT_LOCAL_PREF,
-                        DEFAULT_MULTI_EXIT_DISC,
-                        asPathLong,
-                        addedRoutes,
-                        withdrawnRoutes);
-        peer1.peerChannelHandler.savedCtx.getChannel().write(message);
-        bgpRoutes = waitForBgpRoutes(2);
-        assertThat(bgpRoutes, hasSize(2));
-
-        //
-        // Add a route entry to Peer2 with a better LOCAL_PREF
-        //
-        addedRoutes = new LinkedList<>();
-        withdrawnRoutes = new LinkedList<>();
-        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
-        // Write the routes
-        message = peer2.peerChannelHandler.prepareBgpUpdate(
-                        NEXT_HOP2_ROUTER,
-                        BETTER_LOCAL_PREF,
-                        DEFAULT_MULTI_EXIT_DISC,
-                        asPathLong,
-                        addedRoutes,
-                        withdrawnRoutes);
-        peer2.peerChannelHandler.savedCtx.getChannel().write(message);
-        //
-        // Check that the routes have been received, processed and stored
-        //
-        bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1);
-        assertThat(bgpRibIn2, hasSize(1));
-        bgpRoutes = waitForBgpRoutes(2);
-        assertThat(bgpRoutes, hasSize(2));
-        //
-        bgpRouteEntry =
-            new BgpRouteEntry(bgpSession2,
-                              Ip4Prefix.valueOf("20.0.0.0/8"),
-                              NEXT_HOP2_ROUTER,
-                              (byte) BgpConstants.Update.Origin.IGP,
-                              asPathLong,
-                              BETTER_LOCAL_PREF);
-        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
-        assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry));
-        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
-
-        //
-        // Add a route entry to Peer3 with a shorter AS path
-        //
-        addedRoutes = new LinkedList<>();
-        withdrawnRoutes = new LinkedList<>();
-        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
-        // Write the routes
-        message = peer3.peerChannelHandler.prepareBgpUpdate(
-                        NEXT_HOP3_ROUTER,
-                        BETTER_LOCAL_PREF,
-                        DEFAULT_MULTI_EXIT_DISC,
-                        asPathShort,
-                        addedRoutes,
-                        withdrawnRoutes);
-        peer3.peerChannelHandler.savedCtx.getChannel().write(message);
-        //
-        // Check that the routes have been received, processed and stored
-        //
-        bgpRibIn3 = waitForBgpRibIn(bgpSession3, 1);
-        assertThat(bgpRibIn3, hasSize(1));
-        bgpRoutes = waitForBgpRoutes(2);
-        assertThat(bgpRoutes, hasSize(2));
-        //
-        bgpRouteEntry =
-            new BgpRouteEntry(bgpSession3,
-                              Ip4Prefix.valueOf("20.0.0.0/8"),
-                              NEXT_HOP3_ROUTER,
-                              (byte) BgpConstants.Update.Origin.IGP,
-                              asPathShort,
-                              BETTER_LOCAL_PREF);
-        bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
-        assertThat(bgpRibIn3, hasBgpRouteEntry(bgpRouteEntry));
-        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
-
-        //
-        // Cleanup in preparation for next test: delete old route entry from
-        // Peer2
-        //
-        addedRoutes = new LinkedList<>();
-        withdrawnRoutes = new LinkedList<>();
-        withdrawnRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
-        // Write the routes
-        message = peer2.peerChannelHandler.prepareBgpUpdate(
-                        NEXT_HOP2_ROUTER,
-                        BETTER_LOCAL_PREF,
-                        BETTER_MULTI_EXIT_DISC,
-                        asPathShort,
-                        addedRoutes,
-                        withdrawnRoutes);
-        peer2.peerChannelHandler.savedCtx.getChannel().write(message);
-        //
-        // Check that the routes have been received, processed and stored
-        //
-        bgpRibIn2 = waitForBgpRibIn(bgpSession2, 0);
-        assertThat(bgpRibIn2, hasSize(0));
-
-        //
-        // Add a route entry to Peer2 with a better MED
-        //
-        addedRoutes = new LinkedList<>();
-        withdrawnRoutes = new LinkedList<>();
-        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
-        // Write the routes
-        message = peer2.peerChannelHandler.prepareBgpUpdate(
-                        NEXT_HOP2_ROUTER,
-                        BETTER_LOCAL_PREF,
-                        BETTER_MULTI_EXIT_DISC,
-                        asPathShort,
-                        addedRoutes,
-                        withdrawnRoutes);
-        peer2.peerChannelHandler.savedCtx.getChannel().write(message);
-        //
-        // Check that the routes have been received, processed and stored
-        //
-        bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1);
-        assertThat(bgpRibIn2, hasSize(1));
-        bgpRoutes = waitForBgpRoutes(2);
-        assertThat(bgpRoutes, hasSize(2));
-        //
-        bgpRouteEntry =
-            new BgpRouteEntry(bgpSession2,
-                              Ip4Prefix.valueOf("20.0.0.0/8"),
-                              NEXT_HOP2_ROUTER,
-                              (byte) BgpConstants.Update.Origin.IGP,
-                              asPathShort,
-                              BETTER_LOCAL_PREF);
-        bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC);
-        assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry));
-        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
-
-        //
-        // Add a route entry to Peer1 with a better (lower) BGP ID
-        //
-        addedRoutes = new LinkedList<>();
-        withdrawnRoutes = new LinkedList<>();
-        addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
-        withdrawnRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
-        // Write the routes
-        message = peer1.peerChannelHandler.prepareBgpUpdate(
-                        NEXT_HOP1_ROUTER,
-                        BETTER_LOCAL_PREF,
-                        BETTER_MULTI_EXIT_DISC,
-                        asPathShort,
-                        addedRoutes,
-                        withdrawnRoutes);
-        peer1.peerChannelHandler.savedCtx.getChannel().write(message);
-        //
-        // Check that the routes have been received, processed and stored
-        //
-        bgpRibIn1 = waitForBgpRibIn(bgpSession1, 1);
-        assertThat(bgpRibIn1, hasSize(1));
-        bgpRoutes = waitForBgpRoutes(1);
-        assertThat(bgpRoutes, hasSize(1));
-        //
-        bgpRouteEntry =
-            new BgpRouteEntry(bgpSession1,
-                              Ip4Prefix.valueOf("20.0.0.0/8"),
-                              NEXT_HOP1_ROUTER,
-                              (byte) BgpConstants.Update.Origin.IGP,
-                              asPathShort,
-                              BETTER_LOCAL_PREF);
-        bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC);
-        assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
-        assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
-
-
-        // Close the channels and test there are no routes
-        peer1.peerChannelHandler.closeChannel();
-        peer2.peerChannelHandler.closeChannel();
-        peer3.peerChannelHandler.closeChannel();
-        bgpRoutes = waitForBgpRoutes(0);
-        assertThat(bgpRoutes, hasSize(0));
-    }
-}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/PathSegmentTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/PathSegmentTest.java
deleted file mode 100644
index e8f2ddc..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/PathSegmentTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * 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 static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertThat;
-
-import java.util.ArrayList;
-
-import org.junit.Test;
-
-/**
- * Unit tests for the BgpRouteEntry.PathSegment class.
- */
-public class PathSegmentTest {
-    /**
-     * Generates a Path Segment.
-     *
-     * @return a generated PathSegment
-     */
-    private BgpRouteEntry.PathSegment generatePathSegment() {
-        byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
-        ArrayList<Long> segmentAsNumbers = new ArrayList<>();
-        segmentAsNumbers.add((long) 1);
-        segmentAsNumbers.add((long) 2);
-        segmentAsNumbers.add((long) 3);
-        BgpRouteEntry.PathSegment pathSegment =
-            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
-
-        return pathSegment;
-    }
-
-    /**
-     * Tests valid class constructor.
-     */
-    @Test
-    public void testConstructor() {
-        BgpRouteEntry.PathSegment pathSegment = generatePathSegment();
-
-        String expectedString =
-            "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}";
-        assertThat(pathSegment.toString(), is(expectedString));
-    }
-
-    /**
-     * Tests invalid class constructor for null Segment AS Numbers.
-     */
-    @Test(expected = NullPointerException.class)
-    public void testInvalidConstructorNullSegmentAsNumbers() {
-        byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
-        ArrayList<Long> segmentAsNumbers = null;
-        new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
-    }
-
-    /**
-     * Tests getting the fields of a Path Segment.
-     */
-    @Test
-    public void testGetFields() {
-        // Create the fields to compare against
-        byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
-        ArrayList<Long> segmentAsNumbers = new ArrayList<>();
-        segmentAsNumbers.add((long) 1);
-        segmentAsNumbers.add((long) 2);
-        segmentAsNumbers.add((long) 3);
-
-        // Generate the entry to test
-        BgpRouteEntry.PathSegment pathSegment = generatePathSegment();
-
-        assertThat(pathSegment.getType(), is(pathSegmentType));
-        assertThat(pathSegment.getSegmentAsNumbers(), is(segmentAsNumbers));
-    }
-
-    /**
-     * Tests equality of {@link BgpRouteEntry.PathSegment}.
-     */
-    @Test
-    public void testEquality() {
-        BgpRouteEntry.PathSegment pathSegment1 = generatePathSegment();
-        BgpRouteEntry.PathSegment pathSegment2 = generatePathSegment();
-
-        assertThat(pathSegment1, is(pathSegment2));
-    }
-
-    /**
-     * Tests non-equality of {@link BgpRouteEntry.PathSegment}.
-     */
-    @Test
-    public void testNonEquality() {
-        BgpRouteEntry.PathSegment pathSegment1 = generatePathSegment();
-
-        // Setup Path Segment 2
-        byte pathSegmentType = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
-        ArrayList<Long> segmentAsNumbers = new ArrayList<>();
-        segmentAsNumbers.add((long) 1);
-        segmentAsNumbers.add((long) 22);                        // Different
-        segmentAsNumbers.add((long) 3);
-        //
-        BgpRouteEntry.PathSegment pathSegment2 =
-            new BgpRouteEntry.PathSegment(pathSegmentType, segmentAsNumbers);
-
-        assertThat(pathSegment1, is(not(pathSegment2)));
-    }
-
-    /**
-     * Tests object string representation.
-     */
-    @Test
-    public void testToString() {
-        BgpRouteEntry.PathSegment pathSegment = generatePathSegment();
-
-        String expectedString =
-            "PathSegment{type=AS_SEQUENCE, segmentAsNumbers=[1, 2, 3]}";
-        assertThat(pathSegment.toString(), is(expectedString));
-    }
-}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/TestBgpPeerChannelHandler.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/TestBgpPeerChannelHandler.java
deleted file mode 100644
index 979a1ed..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/TestBgpPeerChannelHandler.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * 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.Collection;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.channel.SimpleChannelHandler;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-
-/**
- * Class for handling the remote BGP Peer session.
- */
-class TestBgpPeerChannelHandler extends SimpleChannelHandler {
-    static final long PEER_AS = 65001;
-    static final long PEER_AS4 = 0x12345678;
-    static final int PEER_HOLDTIME = 120;       // 120 seconds
-
-    final BgpSessionInfo localInfo = new BgpSessionInfo();
-    ChannelHandlerContext savedCtx;
-
-    /**
-     * Constructor for given BGP ID.
-     *
-     * @param bgpId the BGP ID to use
-     */
-    TestBgpPeerChannelHandler(Ip4Address bgpId) {
-        this.localInfo.setBgpVersion(BgpConstants.BGP_VERSION);
-        this.localInfo.setBgpId(bgpId);
-        this.localInfo.setAsNumber(PEER_AS);
-        this.localInfo.setHoldtime(PEER_HOLDTIME);
-    }
-
-    /**
-     * Closes the channel.
-     */
-    void closeChannel() {
-        savedCtx.getChannel().close();
-    }
-
-    @Override
-    public void channelConnected(ChannelHandlerContext ctx,
-                                 ChannelStateEvent channelEvent) {
-        this.savedCtx = ctx;
-        // Prepare and transmit BGP OPEN message
-        ChannelBuffer message = BgpOpen.prepareBgpOpen(localInfo);
-        ctx.getChannel().write(message);
-
-        // Prepare and transmit BGP KEEPALIVE message
-        message = BgpKeepalive.prepareBgpKeepalive();
-        ctx.getChannel().write(message);
-    }
-
-    @Override
-    public void channelDisconnected(ChannelHandlerContext ctx,
-                                    ChannelStateEvent channelEvent) {
-        // Nothing to do
-    }
-
-    /**
-     * Prepares BGP UPDATE message.
-     *
-     * @param nextHopRouter the next-hop router address for the routes to add
-     * @param localPref the local preference for the routes to use
-     * @param multiExitDisc the MED value
-     * @param asPath the AS path for the routes to add
-     * @param addedRoutes the routes to add
-     * @param withdrawnRoutes the routes to withdraw
-     * @return the message to transmit (BGP header included)
-     */
-    ChannelBuffer prepareBgpUpdate(Ip4Address nextHopRouter,
-                                   long localPref,
-                                   long multiExitDisc,
-                                   BgpRouteEntry.AsPath asPath,
-                                   Collection<Ip4Prefix> addedRoutes,
-                                   Collection<Ip4Prefix> withdrawnRoutes) {
-        int attrFlags;
-        ChannelBuffer message =
-            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
-        ChannelBuffer pathAttributes =
-            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
-
-        // Encode the Withdrawn Routes
-        ChannelBuffer encodedPrefixes = encodePackedPrefixes(withdrawnRoutes);
-        message.writeShort(encodedPrefixes.readableBytes());
-        message.writeBytes(encodedPrefixes);
-
-        // Encode the Path Attributes
-        // ORIGIN: IGP
-        attrFlags = 0x40;                               // Transitive flag
-        pathAttributes.writeByte(attrFlags);
-        pathAttributes.writeByte(BgpConstants.Update.Origin.TYPE);
-        pathAttributes.writeByte(1);                    // Data length
-        pathAttributes.writeByte(BgpConstants.Update.Origin.IGP);
-
-        // AS_PATH: asPath
-        attrFlags = 0x40;                               // Transitive flag
-        pathAttributes.writeByte(attrFlags);
-        pathAttributes.writeByte(BgpConstants.Update.AsPath.TYPE);
-        ChannelBuffer encodedAsPath = encodeAsPath(asPath);
-        pathAttributes.writeByte(encodedAsPath.readableBytes()); // Data length
-        pathAttributes.writeBytes(encodedAsPath);
-        // NEXT_HOP: nextHopRouter
-        attrFlags = 0x40;                               // Transitive flag
-        pathAttributes.writeByte(attrFlags);
-        pathAttributes.writeByte(BgpConstants.Update.NextHop.TYPE);
-        pathAttributes.writeByte(4);                    // Data length
-        pathAttributes.writeInt(nextHopRouter.toInt()); // Next-hop router
-        // LOCAL_PREF: localPref
-        attrFlags = 0x40;                               // Transitive flag
-        pathAttributes.writeByte(attrFlags);
-        pathAttributes.writeByte(BgpConstants.Update.LocalPref.TYPE);
-        pathAttributes.writeByte(4);                    // Data length
-        pathAttributes.writeInt((int) localPref);       // Preference value
-        // MULTI_EXIT_DISC: multiExitDisc
-        attrFlags = 0x80;                               // Optional
-                                                        // Non-Transitive flag
-        pathAttributes.writeByte(attrFlags);
-        pathAttributes.writeByte(BgpConstants.Update.MultiExitDisc.TYPE);
-        pathAttributes.writeByte(4);                    // Data length
-        pathAttributes.writeInt((int) multiExitDisc);   // Preference value
-        // The NLRI prefixes
-        encodedPrefixes = encodePackedPrefixes(addedRoutes);
-
-        // Write the Path Attributes, beginning with its length
-        message.writeShort(pathAttributes.readableBytes());
-        message.writeBytes(pathAttributes);
-        message.writeBytes(encodedPrefixes);
-
-        return BgpMessage.prepareBgpMessage(BgpConstants.BGP_TYPE_UPDATE,
-                                            message);
-    }
-
-    /**
-     * Encodes a collection of IPv4 network prefixes in a packed format.
-     * <p>
-     * The IPv4 prefixes are encoded in the form:
-     * <Length, Prefix> where Length is the length in bits of the IPv4 prefix,
-     * and Prefix is the IPv4 prefix (padded with trailing bits to the end
-     * of an octet).
-     *
-     * @param prefixes the prefixes to encode
-     * @return the buffer with the encoded prefixes
-     */
-    private ChannelBuffer encodePackedPrefixes(Collection<Ip4Prefix> prefixes) {
-        ChannelBuffer message =
-            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
-
-        // Write each of the prefixes
-        for (Ip4Prefix prefix : prefixes) {
-            int prefixBitlen = prefix.prefixLength();
-            int prefixBytelen = (prefixBitlen + 7) / 8;         // Round-up
-            message.writeByte(prefixBitlen);
-
-            Ip4Address address = prefix.address();
-            long value = address.toInt() & 0xffffffffL;
-            for (int i = 0; i < Ip4Address.BYTE_LENGTH; i++) {
-                if (prefixBytelen-- == 0) {
-                    break;
-                }
-                long nextByte =
-                    (value >> ((Ip4Address.BYTE_LENGTH - i - 1) * 8)) & 0xff;
-                message.writeByte((int) nextByte);
-            }
-        }
-
-        return message;
-    }
-
-    /**
-     * Encodes an AS path.
-     *
-     * @param asPath the AS path to encode
-     * @return the buffer with the encoded AS path
-     */
-    private ChannelBuffer encodeAsPath(BgpRouteEntry.AsPath asPath) {
-        ChannelBuffer message =
-            ChannelBuffers.buffer(BgpConstants.BGP_MESSAGE_MAX_LENGTH);
-
-        for (BgpRouteEntry.PathSegment pathSegment : asPath.getPathSegments()) {
-            message.writeByte(pathSegment.getType());
-            message.writeByte(pathSegment.getSegmentAsNumbers().size());
-            for (Long asNumber : pathSegment.getSegmentAsNumbers()) {
-                message.writeShort(asNumber.intValue());
-            }
-        }
-
-        return message;
-    }
-}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/TestBgpPeerFrameDecoder.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/TestBgpPeerFrameDecoder.java
deleted file mode 100644
index 4f39547..0000000
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/TestBgpPeerFrameDecoder.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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.concurrent.CountDownLatch;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.handler.codec.frame.FrameDecoder;
-import org.onlab.packet.Ip4Address;
-
-/**
- * Class for handling the decoding of the BGP messages at the remote
- * BGP peer session.
- */
-class TestBgpPeerFrameDecoder extends FrameDecoder {
-    final BgpSessionInfo remoteInfo = new BgpSessionInfo();
-
-    final CountDownLatch receivedOpenMessageLatch = new CountDownLatch(1);
-    final CountDownLatch receivedKeepaliveMessageLatch = new CountDownLatch(1);
-
-    @Override
-    protected Object decode(ChannelHandlerContext ctx,
-                            Channel channel,
-                            ChannelBuffer buf) throws Exception {
-        // Test for minimum length of the BGP message
-        if (buf.readableBytes() < BgpConstants.BGP_HEADER_LENGTH) {
-            // No enough data received
-            return null;
-        }
-
-        //
-        // Mark the current buffer position in case we haven't received
-        // the whole message.
-        //
-        buf.markReaderIndex();
-
-        //
-        // Read and check the BGP message Marker field: it must be all ones
-        //
-        byte[] marker = new byte[BgpConstants.BGP_HEADER_MARKER_LENGTH];
-        buf.readBytes(marker);
-        for (int i = 0; i < marker.length; i++) {
-            if (marker[i] != (byte) 0xff) {
-                // ERROR: Connection Not Synchronized. Close the channel.
-                ctx.getChannel().close();
-                return null;
-            }
-        }
-
-        //
-        // Read and check the BGP message Length field
-        //
-        int length = buf.readUnsignedShort();
-        if ((length < BgpConstants.BGP_HEADER_LENGTH) ||
-            (length > BgpConstants.BGP_MESSAGE_MAX_LENGTH)) {
-            // ERROR: Bad Message Length. Close the channel.
-            ctx.getChannel().close();
-            return null;
-        }
-
-        //
-        // Test whether the rest of the message is received:
-        // So far we have read the Marker (16 octets) and the
-        // Length (2 octets) fields.
-        //
-        int remainingMessageLen =
-            length - BgpConstants.BGP_HEADER_MARKER_LENGTH - 2;
-        if (buf.readableBytes() < remainingMessageLen) {
-            // No enough data received
-            buf.resetReaderIndex();
-            return null;
-        }
-
-        //
-        // Read the BGP message Type field, and process based on that type
-        //
-        int type = buf.readUnsignedByte();
-        remainingMessageLen--;      // Adjust after reading the type
-        ChannelBuffer message = buf.readBytes(remainingMessageLen);
-
-        //
-        // Process the remaining of the message based on the message type
-        //
-        switch (type) {
-        case BgpConstants.BGP_TYPE_OPEN:
-            processBgpOpen(ctx, message);
-            break;
-        case BgpConstants.BGP_TYPE_UPDATE:
-            // NOTE: Not used as part of the test, because ONOS does not
-            // originate UPDATE messages.
-            break;
-        case BgpConstants.BGP_TYPE_NOTIFICATION:
-            // NOTE: Not used as part of the testing (yet)
-            break;
-        case BgpConstants.BGP_TYPE_KEEPALIVE:
-            processBgpKeepalive(ctx, message);
-            break;
-        default:
-            // ERROR: Bad Message Type. Close the channel.
-            ctx.getChannel().close();
-            return null;
-        }
-
-        return null;
-    }
-
-    /**
-     * Processes BGP OPEN message.
-     *
-     * @param ctx the Channel Handler Context.
-     * @param message the message to process.
-     */
-    private void processBgpOpen(ChannelHandlerContext ctx,
-                                ChannelBuffer message) {
-        int minLength =
-            BgpConstants.BGP_OPEN_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH;
-        if (message.readableBytes() < minLength) {
-            // ERROR: Bad Message Length. Close the channel.
-            ctx.getChannel().close();
-            return;
-        }
-
-        //
-        // Parse the OPEN message
-        //
-        remoteInfo.setBgpVersion(message.readUnsignedByte());
-        remoteInfo.setAsNumber(message.readUnsignedShort());
-        remoteInfo.setHoldtime(message.readUnsignedShort());
-        remoteInfo.setBgpId(Ip4Address.valueOf((int) message.readUnsignedInt()));
-        // Optional Parameters
-        int optParamLen = message.readUnsignedByte();
-        if (message.readableBytes() < optParamLen) {
-            // ERROR: Bad Message Length. Close the channel.
-            ctx.getChannel().close();
-            return;
-        }
-        message.readBytes(optParamLen);             // NOTE: data ignored
-
-        // BGP OPEN message successfully received
-        receivedOpenMessageLatch.countDown();
-    }
-
-    /**
-     * Processes BGP KEEPALIVE message.
-     *
-     * @param ctx the Channel Handler Context.
-     * @param message the message to process.
-     */
-    private void processBgpKeepalive(ChannelHandlerContext ctx,
-                                     ChannelBuffer message) {
-        if (message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH !=
-            BgpConstants.BGP_KEEPALIVE_EXPECTED_LENGTH) {
-            // ERROR: Bad Message Length. Close the channel.
-            ctx.getChannel().close();
-            return;
-        }
-        // BGP KEEPALIVE message successfully received
-        receivedKeepaliveMessageLatch.countDown();
-    }
-}
