diff --git a/src/main/java/net/onrc/onos/apps/sdnip/ISdnIpService.java b/src/main/java/net/onrc/onos/apps/sdnip/ISdnIpService.java
index 6189aa7..a2abaa1 100644
--- a/src/main/java/net/onrc/onos/apps/sdnip/ISdnIpService.java
+++ b/src/main/java/net/onrc/onos/apps/sdnip/ISdnIpService.java
@@ -52,5 +52,6 @@
     /**
      * Start SDN-IP Routing.
      */
-    public void beginRoutingNew();
+    public void beginRouting();
+
 }
diff --git a/src/main/java/net/onrc/onos/apps/sdnip/Prefix.java b/src/main/java/net/onrc/onos/apps/sdnip/Prefix.java
index d4e730d..81010d6 100644
--- a/src/main/java/net/onrc/onos/apps/sdnip/Prefix.java
+++ b/src/main/java/net/onrc/onos/apps/sdnip/Prefix.java
@@ -192,6 +192,16 @@
         return Arrays.copyOf(address, address.length);
     }
 
+    /**
+     * Gets the InetAddress.
+     *
+     * @return the inetAddress
+     */
+    public InetAddress getInetAddress() {
+        return inetAddress;
+    }
+
+
     @Override
     public boolean equals(Object other) {
         if (!(other instanceof Prefix)) {
diff --git a/src/main/java/net/onrc/onos/apps/sdnip/SdnIp.java b/src/main/java/net/onrc/onos/apps/sdnip/SdnIp.java
index d6713d5..35c3eaa 100644
--- a/src/main/java/net/onrc/onos/apps/sdnip/SdnIp.java
+++ b/src/main/java/net/onrc/onos/apps/sdnip/SdnIp.java
@@ -6,25 +6,25 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 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 net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.IOFSwitch.PortChangeType;
-import net.floodlightcontroller.core.IOFSwitchListener;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.module.FloodlightModuleException;
 import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.restserver.IRestApiService;
 import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.api.newintent.IntentService;
+import net.onrc.onos.api.newintent.MultiPointToSinglePointIntent;
 import net.onrc.onos.apps.proxyarp.IArpRequester;
 import net.onrc.onos.apps.proxyarp.IProxyArpService;
 import net.onrc.onos.apps.sdnip.RibUpdate.Operation;
@@ -36,8 +36,13 @@
 import net.onrc.onos.core.intent.runtime.IPathCalcRuntimeService;
 import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryService;
 import net.onrc.onos.core.main.config.IConfigInfoService;
+import net.onrc.onos.core.matchaction.action.ModifyDstMacAction;
+import net.onrc.onos.core.matchaction.match.PacketMatch;
+import net.onrc.onos.core.matchaction.match.PacketMatchBuilder;
+import net.onrc.onos.core.newintent.IdBlockAllocatorBasedIntentIdGenerator;
 import net.onrc.onos.core.registry.IControllerRegistryService;
 import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.IPv4;
 import net.onrc.onos.core.util.PortNumber;
 import net.onrc.onos.core.util.SwitchPort;
 import net.sf.json.JSONArray;
@@ -49,7 +54,6 @@
 import org.codehaus.jackson.JsonParseException;
 import org.codehaus.jackson.map.JsonMappingException;
 import org.codehaus.jackson.map.ObjectMapper;
-import org.projectfloodlight.openflow.protocol.OFPortDesc;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -63,12 +67,15 @@
 import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree;
 import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
 
+/**
+ * This class sets up BGP paths, handles RIB updates and relative intents.
+ * TODO: Thread-safe.
+ */
 public class SdnIp implements IFloodlightModule, ISdnIpService,
-        IArpRequester, IOFSwitchListener, IConfigInfoService {
+        IArpRequester, IConfigInfoService {
 
     private static final Logger log = LoggerFactory.getLogger(SdnIp.class);
 
-    private IFloodlightProviderService floodlightProvider;
     private ILinkDiscoveryService linkDiscoveryService;
     private IRestApiService restApi;
     private IProxyArpService proxyArp;
@@ -86,31 +93,13 @@
     /* ShortestPath Intent Variables */
     private final String caller = "SdnIp";
     private IControllerRegistryService controllerRegistryService;
+    private IntentService intentService;
     private IPathCalcRuntimeService pathRuntime;
     /* Shortest Intent Path Variables */
+    private IdBlockAllocatorBasedIntentIdGenerator intentIdGenerator;
+    //private static final short ARP_PRIORITY = 20;
 
-    private static final short ARP_PRIORITY = 20;
-
-    // The fields below are unused after the move to FlowManager.
-    // Remove them if no longer needed.
-    /*
-    // We need to identify our flows somehow, in lieu of an OS-wide mechanism
-    // to hand out cookie IDs to prevent conflicts.
-    private static final long APP_COOKIE = 0xa0000000000000L;
-    // Cookie for flows that do L2 forwarding within SDN domain to egress routers
-    private static final long L2_FWD_COOKIE = APP_COOKIE + 1;
-    // Cookie for flows in ingress switches that rewrite the MAC address
-    private static final long MAC_RW_COOKIE = APP_COOKIE + 2;
-    // Cookie for flows that setup BGP paths
-    private static final long BGP_COOKIE = APP_COOKIE + 3;
-    // Forwarding uses priority 0, and the mac rewrite entries in ingress switches
-    // need to be higher priority than this otherwise the rewrite may not get done
-    private static final short SDNIP_PRIORITY = 10;
-    */
-
-    private static final short BGP_PORT = 179;
-
-    private static final int TOPO_DETECTION_WAIT = 2; // seconds
+    //private static final short BGP_PORT = 179;
 
     // Configuration stuff
     private List<String> switches;
@@ -120,70 +109,18 @@
     private MACAddress bgpdMacAddress;
     private short vlan;
 
-    // True when all switches have connected
-    private volatile boolean switchesConnected = false;
-    // True when we have a full mesh of shortest paths between gateways
-    private volatile boolean topologyReady = false;
-
-    // private SingletonTask topologyChangeDetectorTask;
-
     private SetMultimap<InetAddress, RibUpdate> prefixesWaitingOnArp;
 
-    private Map<InetAddress, Path> pathsWaitingOnArp;
-
     private ExecutorService bgpUpdatesExecutor;
 
-    private Map<InetAddress, Path> pushedPaths;
-    private Map<Prefix, Path> prefixToPath;
-    // private Multimap<Prefix, PushedFlowMod> pushedFlows;
-    //private Multimap<Prefix, FlowId> pushedFlowIds;
+    private ConcurrentHashMap<Prefix, MultiPointToSinglePointIntent> pushedRouteIntents;
 
-    // XXX FlowCache has been removed
-    //private FlowCache flowCache;
-
-    // TODO: Fix for the new Topology Network Graph
-    // private volatile Topology topology = null;
-
-    /*
-    private class TopologyChangeDetector implements Runnable {
-        @Override
-        public void run() {
-            log.debug("Running topology change detection task");
-            // TODO: Fix the code below after topoLinkService was removed
-            synchronized (linkUpdates) {
-
-                ITopoLinkService topoLinkService = new TopoLinkServiceImpl();
-
-                List<Link> activeLinks = topoLinkService.getActiveLinks();
-
-                Iterator<LDUpdate> it = linkUpdates.iterator();
-                while (it.hasNext()){
-                    LDUpdate ldu = it.next();
-                    Link l = new Link(ldu.getSrc(), ldu.getSrcPort(),
-                            ldu.getDst(), ldu.getDstPort());
-
-                    if (activeLinks.contains(l)){
-                        it.remove();
-                    }
-                }
-            }
-
-            if (!topologyReady) {
-                if (linkUpdates.isEmpty()) {
-                    // All updates have been seen in network map.
-                    // We can check if topology is ready
-                    log.debug("No known changes outstanding. Checking topology now");
-                    checkStatus();
-                } else {
-                    // We know of some link updates that haven't propagated to the database yet
-                    log.debug("Some changes not found in network map - {} links missing", linkUpdates.size());
-                    topologyChangeDetectorTask.reschedule(TOPO_DETECTION_WAIT, TimeUnit.SECONDS);
-                }
-            }
-        }
-    }
-    */
-
+    /**
+     * SDN-IP application has a configuration file. This method is to read all
+     * the info from this file.
+     *
+     * @param configFilename the name of configuration file for SDN-IP application
+     */
     private void readConfiguration(String configFilename) {
         File gatewaysFile = new File(configFilename);
         ObjectMapper mapper = new ObjectMapper();
@@ -215,7 +152,7 @@
             throw new ConfigurationRuntimeException("Error in JSON file", e);
         }
 
-        // Populate the interface Patricia Tree
+        // Populate the interface InvertedRadixTree
         for (Interface intf : interfaces.values()) {
             Prefix prefix = new Prefix(intf.getIpAddress().getAddress(),
                     intf.getPrefixLength());
@@ -242,7 +179,6 @@
     @Override
     public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
         Collection<Class<? extends IFloodlightService>> l = new ArrayList<>();
-        l.add(IFloodlightProviderService.class);
         l.add(IRestApiService.class);
         l.add(IControllerRegistryService.class);
         l.add(IPathCalcRuntimeService.class);
@@ -260,30 +196,23 @@
 
         ribUpdates = new LinkedBlockingQueue<>();
 
-        // Register floodlight provider and REST handler.
-        floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
-        linkDiscoveryService = context.getServiceImpl(ILinkDiscoveryService.class);
+        // Register REST handler.
         restApi = context.getServiceImpl(IRestApiService.class);
         proxyArp = context.getServiceImpl(IProxyArpService.class);
 
         controllerRegistryService = context
                 .getServiceImpl(IControllerRegistryService.class);
-        pathRuntime = context.getServiceImpl(IPathCalcRuntimeService.class);
 
-        // ScheduledExecutorService executor =
-        // Executors.newScheduledThreadPool(1);
-        // topologyChangeDetectorTask = new SingletonTask(executor, new
-        // TopologyChangeDetector());
+        intentIdGenerator = new IdBlockAllocatorBasedIntentIdGenerator(
+                controllerRegistryService);
 
-        pathsWaitingOnArp = new HashMap<>();
+        // TODO: initialize intentService
+
+        pushedRouteIntents = new ConcurrentHashMap<>();
+
         prefixesWaitingOnArp = Multimaps.synchronizedSetMultimap(
                 HashMultimap.<InetAddress, RibUpdate>create());
 
-        pushedPaths = new HashMap<>();
-        prefixToPath = new HashMap<>();
-        // pushedFlows = HashMultimap.<Prefix, PushedFlowMod>create();
-        // pushedFlowIds = HashMultimap.create();
-
         //flowCache = new FlowCache(floodlightProvider);
 
         bgpUpdatesExecutor = Executors.newSingleThreadExecutor(
@@ -321,7 +250,6 @@
     public void startUp(FloodlightModuleContext context) {
         restApi.addRestletRoutable(new SdnIpWebRoutable());
         restApi.addRestletRoutable(new SdnIpWebRoutableNew());
-        floodlightProvider.addOFSwitchListener(this);
 
         // Retrieve the RIB from BGPd during startup
         retrieveRib();
@@ -347,6 +275,12 @@
         return routerId;
     }
 
+    /**
+     * SDN-IP application will fetch all rib entries from BGPd when it starts.
+     * Especially when we restart SDN-IP application while the BGPd has been
+     * running all the time. Then before SDN-IP application re-connects to BGPd,
+     * there are already lots of rib entries in BGPd.
+     */
     private void retrieveRib() {
         String url = "http://" + bgpdRestIp + "/wm/bgp/" + routerId;
         String response = RestClient.get(url);
@@ -400,6 +334,11 @@
         }
     }
 
+    /**
+     * Put RIB update to RIB update queue.
+     *
+     * @param update RIB update
+     */
     @Override
     public void newRibUpdate(RibUpdate update) {
         try {
@@ -410,6 +349,15 @@
         }
     }
 
+    /**
+     * Process adding RIB update.
+     * Put new RIB update into InvertedRadixTree. If there was an existing nexthop
+     * for this prefix, but the next hop was different, then execute deleting old
+     * RIB update. If the next hop is the SDN domain, we do not handle it at the
+     * moment. Otherwise, execute adding RIB.
+     *
+     * @param update RIB update
+     */
     private void processRibAdd(RibUpdate update) {
         synchronized (this) {
             Prefix prefix = update.getPrefix();
@@ -420,10 +368,9 @@
 
             if (rib != null && !rib.equals(update.getRibEntry())) {
                 // There was an existing nexthop for this prefix. This update
-                // supersedes that,
-                // so we need to remove the old flows for this prefix from the
-                // switches
-                executeDeletePrefix(prefix, rib);
+                // supersedes that, so we need to remove the old flows for this
+                // prefix from the switches
+                executeDeleteRoute(prefix, rib);
             }
 
             if (update.getRibEntry().getNextHop().equals(
@@ -439,405 +386,157 @@
         }
     }
 
+    /**
+     * Execute adding RIB update.
+     * Find out the egress Interface and MAC address of next hop router for this
+     * RIB update. If the MAC address can not be found in ARP cache, then this
+     * prefix will be put in prefixesWaitingOnArp queue. Otherwise, new flow
+     * intent will be created and installed.
+     *
+     * @param update RIB update
+     */
     private void executeRibAdd(RibUpdate update) {
-        // TODO: Fix the code below. Note that "deviceStorage" was removed.
 
-        /*
         Prefix prefix = update.getPrefix();
         RibEntry rib = update.getRibEntry();
 
-        InetAddress dstIpAddress = rib.getNextHop();
-        MACAddress nextHopMacAddress = null;
-
-        // See if we know the MAC address of the next hop
-        // TODO if we do not treat the next hop as a device in the future, we need to update this
-        IDeviceObject nextHopDevice =
-                deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(dstIpAddress));
-
-        if (nextHopDevice == null){
-            log.debug("NextHopDevice for IP: {} is null", dstIpAddress);
-            prefixesWaitingOnArp.put(dstIpAddress,
-                    new RibUpdate(Operation.UPDATE, prefix, rib));
-            proxyArp.sendArpRequest(dstIpAddress, this, true);
-            return;
-
-        }
-        nextHopMacAddress = MACAddress.valueOf(nextHopDevice.getMACAddress());
+        InetAddress nextHopIpAddress = rib.getNextHop();
 
         // Find the attachment point (egress interface) of the next hop
         Interface egressInterface = null;
-        if (bgpPeers.containsKey(dstIpAddress)) {
-            //Route to a peer
-            log.debug("Route to peer {}", dstIpAddress);
-            BgpPeer peer = bgpPeers.get(dstIpAddress);
+
+        if (bgpPeers.containsKey(nextHopIpAddress)) {
+            // Route to a peer
+            log.debug("Route to peer {}", nextHopIpAddress);
+            BgpPeer peer = bgpPeers.get(nextHopIpAddress);
             egressInterface = interfaces.get(peer.getInterfaceName());
         } else {
-            //Route to non-peer
-            log.debug("Route to non-peer {}", dstIpAddress);
-            egressInterface = interfacePtree.match(
-                    new Prefix(dstIpAddress.getAddress(), 32));
+            // Route to non-peer
+            log.debug("Route to non-peer {}", nextHopIpAddress);
+            egressInterface = getOutgoingInterface(nextHopIpAddress);
             if (egressInterface == null) {
-                log.warn("No outgoing interface found for {}", dstIpAddress.getHostAddress());
+                log.warn("No outgoing interface found for {}", nextHopIpAddress
+                        .getHostAddress());
                 return;
             }
         }
 
+        // See if we know the MAC address of the next hop
+        MACAddress nextHopMacAddress = proxyArp.getMacAddress(nextHopIpAddress);
+
         if (nextHopMacAddress == null) {
-            prefixesWaitingOnArp.put(dstIpAddress,
+            prefixesWaitingOnArp.put(nextHopIpAddress,
                     new RibUpdate(Operation.UPDATE, prefix, rib));
-            proxyArp.sendArpRequest(dstIpAddress, this, true);
+            proxyArp.sendArpRequest(nextHopIpAddress, this, true);
             return;
         } else {
-            if (!bgpPeers.containsKey(dstIpAddress)) {
-                //If the prefix is for a non-peer we need to ensure there's a path,
-                //and push one if there isn't.
-                Path path = pushedPaths.get(dstIpAddress);
-                if (path == null) {
-                    path = new Path(egressInterface, dstIpAddress);
-                    calculateAndPushPath(path, nextHopMacAddress);
-                    pushedPaths.put(dstIpAddress, path);
-                }
 
-                path.incrementUsers();
-                prefixToPath.put(prefix, path);
-            }
+            //For all prefixes we need to add a intent for each of them
+            addRouteIntent(prefix, egressInterface, nextHopMacAddress);
 
-            //For all prefixes we need to add the first-hop mac-rewriting flows
-            addPrefixFlows(prefix, egressInterface, nextHopMacAddress);
         }
-        */
+
     }
 
     /**
-     * Add a flow to match dst-IP prefix and rewrite MAC for one IP prefix to
-     * all other border switches.
+     * Install a flow intent for a prefix.
+     * Intent will match dst IP prefix and rewrite dst MAC address at all other
+     * border switches, then forward packets according to dst MAC address.
+     *
+     * @param prefix IP prefix from BGP route
+     * @param egressInterface egress Interface connected to next hop router
+     * @param nextHopMacAddress MAC address of next hop router
      */
-    private void addPrefixFlows(Prefix prefix, Interface egressInterface,
+    private void addRouteIntent(Prefix prefix, Interface egressInterface,
             MACAddress nextHopMacAddress) {
-        log.debug("Adding flows for prefix {}, next hop mac {}",
+        log.debug("Adding intent for prefix {}, next hop mac {}",
                 prefix, nextHopMacAddress);
 
-        /*
-        FlowPath flowPath = new FlowPath();
-        flowPath.setInstallerId(callerId);
+        MultiPointToSinglePointIntent pushedIntent = pushedRouteIntents.get(prefix);
 
-        // Set flowPath FlowPathType and FlowPathUserState
-        flowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
-        flowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
+        // Just for testing.
+        if (pushedIntent != null) {
+            log.error("There should not be a pushed intent: {}", pushedIntent);
+        }
 
-        // Insert dst-ip prefix based forwarding and MAC rewrite flow entry
-        // only to the first-host switches
-        FlowPathFlags flowPathFlags = new FlowPathFlags();
-        flowPathFlags.setFlags(FlowPathFlags.KEEP_ONLY_FIRST_HOP_ENTRY);
-        flowPath.setFlowPathFlags(flowPathFlags);
+        SwitchPort egressPort = egressInterface.getSwitchPort();
 
-        // Create the DataPath object: dstSwitchPort
-        SwitchPort dstPort =
-                new SwitchPort(new Dpid(egressInterface.getDpid()),
-                        new PortNumber(egressInterface.getPort()));
+        Set<SwitchPort> ingressPorts = new HashSet<SwitchPort>();
 
-        // We only need one flow mod per switch, so pick one interface on each
-        // switch
-        Map<Long, Interface> srcInterfaces = new HashMap<>();
         for (Interface intf : interfaces.values()) {
-            if (!srcInterfaces.containsKey(intf.getDpid())
-                    && !intf.equals(egressInterface)) {
-                srcInterfaces.put(intf.getDpid(), intf);
+            if (!intf.equals(egressInterface)) {
+                SwitchPort srcPort = intf.getSwitchPort();
+                ingressPorts.add(srcPort);
             }
         }
-        for (Interface srcInterface : srcInterfaces.values()) {
 
-            if (egressInterface.equals(srcInterface)) {
-                continue;
-            }
+        // Match the destination IP prefix at the first hop
+        PacketMatchBuilder builder = new PacketMatchBuilder();
+        builder.setDstIp(new IPv4(InetAddresses
+                .coerceToInteger(prefix.getInetAddress())),
+                (short) prefix.getPrefixLength());
+        PacketMatch packetMatch = builder.build();
 
-            // Create flowPath FlowId
-            flowPath.setFlowId(new FlowId());
+        // Rewrite the destination MAC address
+        ModifyDstMacAction modifyDstMacAction =
+                new ModifyDstMacAction(nextHopMacAddress);
 
-            // Create DataPath object: srcSwitchPort
-            SwitchPort srcPort =
-                    new SwitchPort(new Dpid(srcInterface.getDpid()),
-                            new PortNumber(srcInterface.getPort()));
+        MultiPointToSinglePointIntent intent =
+                new MultiPointToSinglePointIntent(intentIdGenerator.getNewId(),
+                        packetMatch, modifyDstMacAction, ingressPorts, egressPort);
 
-            DataPath dataPath = new DataPath();
-            dataPath.setSrcPort(srcPort);
-            dataPath.setDstPort(dstPort);
-            flowPath.setDataPath(dataPath);
+        intentService.submit(intent);
 
-            // Create flow path matching condition(s): IPv4 Prefix
-            FlowEntryMatch flowEntryMatch = new FlowEntryMatch();
-            flowEntryMatch.enableEthernetFrameType(Ethernet.TYPE_IPV4);
-            IPv4Net dstIPv4Net = new IPv4Net(prefix.toString());
-            flowEntryMatch.enableDstIPv4Net(dstIPv4Net);
-            flowPath.setFlowEntryMatch(flowEntryMatch);
-
-             *
-             * Create the Flow Entry Action(s): dst-MAC rewrite action
-             *
-            FlowEntryActions flowEntryActions = new FlowEntryActions();
-            FlowEntryAction flowEntryAction1 = new FlowEntryAction();
-            flowEntryAction1.setActionSetEthernetDstAddr(nextHopMacAddress);
-            // flowEntryAction1.actionSetEthernetDstAddr(nextHopMacAddress);
-            flowEntryActions.addAction(flowEntryAction1);
-            flowPath.setFlowEntryActions(flowEntryActions);
-
-            // Flow Path installation, only to first hop switches
-            // TODO: Add the flow by using the new Path Intent framework
-            /*
-            if (flowManagerService.addFlow(flowPath) == null) {
-                log.error("Failed to install flow path to the first hop for " +
-                        "prefix: {}, nextHopMacAddress: {}", prefix.getAddress(),
-                        nextHopMacAddress);
-            }
-            else {
-                log.debug("Successfully installed flow path to the first hop " +
-                        "for prefix: {}, nextHopMacAddress: {}", prefix.getAddress(),
-                        nextHopMacAddress);
-
-                pushedFlowIds.put(prefix, flowPath.flowId());
-            }
-
-        }
-        */
+        // Maintain the Intent
+        pushedRouteIntents.put(prefix, intent);
     }
 
+    /**
+     * Remove prefix from InvertedRadixTree, if success, then try to delete the
+     * relative intent.
+     *
+     * @param update RIB update
+     */
     private void processRibDelete(RibUpdate update) {
         synchronized (this) {
             Prefix prefix = update.getPrefix();
 
             // if (ptree.remove(prefix, update.getRibEntry())) {
+
             // TODO check the change of logic here - remove doesn't check that
-            // the
-            // rib entry was what we expected (and we can't do this
+            // the rib entry was what we expected (and we can't do this
             // concurrently)
+
             if (bgpRoutes.remove(prefix.toBinaryString())) {
                 /*
                  * Only delete flows 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
                  */
-                executeDeletePrefix(prefix, update.getRibEntry());
+                executeDeleteRoute(prefix, update.getRibEntry());
+
             }
         }
     }
 
-    private void executeDeletePrefix(Prefix prefix, RibEntry ribEntry) {
-        deletePrefixFlows(prefix);
-
-        log.debug("Deleting {} to {}", prefix, ribEntry.getNextHop());
-
-        if (!bgpPeers.containsKey(ribEntry.getNextHop())) {
-            log.debug("Getting path for route with non-peer nexthop");
-            Path path = prefixToPath.remove(prefix);
-
-            if (path != null) {
-                // path could be null if we added to the Ptree but didn't push
-                // flows yet because we were waiting to resolve ARP
-
-                path.decrementUsers();
-                if (path.getUsers() <= 0 && !path.isPermanent()) {
-                    deletePath(path);
-                    pushedPaths.remove(path.getDstIpAddress());
-                }
-            }
-        }
-    }
-
-    // TODO have not tested this module
-    private void deletePrefixFlows(Prefix prefix) {
-        log.debug("Deleting flows for prefix {}", prefix);
-
-        //
-        // TODO: Delete the flow by using the new Path Intent framework
-        // NOTE: During the refactoring of the code below, if obtaining
-        // the values of the removed flowIds is needed, the first
-        // removeAll() statement should be replaced with the second removeAll()
-        // statement.
-        //
-        // pushedFlowIds.removeAll(prefix);
-        /*
-        Collection<FlowId> flowIds = pushedFlowIds.removeAll(prefix);
-        for (FlowId flowId : flowIds) {
-            if (log.isTraceEnabled()) {
-                //Trace the flow status by flowPath in the switch before deleting it
-                log.trace("Pushing a DELETE flow mod to flowPath : {}",
-                        flowManagerService.getFlow(flowId).toString());
-            }
-
-            if( flowManagerService.deleteFlow(flowId))
-            {
-                log.debug("Successfully deleted FlowId: {}",flowId);
-            }
-            else
-            {
-                log.debug("Failed to delete FlowId: {}",flowId);
-            }
-        }
-        */
-    }
-
-    // TODO need to record the path and then delete here
-    private void deletePath(Path path) {
-        log.debug("Deleting flows for path to {}",
-                path.getDstIpAddress().getHostAddress());
-
-        // TODO need update
-        /*for (PushedFlowMod pfm : path.getFlowMods()) {
-            if (log.isTraceEnabled()) {
-                log.trace("Pushing a DELETE flow mod to {}, dst MAC {}",
-                        new Object[] {HexString.toHexString(pfm.getDpid()),
-                        HexString.toHexString(pfm.getFlowMod().getMatch().getDataLayerDestination())
-                });
-            }
-
-            sendDeleteFlowMod(pfm.getFlowMod(), pfm.getDpid());
-        }*/
-    }
-
-    // TODO test next-hop changes
-    // TODO check delete/add synchronization
-
     /**
-     * On startup, we need to calculate a full mesh of paths between all gateway
-     * switches.
+     * Delete prefix intent installed.
+     *
+     * @param prefix IP prefix withdrew in a rib update announcement
+     * @param ribEntry next hop information
      */
-    private void setupFullMesh() {
-        // TODO: Fix the code below. Note that "deviceStorage" was removed.
+    private void executeDeleteRoute(Prefix prefix, RibEntry ribEntry) {
+        log.debug("Deleting {} to {}", prefix, ribEntry.getNextHop());
 
-        /*
+        MultiPointToSinglePointIntent intent = pushedRouteIntents.remove(prefix);
 
-        //For each border router, calculate and install a path from every other
-        //border switch to said border router. However, don't install the entry
-        //in to the first hop switch, as we need to install an entry to rewrite
-        //for each prefix received. This will be done later when prefixes have
-        //actually been received.
-
-        for (BgpPeer peer : bgpPeers.values()) {
-            Interface peerInterface = interfaces.get(peer.getInterfaceName());
-
-            //We know there's not already a Path here pushed, because this is
-            //called before all other routing
-            Path path = new Path(peerInterface, peer.getIpAddress());
-            path.setPermanent();
-
-            //See if we know the MAC address of the peer. If not we can't
-            //do anything until we learn it
-            MACAddress macAddress = null;
-            IDeviceObject nextHopDevice =
-                    deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(peer.getIpAddress()));
-
-            if(nextHopDevice == null){
-                log.debug("There is no DeviceObject for {}", peer.getIpAddress().getHostAddress());
-                //Put in the pending paths list first
-                pathsWaitingOnArp.put(peer.getIpAddress(), path);
-                proxyArp.sendArpRequest(peer.getIpAddress(), this, true);
-                continue;
-            }
-
-            macAddress = MACAddress.valueOf(nextHopDevice.getMACAddress());
-
-            if (macAddress == null) {
-                log.debug("Don't know MAC for {}", peer.getIpAddress().getHostAddress());
-                //Put in the pending paths list first
-                pathsWaitingOnArp.put(peer.getIpAddress(), path);
-                proxyArp.sendArpRequest(peer.getIpAddress(), this, true);
-                continue;
-            }
-
-            //If we know the MAC, lets go ahead and push the paths to this peer
-            calculateAndPushPath(path, macAddress);
+        if (intent == null) {
+            log.debug("There is no intent in pushedRouteIntents to delete for " +
+                    "prefix: {}", prefix);
+        } else {
+            intentService.withdraw(intent);
+            log.debug("Deleted the pushedRouteIntent for prefix: {}", prefix);
         }
-        */
-    }
-
-    private void calculateAndPushPath(Path path, MACAddress dstMacAddress) {
-        // Interface dstInterface = path.getDstInterface();
-
-        log.debug("Setting up path to {}, {}", path.getDstIpAddress().getHostAddress(),
-                dstMacAddress);
-
-        /*
-        FlowPath flowPath = new FlowPath();
-
-        flowPath.setInstallerId(callerId);
-
-        // Set flowPath FlowPathType and FlowPathUserState
-        flowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
-        flowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
-
-        // Insert the dest-mac based forwarding flow entry to the non-first-hop
-        // switches
-        FlowPathFlags flowPathFlags = new FlowPathFlags();
-        flowPathFlags.setFlags(FlowPathFlags.DISCARD_FIRST_HOP_ENTRY);
-        flowPath.setFlowPathFlags(flowPathFlags);
-
-        // Create the DataPath object: dstSwitchPort
-        SwitchPort dstPort =
-                new SwitchPort(new Dpid(dstInterface.getDpid()),
-                        new PortNumber(dstInterface.getPort()));
-
-        for (Interface srcInterface : interfaces.values()) {
-
-            if (dstInterface.equals(srcInterface)) {
-                continue;
-            }
-
-            // Create flowPath FlowId
-            flowPath.setFlowId(new FlowId());
-
-            // Create the DataPath object: srcSwitchPort
-            SwitchPort srcPort =
-                    new SwitchPort(new Dpid(srcInterface.getDpid()),
-                            new PortNumber(srcInterface.getPort()));
-
-            DataPath dataPath = new DataPath();
-            dataPath.setSrcPort(srcPort);
-            dataPath.setDstPort(dstPort);
-            flowPath.setDataPath(dataPath);
-
-            // Create the Flow Path Match condition(s)
-            FlowEntryMatch flowEntryMatch = new FlowEntryMatch();
-            flowEntryMatch.enableEthernetFrameType(Ethernet.TYPE_IPV4);
-            flowEntryMatch.enableDstMac(dstMacAddress);
-            flowPath.setFlowEntryMatch(flowEntryMatch);
-
-            // NOTE: No need to add ACTION_OUTPUT. It is implied when creating
-            // Shortest Path Flow, and is always the last action for the Flow
-            // Entries
-            log.debug("FlowPath of MAC based forwarding: {}", flowPath.toString());
-            // TODO: Add the flow by using the new Path Intent framework
-
-            if (flowManagerService.addFlow(flowPath) == null) {
-                log.error("Failed to set up MAC based forwarding path to {}, {}",
-                        path.getDstIpAddress().getHostAddress(),dstMacAddress);
-            }
-            else {
-                log.debug("Successfully set up MAC based forwarding path to {}, {}",
-                        path.getDstIpAddress().getHostAddress(),dstMacAddress);
-            }
-
-        }
-        */
-    }
-
-    @Override
-    public void beginRoutingNew() {
-        setupBgpPathsNew();
-
-        // setupFullMesh();
-
-        // Suppress link discovery on external-facing router ports
-
-        for (Interface intf : interfaces.values()) {
-            linkDiscoveryService.disableDiscoveryOnPort(intf.getDpid(), intf.getPort());
-        }
-
-        bgpUpdatesExecutor.execute(new Runnable() {
-            @Override
-            public void run() {
-                doUpdatesThread();
-            }
-        });
     }
 
     /**
@@ -847,7 +546,7 @@
      * srcPort, long srcMac, int srcIP, long dstSwitch, long dstPort, long
      * dstMac, int dstIP
      */
-    private void setupBgpPathsNew() {
+    private void setupBgpPaths() {
         IntentOperationList operations = new IntentOperationList();
         for (BgpPeer bgpPeer : bgpPeers.values()) {
             Interface peerInterface = interfaces.get(bgpPeer.getInterfaceName());
@@ -861,9 +560,14 @@
             SwitchPort srcPort =
                     new SwitchPort(bgpdAttachmentPoint.getDpid(),
                             bgpdAttachmentPoint.getPortNumber());
+            // TODO: replace the code below with peerInterface.getSwitchPort()
+            // when using poingToPointIntent
             SwitchPort dstPort =
                     new SwitchPort(new Dpid(peerInterface.getDpid()),
                             new PortNumber(peerInterface.getSwitchPort().getPortNumber()));
+
+            // TODO: add TCP port number 179 into intent for BGP
+
             ShortestPathIntent fwdIntent = new ShortestPathIntent(fwdIntentId,
                     srcPort.getDpid().value(), srcPort.getPortNumber().value(),
                     ShortestPathIntent.EMPTYMACADDRESS, srcIP,
@@ -881,41 +585,26 @@
         pathRuntime.executeIntentOperations(operations);
     }
 
+    /**
+     * This method handles the prefixes which are waiting for ARP replies for
+     * MAC addresses of next hops.
+     *
+     * @param ipAddress next hop router IP address, for which we sent ARP request out
+     * @param macAddress MAC address which is relative to the ipAddress
+     */
     @Override
     public void arpResponse(InetAddress ipAddress, MACAddress macAddress) {
         log.debug("Received ARP response: {} => {}",
                 ipAddress.getHostAddress(), macAddress);
 
         /*
-         * We synchronize on this to prevent changes to the ptree while we're pushing
-         * flows to the switches. If the ptree changes, the ptree and switches
-         * could get out of sync.
+         * We synchronize on this to prevent changes to the InvertedRadixTree
+         * while we're pushing intent. If the InvertedRadixTree changes, the
+         * InvertedRadixTree and intent could get out of sync.
          */
         synchronized (this) {
-            Path path = pathsWaitingOnArp.remove(ipAddress);
 
-            if (path != null) {
-                log.debug("Pushing path to {} at {} on {}",
-                        path.getDstIpAddress().getHostAddress(), macAddress,
-                        path.getDstInterface().getSwitchPort());
-                // These paths should always be to BGP peers. Paths to non-peers
-                // are
-                // handled once the first prefix is ready to push
-                if (pushedPaths.containsKey(path.getDstIpAddress())) {
-                    // A path already got pushed to this endpoint while we were
-                    // waiting
-                    // for ARP. We'll copy over the permanent attribute if it is
-                    // set on this path.
-                    if (path.isPermanent()) {
-                        pushedPaths.get(path.getDstIpAddress()).setPermanent();
-                    }
-                } else {
-                    calculateAndPushPath(path, macAddress);
-                    pushedPaths.put(path.getDstIpAddress(), path);
-                }
-            }
-
-            Set<RibUpdate> prefixesToPush = prefixesWaitingOnArp.removeAll(ipAddress);
+          Set<RibUpdate> prefixesToPush = prefixesWaitingOnArp.removeAll(ipAddress);
 
             for (RibUpdate update : prefixesToPush) {
                 // These will always be adds
@@ -926,22 +615,20 @@
                     log.debug("Pushing prefix {} next hop {}", update.getPrefix(),
                             rib.getNextHop().getHostAddress());
                     // We only push prefix flows if the prefix is still in the
-                    // ptree
-                    // and the next hop is the same as our update. The prefix
-                    // could
-                    // have been removed while we were waiting for the ARP, or
-                    // the
-                    // next hop could have changed.
+                    // InvertedRadixTree and the next hop is the same as our update.
+                    // The prefix could have been removed while we were waiting
+                    // for the ARP, or the next hop could have changed.
                     executeRibAdd(update);
                 } else {
-                    log.debug("Received ARP response, but {},{} is no longer in ptree",
-                            update.getPrefix(), update.getRibEntry());
+                    log.debug("Received ARP response, but {},{} is no longer in " +
+                            "InvertedRadixTree", update.getPrefix(),
+                            update.getRibEntry());
                 }
             }
         }
     }
 
-    // XXX OpenFlow message classes have been removed
+
     /*private void setupArpFlows() {
         OFMatch match = new OFMatch();
         match.setDataLayerType(Ethernet.TYPE_ARP);
@@ -1027,17 +714,18 @@
         }
     }*/
 
-    private void beginRouting() {
+    /**
+     * The SDN-IP application is started from this method.
+     */
+    @Override
+    public void beginRouting() {
         log.debug("Topology is now ready, beginning routing function");
-        // TODO: Fix for the new Topology Network Graph
-        // topology = topologyNetService.newDatabaseTopology();
 
-        // Wait Pavlin's API. We need the following functions.
+        // TODO
         /*setupArpFlows();
         setupDefaultDropFlows();*/
 
-        //setupBgpPaths();
-        setupFullMesh();
+        setupBgpPaths();
 
         // Suppress link discovery on external-facing router ports
         for (Interface intf : interfaces.values()) {
@@ -1052,69 +740,9 @@
         });
     }
 
-    // Before inserting the paths for BGP traffic, we should check whether
-    // all the switches in the configuration file are discovered by ONOS
-    private void checkSwitchesConnected() {
-        // TODO: Fix the code below after topoSwitchSerice was removed
-        /*
-        for (String dpid : switches) {
-
-            Iterator<ISwitchObject> activeSwitches = topoSwitchService.
-                    getActiveSwitches().iterator();
-            while(activeSwitches.hasNext())
-            {
-                ISwitchObject switchObject = activeSwitches.next();
-                if (switchObject.getDPID().equals(dpid)) {
-                    break;
-                }
-                if(activeSwitches.hasNext() == false) {
-                    log.debug("Not all switches are here yet");
-                    return;
-                }
-            }
-        }
-        switchesConnected = true;
-        */
-    }
-
-    // Actually we only need to go half way round to verify full mesh
-    // connectivity
-    private void checkTopologyReady() {
-        for (Interface dstInterface : interfaces.values()) {
-            for (Interface srcInterface : interfaces.values()) {
-                if (dstInterface.equals(srcInterface)) {
-                    continue;
-                }
-
-                // TODO: Fix for the new Topology Network Graph
-                /*
-                DataPath shortestPath = topologyNetService.getDatabaseShortestPath(
-                        srcInterface.getSwitchPort(), dstInterface.getSwitchPort());
-
-                if (shortestPath == null){
-                    log.debug("Shortest path between {} and {} not found",
-                            srcInterface.getSwitchPort(), dstInterface.getSwitchPort());
-                    return;
-                }
-                */
-            }
-        }
-        topologyReady = true;
-    }
-
-    private void checkStatus() {
-        if (!switchesConnected) {
-            checkSwitchesConnected();
-        }
-        boolean oldTopologyReadyStatus = topologyReady;
-        if (switchesConnected && !topologyReady) {
-            checkTopologyReady();
-        }
-        if (!oldTopologyReadyStatus && topologyReady) {
-            beginRouting();
-        }
-    }
-
+    /**
+     * Thread for handling RIB updates.
+     */
     private void doUpdatesThread() {
         boolean interrupted = false;
         try {
@@ -1156,6 +784,12 @@
         }
     }
 
+    /**
+     * Judge whether a RIB update is in correct order.
+     *
+     * @param update RIB update
+     * @return boolean whether the RIB update is in in correct order
+     */
     private boolean validateUpdate(RibUpdate update) {
         RibEntry newEntry = update.getRibEntry();
         RibEntry oldEntry = bgpRoutes.getValueForExactKey(
@@ -1184,6 +818,13 @@
                 newEntry.getSequenceNum() > oldEntry.getSequenceNum();
     }
 
+    /**
+     * To find the Interface which has longest matchable IP prefix (sub-network
+     *  prefix) to next hop IP address.
+     *
+     * @param address the IP address of next hop router
+     * @return Interface the Interface which has longest matchable IP prefix
+     */
     private Interface longestInterfacePrefixMatch(InetAddress address) {
         Prefix prefixToSearchFor = new Prefix(address.getAddress(),
                 Prefix.MAX_PREFIX_LENGTH);
@@ -1199,90 +840,6 @@
         return intf;
     }
 
-    // The code below should be reimplemented after removal of Floodlight's
-    // ITopologyService API. It should be implemented on top of network graph
-    // notifications. (It was pretty hacky anyway...)
-    /*
-    @Override
-    public void topologyChanged() {
-        if (topologyReady) {
-            return;
-        }
-
-        boolean refreshNeeded = false;
-        for (LDUpdate ldu : topologyService.getLastLinkUpdates()){
-            if (!ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.LINK_UPDATED)){
-                //We don't need to recalculate anything for just link updates
-                //They happen very frequently
-                refreshNeeded = true;
-            }
-
-            log.debug("Topo change {}", ldu.getOperation());
-
-            if (ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.LINK_ADDED)){
-                synchronized (linkUpdates) {
-                    linkUpdates.add(ldu);
-                }
-            }
-        }
-
-        if (refreshNeeded && !topologyReady){
-            topologyChangeDetectorTask.reschedule(TOPO_DETECTION_WAIT, TimeUnit.SECONDS);
-        }
-    }
-    */
-
-    // ******************
-    // IOFSwitchListener
-    // ******************
-
-    @Override
-    public void switchActivatedMaster(long swId) {
-        IOFSwitch sw = floodlightProvider.getSwitch(swId);
-        if (sw == null) {
-            log.warn("Added switch not available {} ", swId);
-            return;
-        }
-        if (!topologyReady) {
-            sw.clearAllFlowMods();
-        }
-
-        //flowCache.switchConnected(sw);
-    }
-
-    @Override
-    public void switchActivatedEqual(long swId) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void switchMasterToEqual(long swId) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void switchEqualToMaster(long swId) {
-        // for now treat as switchActivatedMaster
-        switchActivatedMaster(swId);
-    }
-
-    @Override
-    public void switchDisconnected(long swId) {
-        // Not used
-    }
-
-    @Override
-    public void switchPortChanged(long swId, OFPortDesc port, PortChangeType pct) {
-        // Not used
-    }
-
-    @Override
-    public String getName() {
-        return "sdnip";
-    }
-
     /*
      * IConfigInfoService methods
      */
@@ -1309,6 +866,11 @@
         return false;
     }
 
+    /**
+     * To find the relative egress Interface for a next hop IP address.
+     *
+     * @param dstIpAddress the IP address of next hop router
+     */
     @Override
     public Interface getOutgoingInterface(InetAddress dstIpAddress) {
         return longestInterfacePrefixMatch(dstIpAddress);
@@ -1328,4 +890,5 @@
     public short getVlan() {
         return vlan;
     }
+
 }
diff --git a/src/main/java/net/onrc/onos/apps/sdnip/web/SdnIpSetup.java b/src/main/java/net/onrc/onos/apps/sdnip/web/SdnIpSetup.java
index d1c4605..4bed425 100644
--- a/src/main/java/net/onrc/onos/apps/sdnip/web/SdnIpSetup.java
+++ b/src/main/java/net/onrc/onos/apps/sdnip/web/SdnIpSetup.java
@@ -13,7 +13,7 @@
     public String sdnipSetupMethod() {
         ISdnIpService sdnIp = (ISdnIpService) getContext()
                               .getAttributes().get(ISdnIpService.class.getCanonicalName());
-        sdnIp.beginRoutingNew();
+        sdnIp.beginRouting();
         return "SdnIp SetupBgpPaths Succeeded";
     }
 
diff --git a/src/test/java/net/onrc/onos/apps/sdnip/SdnIpTest.java b/src/test/java/net/onrc/onos/apps/sdnip/SdnIpTest.java
new file mode 100644
index 0000000..f5a6d31
--- /dev/null
+++ b/src/test/java/net/onrc/onos/apps/sdnip/SdnIpTest.java
@@ -0,0 +1,81 @@
+package net.onrc.onos.apps.sdnip;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.junit.Test;
+
+import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory;
+import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree;
+import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
+
+public class SdnIpTest {
+
+    private Map<String, Interface> interfaces;
+    private InvertedRadixTree<Interface> interfaceRoutes;
+
+    private Interface longestInterfacePrefixMatch(InetAddress address) {
+        Prefix prefixToSearchFor = new Prefix(address.getAddress(),
+                Prefix.MAX_PREFIX_LENGTH);
+        Iterator<Interface> it =
+                interfaceRoutes.getValuesForKeysPrefixing(
+                        prefixToSearchFor.toBinaryString()).iterator();
+        Interface intf = null;
+        // Find the last prefix, which will be the longest prefix
+        while (it.hasNext()) {
+            intf = it.next();
+        }
+
+        return intf;
+    }
+    /**
+     * This is just a test of the InvertedRadixTree, rather than an actual unit
+     * test of SdnIp.
+     *
+     * @throws IOException
+     */
+    @Test
+    public void getOutgoingInterfaceTest() throws IOException {
+
+        interfaces = new HashMap<>();
+        interfaceRoutes = new ConcurrentInvertedRadixTree<>(
+                new DefaultByteArrayNodeFactory());
+
+        Interface interface1 = new Interface("sw3-eth1", "00:00:00:00:00:00:00:a3",
+                (short) 1, "192.168.10.101", 24);
+        interfaces.put(interface1.getName(), interface1);
+        Interface interface2 = new Interface("sw5-eth1", "00:00:00:00:00:00:00:a5",
+                (short) 1, "192.168.20.101", 16);
+        interfaces.put(interface2.getName(), interface2);
+        Interface interface3 = new Interface("sw2-eth1", "00:00:00:00:00:00:00:a2",
+                (short) 1, "192.168.60.101", 16);
+        interfaces.put(interface3.getName(), interface3);
+        Interface interface4 = new Interface("sw6-eth1", "00:00:00:00:00:00:00:a6",
+                (short) 1, "192.168.60.101", 30);
+        interfaces.put(interface4.getName(), interface4);
+        Interface interface5 = new Interface("sw4-eth4", "00:00:00:00:00:00:00:a4",
+                (short) 4, "192.168.60.101", 24);
+        interfaces.put(interface5.getName(), interface5);
+
+        for (Interface intf : interfaces.values()) {
+            Prefix prefix = new Prefix(intf.getIpAddress().getAddress(),
+                    intf.getPrefixLength());
+            interfaceRoutes.put(prefix.toBinaryString(), intf);
+        }
+
+        // Check whether the prefix length takes effect
+        InetAddress nextHopAddress = InetAddress.getByName("192.0.0.1");
+        assertNotNull(nextHopAddress);
+        assertNull(longestInterfacePrefixMatch(nextHopAddress));
+
+        // Check whether it returns the longest matchable address
+        nextHopAddress = InetAddress.getByName("192.168.60.101");
+        assertEquals("sw6-eth1", longestInterfacePrefixMatch(nextHopAddress).getName());
+
+    }
+}
