diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/FibEntry.java b/apps/routing-api/src/main/java/org/onosproject/routing/FibEntry.java
index e75ea47..3c5d550 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/FibEntry.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/FibEntry.java
@@ -24,7 +24,10 @@
 
 /**
  * An entry in the Forwarding Information Base (FIB).
+ *
+ * @deprecated use RouteService instead
  */
+@Deprecated
 public class FibEntry {
 
     private final IpPrefix prefix;
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/FibListener.java b/apps/routing-api/src/main/java/org/onosproject/routing/FibListener.java
index a184146..868fd02 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/FibListener.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/FibListener.java
@@ -19,7 +19,10 @@
 
 /**
  * A component that is able to process Forwarding Information Base (FIB) updates.
+ *
+ * @deprecated use RouteService instead
  */
+@Deprecated
 public interface FibListener {
 
     /**
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/FibUpdate.java b/apps/routing-api/src/main/java/org/onosproject/routing/FibUpdate.java
index c6efc3f..d8acae7 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/FibUpdate.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/FibUpdate.java
@@ -21,7 +21,10 @@
 
 /**
  * Represents a change to the Forwarding Information Base (FIB).
+ *
+ * @deprecated use RouteService instead
  */
+@Deprecated
 public class FibUpdate {
 
     /**
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/RouteEntry.java b/apps/routing-api/src/main/java/org/onosproject/routing/RouteEntry.java
index 4149164..2baf686 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/RouteEntry.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/RouteEntry.java
@@ -25,7 +25,10 @@
 
 /**
  * Represents a route entry for an IP prefix.
+ *
+ * @deprecated use RouteService instead
  */
+@Deprecated
 public class RouteEntry {
     private final IpPrefix prefix;              // The IP prefix
     private final IpAddress nextHop;            // Next-hop IP address
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/RouteUpdate.java b/apps/routing-api/src/main/java/org/onosproject/routing/RouteUpdate.java
index bac3d71..9f95f3b 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/RouteUpdate.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/RouteUpdate.java
@@ -23,7 +23,10 @@
 
 /**
  * Represents a change in routing information.
+ *
+ * @deprecated use RouteService instead
  */
+@Deprecated
 public class RouteUpdate {
     private final Type type;                    // The route update type
     private final RouteEntry routeEntry;        // The updated route entry
diff --git a/apps/routing/src/main/java/org/onosproject/routing/impl/DefaultRouter.java b/apps/routing/src/main/java/org/onosproject/routing/impl/DefaultRouter.java
deleted file mode 100644
index bf0908d..0000000
--- a/apps/routing/src/main/java/org/onosproject/routing/impl/DefaultRouter.java
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- * Copyright 2014-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.routing.impl;
-
-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.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.Service;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip6Address;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
-import org.onosproject.core.CoreService;
-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.onosproject.routing.RouteSourceService;
-import org.onosproject.routing.FibEntry;
-import org.onosproject.routing.FibListener;
-import org.onosproject.routing.FibUpdate;
-import org.onosproject.routing.RouteEntry;
-import org.onosproject.routing.RouteListener;
-import org.onosproject.routing.RouteUpdate;
-import org.onosproject.routing.RoutingService;
-import org.onosproject.routing.config.RoutingConfigurationService;
-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;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onosproject.routing.RouteEntry.createBinaryString;
-
-/**
- * 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.
- * <p>
- * This implementation has been superseded by the RouteService and will be
- * removed soon.
- * </p>
- */
-@Deprecated
-@Component(immediate = true, enabled = false)
-@Service
-public class DefaultRouter implements RoutingService {
-
-    private static final Logger log = LoggerFactory.getLogger(DefaultRouter.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 =
-            new LinkedBlockingQueue<>();
-
-    // Next-hop IP address to route entry mapping for next hops pending MAC
-    // resolution
-    private SetMultimap<IpAddress, RouteEntry> routesWaitingOnArp;
-
-    // The IPv4 address to MAC address mapping
-    private final Map<IpAddress, MacAddress> ip2Mac = new ConcurrentHashMap<>();
-
-    private FibListener fibComponent;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected CoreService coreService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected HostService hostService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected RouteSourceService routeSourceService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected RoutingConfigurationService routingConfigurationService;
-
-    private ExecutorService bgpUpdatesExecutor;
-    private final HostListener hostListener = new InternalHostListener();
-
-    @Activate
-    public void activate() {
-        ribTable4 = new ConcurrentInvertedRadixTree<>(
-                new DefaultByteArrayNodeFactory());
-        ribTable6 = new ConcurrentInvertedRadixTree<>(
-                new DefaultByteArrayNodeFactory());
-
-        routesWaitingOnArp = Multimaps.synchronizedSetMultimap(
-                HashMultimap.create());
-
-        coreService.registerApplication(ROUTER_APP_ID);
-
-        bgpUpdatesExecutor = Executors.newSingleThreadExecutor(
-                new ThreadFactoryBuilder()
-                .setNameFormat("rib-updates-%d").build());
-    }
-
-    @Deactivate
-    public void deactivate() {
-        log.debug("Stopped");
-    }
-
-    @Override
-    public void addFibListener(FibListener fibListener) {
-        this.fibComponent = checkNotNull(fibListener);
-    }
-
-    @Override
-    public void start() {
-        this.hostService.addListener(hostListener);
-
-        routeSourceService.start(new InternalRouteListener());
-
-        bgpUpdatesExecutor.execute(this::doUpdatesThread);
-    }
-
-    @Override
-    public void stop() {
-        routeSourceService.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();
-        }
-    }
-
-    /**
-     * Entry point for route updates.
-     *
-     * @param routeUpdates collection of route updates to process
-     */
-    private void update(Collection<RouteUpdate> routeUpdates) {
-        try {
-            routeUpdatesQueue.put(routeUpdates);
-        } catch (InterruptedException e) {
-            log.error("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.error("Interrupted while taking from updates queue", e);
-                    interrupted = true;
-                } catch (Exception e) {
-                    log.error("exception", e);
-                }
-            }
-        } finally {
-            if (interrupted) {
-                Thread.currentThread().interrupt();
-            }
-        }
-    }
-
-    /**
-     * Gets all IPv4 routes from the RIB.
-     *
-     * @return all IPv4 routes from the RIB
-     */
-    @Override
-    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
-     */
-    @Override
-    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 = createBinaryString(prefix);
-        if (prefix.isIp4()) {
-            // 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.isIp4()) {
-            // IPv4
-            ribTable4.put(createBinaryString(routeEntry.prefix()), routeEntry);
-        } else {
-            // IPv6
-            ribTable6.put(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.isIp4()) {
-            // IPv4
-            return ribTable4.remove(createBinaryString(prefix));
-        }
-        // IPv6
-        return ribTable6.remove(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))));
-
-            if (!fibUpdates.isEmpty() || !fibWithdraws.isEmpty()) {
-                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 (routingConfigurationService.isIpPrefixLocal(routeEntry.prefix())) {
-            // Route originated by local SDN domain
-            // We don't handle these here, reactive routing APP will handle
-            // these
-            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;
-            }
-        }
-    }
-
-    /**
-     * Listener for route events.
-     */
-    private class InternalRouteListener implements RouteListener {
-        @Override
-        public void update(Collection<RouteUpdate> routeUpdates) {
-            DefaultRouter.this.update(routeUpdates);
-        }
-    }
-
-    @Override
-    public RouteEntry getLongestMatchableRouteEntry(IpAddress ipAddress) {
-        RouteEntry routeEntry = null;
-        Iterable<RouteEntry> routeEntries;
-
-        if (ipAddress.isIp4()) {
-            routeEntries = ribTable4.getValuesForKeysPrefixing(
-                    createBinaryString(
-                    IpPrefix.valueOf(ipAddress, Ip4Address.BIT_LENGTH)));
-        } else {
-            routeEntries = ribTable6.getValuesForKeysPrefixing(
-                    createBinaryString(
-                    IpPrefix.valueOf(ipAddress, Ip6Address.BIT_LENGTH)));
-        }
-        if (routeEntries == null) {
-            return null;
-        }
-        Iterator<RouteEntry> it = routeEntries.iterator();
-        while (it.hasNext()) {
-            routeEntry = it.next();
-        }
-        return routeEntry;
-    }
-
-}
diff --git a/apps/routing/src/test/java/org/onosproject/routing/impl/RouterAsyncArpTest.java b/apps/routing/src/test/java/org/onosproject/routing/impl/RouterAsyncArpTest.java
deleted file mode 100644
index f05a287..0000000
--- a/apps/routing/src/test/java/org/onosproject/routing/impl/RouterAsyncArpTest.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.routing.impl;
-
-import com.google.common.collect.Sets;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-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.CoreService;
-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.host.HostEvent;
-import org.onosproject.net.host.HostListener;
-import org.onosproject.net.host.HostService;
-import org.onosproject.net.provider.ProviderId;
-import org.onosproject.routing.config.RoutingConfigurationService;
-import org.onosproject.routing.impl.DefaultRouter.InternalHostListener;
-import org.onosproject.routing.RouteSourceService;
-import org.onosproject.routing.FibEntry;
-import org.onosproject.routing.FibListener;
-import org.onosproject.routing.FibUpdate;
-import org.onosproject.routing.RouteEntry;
-import org.onosproject.routing.RouteListener;
-import org.onosproject.routing.RouteUpdate;
-
-import java.util.Collections;
-
-import static org.easymock.EasyMock.*;
-
-/**
-* This class tests adding a route and updating a route.
-* The HostService module answers the MAC address asynchronously.
-*/
-public class RouterAsyncArpTest {
-
-    private HostService hostService;
-    private FibListener fibListener;
-    private RoutingConfigurationService routingConfigurationService;
-
-    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 DefaultRouter router;
-    private InternalHostListener internalHostListener;
-
-    @Before
-    public void setUp() throws Exception {
-        hostService = createMock(HostService.class);
-        routingConfigurationService =
-                createMock(RoutingConfigurationService.class);
-
-        RouteSourceService routeSourceService = createMock(RouteSourceService.class);
-        routeSourceService.start(anyObject(RouteListener.class));
-        routeSourceService.stop();
-        replay(routeSourceService);
-
-        fibListener = createMock(FibListener.class);
-
-        router = new DefaultRouter();
-        router.coreService = createNiceMock(CoreService.class);
-        router.hostService = hostService;
-        router.routingConfigurationService = routingConfigurationService;
-        router.routeSourceService = routeSourceService;
-        router.activate();
-
-        router.addFibListener(fibListener);
-        router.start();
-
-        internalHostListener = router.new InternalHostListener();
-    }
-
-    @After
-    public void tearDown() {
-        // Called during shutdown
-        reset(hostService);
-        hostService.removeListener(anyObject(HostListener.class));
-
-        router.stop();
-    }
-
-    /**
-     * Tests adding a route entry with asynchronous HostService replies.
-     */
-    @Test
-    public void testRouteAdd() {
-        // Construct a route entry
-        IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
-        IpAddress nextHopIp = Ip4Address.valueOf("192.168.10.1");
-
-        RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp);
-
-        // Host service will reply with no hosts when asked
-        reset(hostService);
-        expect(hostService.getHostsByIp(anyObject(IpAddress.class))).andReturn(
-                Collections.emptySet()).anyTimes();
-        hostService.startMonitoringIp(IpAddress.valueOf("192.168.10.1"));
-        replay(hostService);
-
-        reset(routingConfigurationService);
-        expect(routingConfigurationService.isIpPrefixLocal(
-                anyObject(IpPrefix.class))).andReturn(false);
-        replay(routingConfigurationService);
-
-        // Initially when we add the route, no FIB update will be sent
-        replay(fibListener);
-
-        router.processRouteUpdates(Collections.singletonList(
-                new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry)));
-
-        verify(fibListener);
-
-
-        // Now when we send the event, we expect the FIB update to be sent
-        reset(fibListener);
-        FibEntry fibEntry = new FibEntry(prefix, nextHopIp,
-                                         MacAddress.valueOf("00:00:00:00:00:01"));
-
-        fibListener.update(Collections.singletonList(new FibUpdate(
-                FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList());
-        replay(fibListener);
-
-        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")));
-
-        // Send in the host event
-        internalHostListener.event(
-                new HostEvent(HostEvent.Type.HOST_ADDED, host));
-
-        verify(fibListener);
-    }
-
-    /**
-     * Tests updating a route entry with asynchronous HostService replies.
-     */
-    @Test
-    public void testRouteUpdate() {
-        // Add a route
-        testRouteAdd();
-
-        // Construct a route entry
-        IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
-        IpAddress nextHopIp = Ip4Address.valueOf("192.168.20.1");
-
-        RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp);
-
-        // Host service will reply with no hosts when asked
-        reset(hostService);
-        expect(hostService.getHostsByIp(anyObject(IpAddress.class))).andReturn(
-                Collections.emptySet()).anyTimes();
-        hostService.startMonitoringIp(IpAddress.valueOf("192.168.20.1"));
-        replay(hostService);
-
-        reset(routingConfigurationService);
-        expect(routingConfigurationService.isIpPrefixLocal(
-                anyObject(IpPrefix.class))).andReturn(false);
-        replay(routingConfigurationService);
-
-        // Initially when we add the route, the DELETE FIB update will be sent
-        // but the UPDATE FIB update will come later when the MAC is resolved
-        reset(fibListener);
-
-        fibListener.update(Collections.emptyList(), Collections.singletonList(new FibUpdate(
-                FibUpdate.Type.DELETE, new FibEntry(prefix, null, null))));
-        replay(fibListener);
-
-        router.processRouteUpdates(Collections.singletonList(
-                new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry)));
-
-        verify(fibListener);
-
-
-        // Now when we send the event, we expect the FIB update to be sent
-        reset(fibListener);
-        FibEntry fibEntry = new FibEntry(prefix, nextHopIp,
-                                         MacAddress.valueOf("00:00:00:00:00:02"));
-
-        fibListener.update(Collections.singletonList(new FibUpdate(
-                FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList());
-        replay(fibListener);
-
-        Host host = new DefaultHost(ProviderId.NONE, HostId.NONE,
-                                    MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE,
-                                    new HostLocation(
-                                            SW1_ETH1.deviceId(),
-                                            SW1_ETH1.port(), 1),
-                                    Sets.newHashSet(IpAddress.valueOf("192.168.20.1")));
-
-        // Send in the host event
-        internalHostListener.event(
-                new HostEvent(HostEvent.Type.HOST_ADDED, host));
-
-        verify(fibListener);
-    }
-}
diff --git a/apps/routing/src/test/java/org/onosproject/routing/impl/RouterTest.java b/apps/routing/src/test/java/org/onosproject/routing/impl/RouterTest.java
deleted file mode 100644
index 2e3b740..0000000
--- a/apps/routing/src/test/java/org/onosproject/routing/impl/RouterTest.java
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.routing.impl;
-
-import com.google.common.collect.Sets;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.packet.Ip6Address;
-import org.onlab.packet.Ip6Prefix;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onosproject.core.CoreService;
-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.host.HostListener;
-import org.onosproject.net.host.HostService;
-import org.onosproject.net.provider.ProviderId;
-import org.onosproject.routing.RouteSourceService;
-import org.onosproject.routing.FibEntry;
-import org.onosproject.routing.FibListener;
-import org.onosproject.routing.FibUpdate;
-import org.onosproject.routing.RouteEntry;
-import org.onosproject.routing.RouteListener;
-import org.onosproject.routing.RouteUpdate;
-import org.onosproject.routing.config.RoutingConfigurationService;
-
-import java.util.Collections;
-
-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/>
- * The HostService answers requests synchronously.
- */
-public class RouterTest {
-
-    private HostService hostService;
-    private RoutingConfigurationService routingConfigurationService;
-
-    private FibListener fibListener;
-
-    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 ConnectPoint SW5_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000005"),
-            PortNumber.portNumber(1));
-
-    private static final ConnectPoint SW6_ETH1 = new ConnectPoint(
-            DeviceId.deviceId("of:0000000000000006"),
-            PortNumber.portNumber(1));
-    private DefaultRouter router;
-
-    @Before
-    public void setUp() throws Exception {
-        setUpHostService();
-        routingConfigurationService =
-                createMock(RoutingConfigurationService.class);
-
-        RouteSourceService routeSourceService = createMock(RouteSourceService.class);
-        routeSourceService.start(anyObject(RouteListener.class));
-        routeSourceService.stop();
-        replay(routeSourceService);
-
-        fibListener = createMock(FibListener.class);
-
-        router = new DefaultRouter();
-        router.coreService = createNiceMock(CoreService.class);
-        router.hostService = hostService;
-        router.routingConfigurationService = routingConfigurationService;
-        router.routeSourceService = routeSourceService;
-        router.activate();
-
-        router.addFibListener(fibListener);
-        router.start();
-    }
-
-    @After
-    public void tearDown() {
-        router.stop();
-    }
-
-    /**
-     * 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(SW3_ETH1, 1),
-                Sets.newHashSet(host3Address));
-
-        expect(hostService.getHostsByIp(host3Address))
-                .andReturn(Sets.newHashSet(host3)).anyTimes();
-        hostService.startMonitoringIp(host3Address);
-        expectLastCall().anyTimes();
-
-        IpAddress host4Address = IpAddress.valueOf("1000::1");
-        Host host4 = new DefaultHost(ProviderId.NONE, HostId.NONE,
-                 MacAddress.valueOf("00:00:00:00:00:04"), VlanId.NONE,
-                 new HostLocation(SW4_ETH1, 1),
-                 Sets.newHashSet(host4Address));
-
-        expect(hostService.getHostsByIp(host4Address))
-                .andReturn(Sets.newHashSet(host4)).anyTimes();
-        hostService.startMonitoringIp(host4Address);
-        expectLastCall().anyTimes();
-
-        IpAddress host5Address = IpAddress.valueOf("2000::1");
-        Host host5 = new DefaultHost(ProviderId.NONE, HostId.NONE,
-                 MacAddress.valueOf("00:00:00:00:00:05"), VlanId.NONE,
-                 new HostLocation(SW5_ETH1, 1),
-                 Sets.newHashSet(host5Address));
-
-        expect(hostService.getHostsByIp(host5Address))
-                .andReturn(Sets.newHashSet(host5)).anyTimes();
-        hostService.startMonitoringIp(host5Address);
-        expectLastCall().anyTimes();
-
-        // Next hop on a VLAN
-        IpAddress host6Address = IpAddress.valueOf("3000::1");
-        Host host6 = new DefaultHost(ProviderId.NONE, HostId.NONE,
-                 MacAddress.valueOf("00:00:00:00:00:06"), VlanId.vlanId((short) 1),
-                 new HostLocation(SW6_ETH1, 1),
-                 Sets.newHashSet(host6Address));
-
-        expect(hostService.getHostsByIp(host6Address))
-                .andReturn(Sets.newHashSet(host6)).anyTimes();
-        hostService.startMonitoringIp(host6Address);
-        expectLastCall().anyTimes();
-
-
-        // Called during shutdown
-        hostService.removeListener(anyObject(HostListener.class));
-
-        replay(hostService);
-    }
-
-    /**
-     * Tests adding a IPv4 route entry.
-     */
-    @Test
-    public void testIpv4RouteAdd() {
-        // Construct a route entry
-        IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
-        IpAddress nextHopIp = Ip4Address.valueOf("192.168.10.1");
-
-        RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp);
-
-        // Expected FIB entry
-        FibEntry fibEntry = new FibEntry(prefix, nextHopIp,
-                MacAddress.valueOf("00:00:00:00:00:01"));
-
-        fibListener.update(Collections.singletonList(new FibUpdate(
-                FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList());
-
-        replay(fibListener);
-
-        router.processRouteUpdates(Collections.singletonList(
-                new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry)));
-
-        verify(fibListener);
-    }
-
-
-    /**
-     * Tests adding a IPv6 route entry.
-     */
-    @Test
-    public void testIpv6RouteAdd() {
-        // Construct a route entry
-        IpPrefix prefix = Ip6Prefix.valueOf("4000::/64");
-        IpAddress nextHopIp = Ip6Address.valueOf("1000::1");
-
-        RouteEntry routeEntry = new RouteEntry(prefix, nextHopIp);
-
-        // Expected FIB entry
-        FibEntry fibEntry = new FibEntry(prefix, nextHopIp,
-                MacAddress.valueOf("00:00:00:00:00:04"));
-
-        fibListener.update(Collections.singletonList(new FibUpdate(
-                FibUpdate.Type.UPDATE, fibEntry)), Collections.emptyList());
-
-        replay(fibListener);
-
-        router.processRouteUpdates(Collections.singletonList(
-                new RouteUpdate(RouteUpdate.Type.UPDATE, routeEntry)));
-
-        verify(fibListener);
-    }
-
-
-    /**
-     * Tests updating a IPv4 route entry.
-     */
-    @Test
-    public void testRouteUpdate() {
-        // Firstly add a route
-        testIpv4RouteAdd();
-
-        // Route entry with updated next hop for the original prefix
-        RouteEntry routeEntryUpdate = new RouteEntry(
-                Ip4Prefix.valueOf("1.1.1.0/24"),
-                Ip4Address.valueOf("192.168.20.1"));
-
-        // The old FIB entry will be withdrawn
-        FibEntry withdrawFibEntry = new FibEntry(
-                Ip4Prefix.valueOf("1.1.1.0/24"), null, null);
-
-        // A new FIB entry will be added
-        FibEntry updateFibEntry = new FibEntry(
-                Ip4Prefix.valueOf("1.1.1.0/24"),
-                Ip4Address.valueOf("192.168.20.1"),
-                MacAddress.valueOf("00:00:00:00:00:02"));
-
-        reset(fibListener);
-        fibListener.update(Collections.singletonList(new FibUpdate(
-                                    FibUpdate.Type.UPDATE, updateFibEntry)),
-                           Collections.singletonList(new FibUpdate(
-                                    FibUpdate.Type.DELETE, withdrawFibEntry)));
-        replay(fibListener);
-
-        reset(routingConfigurationService);
-        expect(routingConfigurationService.isIpPrefixLocal(
-                anyObject(IpPrefix.class))).andReturn(false);
-        replay(routingConfigurationService);
-
-        router.processRouteUpdates(Collections.singletonList(new RouteUpdate(
-                RouteUpdate.Type.UPDATE, routeEntryUpdate)));
-
-        verify(fibListener);
-    }
-
-    /**
-     * Tests updating a IPv6 route entry.
-     */
-    @Test
-    public void testIpv6RouteUpdate() {
-        // Firstly add a route
-        testIpv6RouteAdd();
-
-        // Route entry with updated next hop for the original prefix
-        RouteEntry routeEntryUpdate = new RouteEntry(
-                Ip6Prefix.valueOf("4000::/64"),
-                Ip6Address.valueOf("2000::1"));
-
-        // The old FIB entry will be withdrawn
-        FibEntry withdrawFibEntry = new FibEntry(
-                Ip6Prefix.valueOf("4000::/64"), null, null);
-
-        // A new FIB entry will be added
-        FibEntry updateFibEntry = new FibEntry(
-                Ip6Prefix.valueOf("4000::/64"),
-                Ip6Address.valueOf("2000::1"),
-                MacAddress.valueOf("00:00:00:00:00:05"));
-
-        reset(fibListener);
-        fibListener.update(Collections.singletonList(new FibUpdate(
-                                   FibUpdate.Type.UPDATE, updateFibEntry)),
-                           Collections.singletonList(new FibUpdate(
-                                   FibUpdate.Type.DELETE, withdrawFibEntry)));
-        replay(fibListener);
-
-        reset(routingConfigurationService);
-        expect(routingConfigurationService.isIpPrefixLocal(
-                anyObject(IpPrefix.class))).andReturn(false);
-        replay(routingConfigurationService);
-
-        router.processRouteUpdates(Collections.singletonList(new RouteUpdate(
-                RouteUpdate.Type.UPDATE, routeEntryUpdate)));
-
-        verify(fibListener);
-    }
-
-    /**
-     * Tests deleting a IPv4 route entry.
-     */
-    @Test
-    public void testIpv4RouteDelete() {
-        // Firstly add a route
-        testIpv4RouteAdd();
-
-        RouteEntry deleteRouteEntry = new RouteEntry(
-                Ip4Prefix.valueOf("1.1.1.0/24"),
-                Ip4Address.valueOf("192.168.10.1"));
-
-        FibEntry deleteFibEntry = new FibEntry(
-                Ip4Prefix.valueOf("1.1.1.0/24"), null, null);
-
-        reset(fibListener);
-        fibListener.update(Collections.emptyList(), Collections.singletonList(
-                new FibUpdate(FibUpdate.Type.DELETE, deleteFibEntry)));
-
-        replay(fibListener);
-
-        router.processRouteUpdates(Collections.singletonList(
-                new RouteUpdate(RouteUpdate.Type.DELETE, deleteRouteEntry)));
-
-        verify(fibListener);
-    }
-
-    /**
-     * Tests deleting a IPv6 route entry.
-     */
-    @Test
-    public void testIpv6RouteDelete() {
-        // Firstly add a route
-        testIpv6RouteAdd();
-
-        RouteEntry deleteRouteEntry = new RouteEntry(
-                Ip6Prefix.valueOf("4000::/64"),
-                Ip6Address.valueOf("1000::1"));
-
-        FibEntry deleteFibEntry = new FibEntry(
-                Ip6Prefix.valueOf("4000::/64"), null, null);
-
-        reset(fibListener);
-        fibListener.update(Collections.emptyList(), Collections.singletonList(
-                new FibUpdate(FibUpdate.Type.DELETE, deleteFibEntry)));
-
-        replay(fibListener);
-
-        router.processRouteUpdates(Collections.singletonList(
-                new RouteUpdate(RouteUpdate.Type.DELETE, deleteRouteEntry)));
-
-        verify(fibListener);
-    }
-
-    /**
-     * Tests adding a IPv4 route whose next hop is the local BGP speaker.
-     */
-    @Test
-    public void testIpv4LocalRouteAdd() {
-        // 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"));
-
-        // No methods on the FIB listener should be called
-        replay(fibListener);
-
-        reset(routingConfigurationService);
-        expect(routingConfigurationService.isIpPrefixLocal(
-                anyObject(IpPrefix.class))).andReturn(true);
-        replay(routingConfigurationService);
-
-        // Call the processRouteUpdates() method in Router class
-        RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
-                                                  routeEntry);
-        router.processRouteUpdates(Collections.singletonList(routeUpdate));
-
-        // Verify
-        assertEquals(1, router.getRoutes4().size());
-        assertTrue(router.getRoutes4().contains(routeEntry));
-        verify(fibListener);
-    }
-
-    /**
-     * Tests adding a IPv6 route whose next hop is the local BGP speaker.
-     */
-    @Test
-    public void testIpv6LocalRouteAdd() {
-        // Construct a route entry, the next hop is the local BGP speaker
-        RouteEntry routeEntry = new RouteEntry(
-                Ip6Prefix.valueOf("4000::/64"),
-                Ip6Address.valueOf("::"));
-
-        // No methods on the FIB listener should be called
-        replay(fibListener);
-
-        reset(routingConfigurationService);
-        expect(routingConfigurationService.isIpPrefixLocal(
-                anyObject(IpPrefix.class))).andReturn(true);
-        replay(routingConfigurationService);
-
-        // Call the processRouteUpdates() method in Router class
-        RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE,
-                                                  routeEntry);
-        router.processRouteUpdates(Collections.singletonList(routeUpdate));
-
-        // Verify
-        assertEquals(1, router.getRoutes6().size());
-        assertTrue(router.getRoutes6().contains(routeEntry));
-        verify(fibListener);
-    }
-}
