diff --git a/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/LocationType.java b/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/LocationType.java
new file mode 100644
index 0000000..01f4f70
--- /dev/null
+++ b/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/LocationType.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.reactive.routing;
+
+/**
+ * Specifies the type of an IP address or an IP prefix location.
+ */
+enum LocationType {
+    /**
+     * The location of an IP address or an IP prefix is in local SDN network.
+     */
+    LOCAL,
+    /**
+     * The location of an IP address or an IP prefix is outside local SDN network.
+     */
+    INTERNET,
+    /**
+     * There is no route for this IP address or IP prefix.
+     */
+    NO_ROUTE
+}
diff --git a/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/ReactiveRoutingFib.java b/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/ReactiveRoutingFib.java
new file mode 100644
index 0000000..8e86056
--- /dev/null
+++ b/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/ReactiveRoutingFib.java
@@ -0,0 +1,395 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.reactive.routing;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Maps;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Host;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.net.intent.constraint.PartialFailureConstraint;
+import org.onosproject.routing.IntentRequestListener;
+import org.onosproject.routing.IntentSynchronizationService;
+import org.onosproject.routing.config.RoutingConfigurationService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * FIB component for reactive routing intents.
+ */
+public class ReactiveRoutingFib implements IntentRequestListener {
+
+    private static final int PRIORITY_OFFSET = 100;
+    private static final int PRIORITY_MULTIPLIER = 5;
+    protected static final ImmutableList<Constraint> CONSTRAINTS
+            = ImmutableList.of(new PartialFailureConstraint());
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private final ApplicationId appId;
+    private final HostService hostService;
+    private final RoutingConfigurationService configService;
+    private final InterfaceService interfaceService;
+    private final IntentSynchronizationService intentSynchronizer;
+
+    private final Map<IpPrefix, MultiPointToSinglePointIntent> routeIntents;
+
+    /**
+     * Class constructor.
+     *
+     * @param appId application ID to use to generate intents
+     * @param hostService host service
+     * @param configService routing configuration service
+     * @param interfaceService interface service
+     * @param intentSynchronizer intent synchronization service
+     */
+    public ReactiveRoutingFib(ApplicationId appId, HostService hostService,
+                              RoutingConfigurationService configService,
+                              InterfaceService interfaceService,
+                              IntentSynchronizationService intentSynchronizer) {
+        this.appId = appId;
+        this.hostService = hostService;
+        this.configService = configService;
+        this.interfaceService = interfaceService;
+        this.intentSynchronizer = intentSynchronizer;
+
+        routeIntents = Maps.newConcurrentMap();
+    }
+
+    @Override
+    public void setUpConnectivityInternetToHost(IpAddress hostIpAddress) {
+        checkNotNull(hostIpAddress);
+        Set<ConnectPoint> ingressPoints =
+                configService.getBgpPeerConnectPoints();
+
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+
+        if (hostIpAddress.isIp4()) {
+            selector.matchEthType(Ethernet.TYPE_IPV4);
+        } else {
+            selector.matchEthType(Ethernet.TYPE_IPV6);
+        }
+
+        // Match the destination IP prefix at the first hop
+        IpPrefix ipPrefix = hostIpAddress.toIpPrefix();
+        selector.matchIPDst(ipPrefix);
+
+        // Rewrite the destination MAC address
+        MacAddress hostMac = null;
+        ConnectPoint egressPoint = null;
+        for (Host host : hostService.getHostsByIp(hostIpAddress)) {
+            if (host.mac() != null) {
+                hostMac = host.mac();
+                egressPoint = host.location();
+                break;
+            }
+        }
+        if (hostMac == null) {
+            hostService.startMonitoringIp(hostIpAddress);
+            return;
+        }
+
+        TrafficTreatment.Builder treatment =
+                DefaultTrafficTreatment.builder().setEthDst(hostMac);
+        Key key = Key.of(ipPrefix.toString(), appId);
+        int priority = ipPrefix.prefixLength() * PRIORITY_MULTIPLIER
+                + PRIORITY_OFFSET;
+        MultiPointToSinglePointIntent intent =
+                MultiPointToSinglePointIntent.builder()
+                        .appId(appId)
+                        .key(key)
+                        .selector(selector.build())
+                        .treatment(treatment.build())
+                        .ingressPoints(ingressPoints)
+                        .egressPoint(egressPoint)
+                        .priority(priority)
+                        .constraints(CONSTRAINTS)
+                        .build();
+
+        log.trace("Generates ConnectivityInternetToHost intent {}", intent);
+        submitReactiveIntent(ipPrefix, intent);
+    }
+
+    @Override
+    public void setUpConnectivityHostToInternet(IpAddress hostIp, IpPrefix prefix,
+                                                IpAddress nextHopIpAddress) {
+        // Find the attachment point (egress interface) of the next hop
+        Interface egressInterface = interfaceService.getMatchingInterface(nextHopIpAddress);
+        if (egressInterface == null) {
+            log.warn("No outgoing interface found for {}",
+                    nextHopIpAddress);
+            return;
+        }
+
+        Set<Host> hosts = hostService.getHostsByIp(nextHopIpAddress);
+        if (hosts.isEmpty()) {
+            log.warn("No host found for next hop IP address");
+            return;
+        }
+        MacAddress nextHopMacAddress = null;
+        for (Host host : hosts) {
+            nextHopMacAddress = host.mac();
+            break;
+        }
+
+        hosts = hostService.getHostsByIp(hostIp);
+        if (hosts.isEmpty()) {
+            log.warn("No host found for host IP address");
+            return;
+        }
+        Host host = hosts.stream().findFirst().get();
+        ConnectPoint ingressPoint = host.location();
+
+        // Generate the intent itself
+        ConnectPoint egressPort = egressInterface.connectPoint();
+        log.debug("Generating intent for prefix {}, next hop mac {}",
+                prefix, nextHopMacAddress);
+
+        // Match the destination IP prefix at the first hop
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        if (prefix.isIp4()) {
+            selector.matchEthType(Ethernet.TYPE_IPV4);
+            selector.matchIPDst(prefix);
+        } else {
+            selector.matchEthType(Ethernet.TYPE_IPV6);
+            selector.matchIPv6Dst(prefix);
+        }
+
+        // Rewrite the destination MAC address
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
+                .setEthDst(nextHopMacAddress);
+        if (!egressInterface.vlan().equals(VlanId.NONE)) {
+            treatment.setVlanId(egressInterface.vlan());
+            // If we set VLAN ID, we have to make sure a VLAN tag exists.
+            // TODO support no VLAN -> VLAN routing
+            selector.matchVlanId(VlanId.ANY);
+        }
+
+        int priority = prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET;
+        Key key = Key.of(prefix.toString() + "-reactive", appId);
+        MultiPointToSinglePointIntent intent = MultiPointToSinglePointIntent.builder()
+                .appId(appId)
+                .key(key)
+                .selector(selector.build())
+                .treatment(treatment.build())
+                .ingressPoints(Collections.singleton(ingressPoint))
+                .egressPoint(egressPort)
+                .priority(priority)
+                .constraints(CONSTRAINTS)
+                .build();
+
+        submitReactiveIntent(prefix, intent);
+    }
+
+    @Override
+    public void setUpConnectivityHostToHost(IpAddress dstIpAddress,
+                                            IpAddress srcIpAddress,
+                                            MacAddress srcMacAddress,
+                                            ConnectPoint srcConnectPoint) {
+        checkNotNull(dstIpAddress);
+        checkNotNull(srcIpAddress);
+        checkNotNull(srcMacAddress);
+        checkNotNull(srcConnectPoint);
+
+        IpPrefix srcIpPrefix = srcIpAddress.toIpPrefix();
+        IpPrefix dstIpPrefix = dstIpAddress.toIpPrefix();
+        ConnectPoint dstConnectPoint = null;
+        MacAddress dstMacAddress = null;
+
+        for (Host host : hostService.getHostsByIp(dstIpAddress)) {
+            if (host.mac() != null) {
+                dstMacAddress = host.mac();
+                dstConnectPoint = host.location();
+                break;
+            }
+        }
+        if (dstMacAddress == null) {
+            hostService.startMonitoringIp(dstIpAddress);
+            return;
+        }
+
+        //
+        // Handle intent from source host to destination host
+        //
+        MultiPointToSinglePointIntent srcToDstIntent =
+                hostToHostIntentGenerator(dstIpAddress, dstConnectPoint,
+                        dstMacAddress, srcConnectPoint);
+        submitReactiveIntent(dstIpPrefix, srcToDstIntent);
+
+        //
+        // Handle intent from destination host to source host
+        //
+
+        // Since we proactively handle the intent from destination host to
+        // source host, we should check whether there is an exiting intent
+        // first.
+        if (mp2pIntentExists(srcIpPrefix)) {
+            updateExistingMp2pIntent(srcIpPrefix, dstConnectPoint);
+            return;
+        } else {
+            // There is no existing intent, create a new one.
+            MultiPointToSinglePointIntent dstToSrcIntent =
+                    hostToHostIntentGenerator(srcIpAddress, srcConnectPoint,
+                            srcMacAddress, dstConnectPoint);
+            submitReactiveIntent(srcIpPrefix, dstToSrcIntent);
+        }
+    }
+
+    /**
+     * Generates MultiPointToSinglePointIntent for both source host and
+     * destination host located in local SDN network.
+     *
+     * @param dstIpAddress the destination IP address
+     * @param dstConnectPoint the destination host connect point
+     * @param dstMacAddress the MAC address of destination host
+     * @param srcConnectPoint the connect point where packet-in from
+     * @return the generated MultiPointToSinglePointIntent
+     */
+    private MultiPointToSinglePointIntent hostToHostIntentGenerator(
+            IpAddress dstIpAddress,
+            ConnectPoint dstConnectPoint,
+            MacAddress dstMacAddress,
+            ConnectPoint srcConnectPoint) {
+        checkNotNull(dstIpAddress);
+        checkNotNull(dstConnectPoint);
+        checkNotNull(dstMacAddress);
+        checkNotNull(srcConnectPoint);
+
+        Set<ConnectPoint> ingressPoints = new HashSet<>();
+        ingressPoints.add(srcConnectPoint);
+        IpPrefix dstIpPrefix = dstIpAddress.toIpPrefix();
+
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        if (dstIpAddress.isIp4()) {
+            selector.matchEthType(Ethernet.TYPE_IPV4);
+            selector.matchIPDst(dstIpPrefix);
+        } else {
+            selector.matchEthType(Ethernet.TYPE_IPV6);
+            selector.matchIPv6Dst(dstIpPrefix);
+        }
+
+        // Rewrite the destination MAC address
+        TrafficTreatment.Builder treatment =
+                DefaultTrafficTreatment.builder().setEthDst(dstMacAddress);
+
+        Key key = Key.of(dstIpPrefix.toString(), appId);
+        int priority = dstIpPrefix.prefixLength() * PRIORITY_MULTIPLIER
+                + PRIORITY_OFFSET;
+        MultiPointToSinglePointIntent intent =
+                MultiPointToSinglePointIntent.builder()
+                        .appId(appId)
+                        .key(key)
+                        .selector(selector.build())
+                        .treatment(treatment.build())
+                        .ingressPoints(ingressPoints)
+                        .egressPoint(dstConnectPoint)
+                        .priority(priority)
+                        .constraints(CONSTRAINTS)
+                        .build();
+
+        log.trace("Generates ConnectivityHostToHost = {} ", intent);
+        return intent;
+    }
+
+    @Override
+    public void updateExistingMp2pIntent(IpPrefix ipPrefix,
+                                         ConnectPoint ingressConnectPoint) {
+        checkNotNull(ipPrefix);
+        checkNotNull(ingressConnectPoint);
+
+        MultiPointToSinglePointIntent existingIntent =
+                getExistingMp2pIntent(ipPrefix);
+        if (existingIntent != null) {
+            Set<ConnectPoint> ingressPoints = existingIntent.ingressPoints();
+            // Add host connect point into ingressPoints of the existing intent
+            if (ingressPoints.add(ingressConnectPoint)) {
+                MultiPointToSinglePointIntent updatedMp2pIntent =
+                        MultiPointToSinglePointIntent.builder()
+                                .appId(appId)
+                                .key(existingIntent.key())
+                                .selector(existingIntent.selector())
+                                .treatment(existingIntent.treatment())
+                                .ingressPoints(ingressPoints)
+                                .egressPoint(existingIntent.egressPoint())
+                                .priority(existingIntent.priority())
+                                .constraints(CONSTRAINTS)
+                                .build();
+
+                log.trace("Update an existing MultiPointToSinglePointIntent "
+                        + "to new intent = {} ", updatedMp2pIntent);
+                submitReactiveIntent(ipPrefix, updatedMp2pIntent);
+            }
+            // If adding ingressConnectPoint to ingressPoints failed, it
+            // because between the time interval from checking existing intent
+            // to generating new intent, onos updated this intent due to other
+            // packet-in and the new intent also includes the
+            // ingressConnectPoint. This will not affect reactive routing.
+        }
+    }
+
+    /**
+     * Submits a reactive intent to the intent synchronizer.
+     *
+     * @param ipPrefix IP prefix of the intent
+     * @param intent intent to submit
+     */
+    void submitReactiveIntent(IpPrefix ipPrefix, MultiPointToSinglePointIntent intent) {
+        routeIntents.put(ipPrefix, intent);
+
+        intentSynchronizer.submit(intent);
+    }
+
+    /**
+     * Gets the existing MultiPointToSinglePointIntent from memory for a given
+     * IP prefix.
+     *
+     * @param ipPrefix the IP prefix used to find MultiPointToSinglePointIntent
+     * @return the MultiPointToSinglePointIntent if found, otherwise null
+     */
+    private MultiPointToSinglePointIntent getExistingMp2pIntent(IpPrefix ipPrefix) {
+        checkNotNull(ipPrefix);
+        return routeIntents.get(ipPrefix);
+    }
+
+    @Override
+    public boolean mp2pIntentExists(IpPrefix ipPrefix) {
+        checkNotNull(ipPrefix);
+        return routeIntents.get(ipPrefix) != null;
+    }
+}
diff --git a/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java b/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java
index ad78a1c..a05e394 100644
--- a/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java
+++ b/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java
@@ -25,27 +25,39 @@
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.IPv4;
 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.ApplicationId;
 import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Host;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.HostService;
 import org.onosproject.net.packet.DefaultOutboundPacket;
 import org.onosproject.net.packet.InboundPacket;
 import org.onosproject.net.packet.OutboundPacket;
 import org.onosproject.net.packet.PacketContext;
 import org.onosproject.net.packet.PacketProcessor;
 import org.onosproject.net.packet.PacketService;
+import org.onosproject.routing.IntentRequestListener;
+import org.onosproject.routing.RouteEntry;
 import org.onosproject.routing.RoutingService;
+import org.onosproject.routing.SdnIpService;
 import org.onosproject.routing.config.RoutingConfigurationService;
 import org.slf4j.Logger;
 
 import java.nio.ByteBuffer;
+import java.util.Optional;
+import java.util.Set;
 
+import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onlab.packet.Ethernet.TYPE_ARP;
 import static org.onlab.packet.Ethernet.TYPE_IPV4;
 import static org.onosproject.net.packet.PacketPriority.REACTIVE;
@@ -74,16 +86,32 @@
     protected RoutingService routingService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected SdnIpService sdnIpService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected RoutingConfigurationService config;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
     private ApplicationId appId;
 
+    private IntentRequestListener intentRequestListener;
+
     private ReactiveRoutingProcessor processor =
             new ReactiveRoutingProcessor();
 
     @Activate
     public void activate() {
         appId = coreService.registerApplication(APP_NAME);
+
+        intentRequestListener = new ReactiveRoutingFib(appId, hostService,
+                config, interfaceService,
+                sdnIpService.getIntentSynchronizationService());
+
         packetService.addProcessor(processor, PacketProcessor.director(2));
         requestIntercepts();
         log.info("SDN-IP Reactive Routing Started");
@@ -168,12 +196,11 @@
                 IpAddress srcIp =
                         IpAddress.valueOf(ipv4Packet.getSourceAddress());
                 MacAddress srcMac = ethPkt.getSourceMAC();
-                routingService.packetReactiveProcessor(dstIp, srcIp,
-                                                       srcConnectPoint, srcMac);
+                packetReactiveProcessor(dstIp, srcIp, srcConnectPoint, srcMac);
 
                 // TODO emit packet first or packetReactiveProcessor first
                 ConnectPoint egressConnectPoint = null;
-                egressConnectPoint = routingService.getEgressConnectPoint(dstIp);
+                egressConnectPoint = getEgressConnectPoint(dstIp);
                 if (egressConnectPoint != null) {
                     forwardPacketToDst(context, egressConnectPoint);
                 }
@@ -185,6 +212,170 @@
     }
 
     /**
+     * Routes packet reactively.
+     *
+     * @param dstIpAddress the destination IP address of a packet
+     * @param srcIpAddress the source IP address of a packet
+     * @param srcConnectPoint the connect point where a packet comes from
+     * @param srcMacAddress the source MAC address of a packet
+     */
+    private void packetReactiveProcessor(IpAddress dstIpAddress,
+                                        IpAddress srcIpAddress,
+                                        ConnectPoint srcConnectPoint,
+                                        MacAddress srcMacAddress) {
+        checkNotNull(dstIpAddress);
+        checkNotNull(srcIpAddress);
+        checkNotNull(srcConnectPoint);
+        checkNotNull(srcMacAddress);
+
+        //
+        // Step1: Try to update the existing intent first if it exists.
+        //
+        IpPrefix ipPrefix = null;
+        RouteEntry routeEntry = null;
+        if (config.isIpAddressLocal(dstIpAddress)) {
+            if (dstIpAddress.isIp4()) {
+                ipPrefix = IpPrefix.valueOf(dstIpAddress,
+                        Ip4Address.BIT_LENGTH);
+            } else {
+                ipPrefix = IpPrefix.valueOf(dstIpAddress,
+                        Ip6Address.BIT_LENGTH);
+            }
+        } else {
+            // Get IP prefix from BGP route table
+            routeEntry = routingService.getLongestMatchableRouteEntry(dstIpAddress);
+            if (routeEntry != null) {
+                ipPrefix = routeEntry.prefix();
+            }
+        }
+        if (ipPrefix != null
+                && intentRequestListener.mp2pIntentExists(ipPrefix)) {
+            intentRequestListener.updateExistingMp2pIntent(ipPrefix,
+                    srcConnectPoint);
+            return;
+        }
+
+        //
+        // Step2: There is no existing intent for the destination IP address.
+        // Check whether it is necessary to create a new one. If necessary then
+        // create a new one.
+        //
+        TrafficType trafficType =
+                trafficTypeClassifier(srcConnectPoint, dstIpAddress);
+
+        switch (trafficType) {
+        case HOST_TO_INTERNET:
+            // If the destination IP address is outside the local SDN network.
+            // The Step 1 has already handled it. We do not need to do anything here.
+            intentRequestListener.setUpConnectivityHostToInternet(srcIpAddress,
+                    ipPrefix, routeEntry.nextHop());
+            break;
+        case INTERNET_TO_HOST:
+            intentRequestListener.setUpConnectivityInternetToHost(dstIpAddress);
+            break;
+        case HOST_TO_HOST:
+            intentRequestListener.setUpConnectivityHostToHost(dstIpAddress,
+                    srcIpAddress, srcMacAddress, srcConnectPoint);
+            break;
+        case INTERNET_TO_INTERNET:
+            log.trace("This is transit traffic, "
+                    + "the intent should be preinstalled already");
+            break;
+        case DROP:
+            // TODO here should setUpDropPacketIntent(...);
+            // We need a new type of intent here.
+            break;
+        case UNKNOWN:
+            log.trace("This is unknown traffic, so we do nothing");
+            break;
+        default:
+            break;
+        }
+    }
+
+    /**
+     * Classifies the traffic and return the traffic type.
+     *
+     * @param srcConnectPoint the connect point where the packet comes from
+     * @param dstIp the destination IP address in packet
+     * @return the traffic type which this packet belongs to
+     */
+    private TrafficType trafficTypeClassifier(ConnectPoint srcConnectPoint,
+                                                             IpAddress dstIp) {
+        LocationType dstIpLocationType = getLocationType(dstIp);
+        Optional<Interface> srcInterface =
+                interfaceService.getInterfacesByPort(srcConnectPoint).stream().findFirst();
+
+        switch (dstIpLocationType) {
+        case INTERNET:
+            if (!srcInterface.isPresent()) {
+                return TrafficType.HOST_TO_INTERNET;
+            } else {
+                return TrafficType.INTERNET_TO_INTERNET;
+            }
+        case LOCAL:
+            if (!srcInterface.isPresent()) {
+                return TrafficType.HOST_TO_HOST;
+            } else {
+                // TODO Currently we only consider local public prefixes.
+                // In the future, we will consider the local private prefixes.
+                // If dstIpLocationType is a local private, we should return
+                // TrafficType.DROP.
+                return TrafficType.INTERNET_TO_HOST;
+            }
+        case NO_ROUTE:
+            return TrafficType.DROP;
+        default:
+            return TrafficType.UNKNOWN;
+        }
+    }
+
+    /**
+     * Evaluates the location of an IP address and returns the location type.
+     *
+     * @param ipAddress the IP address to evaluate
+     * @return the IP address location type
+     */
+    private LocationType getLocationType(IpAddress ipAddress) {
+        if (config.isIpAddressLocal(ipAddress)) {
+            return LocationType.LOCAL;
+        } else if (routingService.getLongestMatchableRouteEntry(ipAddress) != null) {
+            return LocationType.INTERNET;
+        } else {
+            return LocationType.NO_ROUTE;
+        }
+    }
+
+    public ConnectPoint getEgressConnectPoint(IpAddress dstIpAddress) {
+        LocationType type = getLocationType(dstIpAddress);
+        if (type == LocationType.LOCAL) {
+            Set<Host> hosts = hostService.getHostsByIp(dstIpAddress);
+            if (!hosts.isEmpty()) {
+                return hosts.iterator().next().location();
+            } else {
+                hostService.startMonitoringIp(dstIpAddress);
+                return null;
+            }
+        } else if (type == LocationType.INTERNET) {
+            IpAddress nextHopIpAddress = null;
+            RouteEntry routeEntry = routingService.getLongestMatchableRouteEntry(dstIpAddress);
+            if (routeEntry != null) {
+                nextHopIpAddress = routeEntry.nextHop();
+                Interface it = interfaceService.getMatchingInterface(nextHopIpAddress);
+                if (it != null) {
+                    return it.connectPoint();
+                } else {
+                    return null;
+                }
+            } else {
+                return null;
+            }
+        } else {
+            return null;
+        }
+    }
+
+    /**
      * Emits the specified packet onto the network.
      *
      * @param context      the packet context
diff --git a/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/TrafficType.java b/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/TrafficType.java
new file mode 100644
index 0000000..134126b
--- /dev/null
+++ b/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/TrafficType.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.reactive.routing;
+
+/**
+ * Specifies the type of traffic.
+ * <p>
+ * We classify traffic by the first packet of each traffic.
+ * </p>
+ */
+enum TrafficType {
+    /**
+     * Traffic from a host located in local SDN network wants to
+     * communicate with destination host located in Internet (outside
+     * local SDN network).
+     */
+    HOST_TO_INTERNET,
+    /**
+     * Traffic from Internet wants to communicate with a host located
+     * in local SDN network.
+     */
+    INTERNET_TO_HOST,
+    /**
+     * Both the source host and destination host of a traffic are in
+     * local SDN network.
+     */
+    HOST_TO_HOST,
+    /**
+     * Traffic from Internet wants to traverse local SDN network.
+     */
+    INTERNET_TO_INTERNET,
+    /**
+     * Any traffic wants to communicate with a destination which has
+     * no route, or traffic from Internet wants to access a local private
+     * IP address.
+     */
+    DROP,
+    /**
+     * Traffic does not belong to the types above.
+     */
+    UNKNOWN
+}
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/IntentRequestListener.java b/apps/routing-api/src/main/java/org/onosproject/routing/IntentRequestListener.java
index 2d1bb31..1069ec5 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/IntentRequestListener.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/IntentRequestListener.java
@@ -47,6 +47,16 @@
                                      ConnectPoint srcConnectPoint);
 
     /**
+     * Sets up connectivity for packet from a local host to the Internet.
+     *
+     * @param hostIp IP address of the local host
+     * @param prefix external IP prefix that the host is talking to
+     * @param nextHopIpAddress IP address of the next hop router for the prefix
+     */
+    void setUpConnectivityHostToInternet(IpAddress hostIp, IpPrefix prefix,
+                                                IpAddress nextHopIpAddress);
+
+    /**
      * Adds one new ingress connect point into ingress points of an existing
      * intent and resubmits the new intent.
      * <p>
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/IntentSynchronizationService.java b/apps/routing-api/src/main/java/org/onosproject/routing/IntentSynchronizationService.java
new file mode 100644
index 0000000..dc6a838
--- /dev/null
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/IntentSynchronizationService.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.routing;
+
+import org.onosproject.net.intent.Intent;
+
+/**
+ * Submits and withdraws intents to the IntentService from a single point in
+ * the cluster at any one time. The provided intents will be synchronized with
+ * the IntentService on leadership change.
+ */
+public interface IntentSynchronizationService {
+
+    /**
+     * Submits and intent to the synchronizer.
+     * <p>
+     * The intent will be submitted directly to the IntentService if this node
+     * is the leader, otherwise it will be stored in the synchronizer for
+     * synchronization if this node becomes the leader.
+     * </p>
+     *
+     * @param intent intent to submit
+     */
+    void submit(Intent intent);
+
+    /**
+     * Withdraws an intent from the synchronizer.
+     * <p>
+     * The intent will be withdrawn directly from the IntentService if this node
+     * is the leader. The intent will be removed from the synchronizer's
+     * in-memory storage.
+     * </p>
+     *
+     * @param intent intent to withdraw
+     */
+    void withdraw(Intent intent);
+}
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/RoutingService.java b/apps/routing-api/src/main/java/org/onosproject/routing/RoutingService.java
index 8b7040e..7399ed7 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/RoutingService.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/RoutingService.java
@@ -16,8 +16,6 @@
 package org.onosproject.routing;
 
 import org.onlab.packet.IpAddress;
-import org.onlab.packet.MacAddress;
-import org.onosproject.net.ConnectPoint;
 import org.onosproject.routing.config.BgpConfig;
 
 import java.util.Collection;
@@ -32,63 +30,6 @@
     Class<BgpConfig> CONFIG_CLASS = BgpConfig.class;
 
     /**
-     * Specifies the type of an IP address or an IP prefix location.
-     */
-    enum LocationType {
-        /**
-         * The location of an IP address or an IP prefix is in local SDN network.
-         */
-        LOCAL,
-        /**
-         * The location of an IP address or an IP prefix is outside local SDN network.
-         */
-        INTERNET,
-        /**
-         * There is no route for this IP address or IP prefix.
-         */
-        NO_ROUTE
-    }
-
-    /**
-     * Specifies the type of traffic.
-     * <p>
-     * We classify traffic by the first packet of each traffic.
-     * </p>
-     */
-    enum TrafficType {
-        /**
-         * Traffic from a host located in local SDN network wants to
-         * communicate with destination host located in Internet (outside
-         * local SDN network).
-         */
-        HOST_TO_INTERNET,
-        /**
-         * Traffic from Internet wants to communicate with a host located
-         * in local SDN network.
-         */
-        INTERNET_TO_HOST,
-        /**
-         * Both the source host and destination host of a traffic are in
-         * local SDN network.
-         */
-        HOST_TO_HOST,
-        /**
-         * Traffic from Internet wants to traverse local SDN network.
-         */
-        INTERNET_TO_INTERNET,
-        /**
-         * Any traffic wants to communicate with a destination which has
-         * no route, or traffic from Internet wants to access a local private
-         * IP address.
-         */
-        DROP,
-        /**
-         * Traffic does not belong to the types above.
-         */
-        UNKNOWN
-    }
-
-    /**
      * Starts the routing service.
      */
     void start();
@@ -101,15 +42,6 @@
     void addFibListener(FibListener fibListener);
 
     /**
-     * Adds intent creation and submission listener.
-     *
-     * @param intentRequestListener listener to send intent creation and
-     *        submission request to
-     */
-    void addIntentRequestListener(IntentRequestListener
-                                         intentRequestListener);
-
-    /**
      * Stops the routing service.
      */
     void stop();
@@ -129,14 +61,6 @@
     Collection<RouteEntry> getRoutes6();
 
     /**
-     * Evaluates the location of an IP address and returns the location type.
-     *
-     * @param ipAddress the IP address to evaluate
-     * @return the IP address location type
-     */
-    LocationType getLocationType(IpAddress ipAddress);
-
-    /**
      * Finds out the route entry which has the longest matchable IP prefix.
      *
      * @param ipAddress IP address used to find out longest matchable IP prefix
@@ -145,25 +69,4 @@
      */
     RouteEntry getLongestMatchableRouteEntry(IpAddress ipAddress);
 
-    /**
-     * Finds out the egress connect point where to emit the first packet
-     * based on destination IP address.
-     *
-     * @param dstIpAddress the destination IP address
-     * @return the egress connect point if found, otherwise null
-     */
-    ConnectPoint getEgressConnectPoint(IpAddress dstIpAddress);
-
-    /**
-     * Routes packet reactively.
-     *
-     * @param dstIpAddress the destination IP address of a packet
-     * @param srcIpAddress the source IP address of a packet
-     * @param srcConnectPoint the connect point where a packet comes from
-     * @param srcMacAddress the source MAC address of a packet
-     */
-    void packetReactiveProcessor(IpAddress dstIpAddress,
-                                        IpAddress srcIpAddress,
-                                        ConnectPoint srcConnectPoint,
-                                        MacAddress srcMacAddress);
 }
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpService.java b/apps/routing-api/src/main/java/org/onosproject/routing/SdnIpService.java
similarity index 77%
rename from apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpService.java
rename to apps/routing-api/src/main/java/org/onosproject/routing/SdnIpService.java
index d26d306..0945336 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpService.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/SdnIpService.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.sdnip;
+package org.onosproject.routing;
 
 /**
  * Service interface exported by SDN-IP.
@@ -28,4 +28,12 @@
      */
     void modifyPrimary(boolean isPrimary);
 
+    /**
+     * Gets the intent synchronization service.
+     *
+     * @return intent synchronization service
+     */
+    // TODO fix service resolution in SDN-IP
+    IntentSynchronizationService getIntentSynchronizationService();
+
 }
diff --git a/apps/routing/src/main/java/org/onosproject/routing/impl/Router.java b/apps/routing/src/main/java/org/onosproject/routing/impl/Router.java
index 6700d53..75d789a 100644
--- a/apps/routing/src/main/java/org/onosproject/routing/impl/Router.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/impl/Router.java
@@ -35,9 +35,7 @@
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.MacAddress;
 import org.onosproject.core.CoreService;
-import org.onosproject.incubator.net.intf.Interface;
 import org.onosproject.incubator.net.intf.InterfaceService;
-import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.Host;
 import org.onosproject.net.host.HostEvent;
 import org.onosproject.net.host.HostListener;
@@ -46,7 +44,6 @@
 import org.onosproject.routing.FibEntry;
 import org.onosproject.routing.FibListener;
 import org.onosproject.routing.FibUpdate;
-import org.onosproject.routing.IntentRequestListener;
 import org.onosproject.routing.RouteEntry;
 import org.onosproject.routing.RouteListener;
 import org.onosproject.routing.RouteUpdate;
@@ -61,7 +58,6 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.ConcurrentHashMap;
@@ -100,7 +96,6 @@
     private final Map<IpAddress, MacAddress> ip2Mac = new ConcurrentHashMap<>();
 
     private FibListener fibComponent;
-    private IntentRequestListener intentRequestListener;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected CoreService coreService;
@@ -145,12 +140,6 @@
     @Override
     public void addFibListener(FibListener fibListener) {
         this.fibComponent = checkNotNull(fibListener);
-
-    }
-
-    @Override
-    public void addIntentRequestListener(IntentRequestListener intentRequestListener) {
-        this.intentRequestListener = checkNotNull(intentRequestListener);
     }
 
     @Override
@@ -287,12 +276,10 @@
     void addRibRoute(RouteEntry routeEntry) {
         if (routeEntry.isIp4()) {
             // IPv4
-            ribTable4.put(createBinaryString(routeEntry.prefix()),
-                    routeEntry);
+            ribTable4.put(createBinaryString(routeEntry.prefix()), routeEntry);
         } else {
             // IPv6
-            ribTable6.put(createBinaryString(routeEntry.prefix()),
-                    routeEntry);
+            ribTable6.put(createBinaryString(routeEntry.prefix()), routeEntry);
         }
     }
 
@@ -553,17 +540,6 @@
     }
 
     @Override
-    public LocationType getLocationType(IpAddress ipAddress) {
-        if (routingConfigurationService.isIpAddressLocal(ipAddress)) {
-            return LocationType.LOCAL;
-        } else if (getLongestMatchableRouteEntry(ipAddress) != null) {
-            return LocationType.INTERNET;
-        } else {
-            return LocationType.NO_ROUTE;
-        }
-    }
-
-    @Override
     public RouteEntry getLongestMatchableRouteEntry(IpAddress ipAddress) {
         RouteEntry routeEntry = null;
         Iterable<RouteEntry> routeEntries;
@@ -587,142 +563,4 @@
         return routeEntry;
     }
 
-    @Override
-    public ConnectPoint getEgressConnectPoint(IpAddress dstIpAddress) {
-        LocationType type = getLocationType(dstIpAddress);
-        if (type == LocationType.LOCAL) {
-            Set<Host> hosts = hostService.getHostsByIp(dstIpAddress);
-            if (!hosts.isEmpty()) {
-                return hosts.iterator().next().location();
-            } else {
-                hostService.startMonitoringIp(dstIpAddress);
-                return null;
-            }
-        } else if (type == LocationType.INTERNET) {
-            IpAddress nextHopIpAddress = null;
-            RouteEntry routeEntry = getLongestMatchableRouteEntry(dstIpAddress);
-            if (routeEntry != null) {
-                nextHopIpAddress = routeEntry.nextHop();
-                Interface it = interfaceService.getMatchingInterface(nextHopIpAddress);
-                if (it != null) {
-                    return it.connectPoint();
-                } else {
-                    return null;
-                }
-            } else {
-                return null;
-            }
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public void packetReactiveProcessor(IpAddress dstIpAddress,
-                                        IpAddress srcIpAddress,
-                                        ConnectPoint srcConnectPoint,
-                                        MacAddress srcMacAddress) {
-        checkNotNull(dstIpAddress);
-        checkNotNull(srcIpAddress);
-        checkNotNull(srcConnectPoint);
-        checkNotNull(srcMacAddress);
-
-        //
-        // Step1: Try to update the existing intent first if it exists.
-        //
-        IpPrefix ipPrefix = null;
-        if (routingConfigurationService.isIpAddressLocal(dstIpAddress)) {
-            if (dstIpAddress.isIp4()) {
-                ipPrefix = IpPrefix.valueOf(dstIpAddress,
-                        Ip4Address.BIT_LENGTH);
-            } else {
-                ipPrefix = IpPrefix.valueOf(dstIpAddress,
-                        Ip6Address.BIT_LENGTH);
-            }
-        } else {
-            // Get IP prefix from BGP route table
-            RouteEntry routeEntry = getLongestMatchableRouteEntry(dstIpAddress);
-            if (routeEntry != null) {
-                ipPrefix = routeEntry.prefix();
-            }
-        }
-        if (ipPrefix != null
-                && intentRequestListener.mp2pIntentExists(ipPrefix)) {
-            intentRequestListener.updateExistingMp2pIntent(ipPrefix,
-                    srcConnectPoint);
-            return;
-        }
-
-        //
-        // Step2: There is no existing intent for the destination IP address.
-        // Check whether it is necessary to create a new one. If necessary then
-        // create a new one.
-        //
-        TrafficType trafficType =
-                trafficTypeClassifier(srcConnectPoint, dstIpAddress);
-
-        switch (trafficType) {
-        case HOST_TO_INTERNET:
-            // If the destination IP address is outside the local SDN network.
-            // The Step 1 has already handled it. We do not need to do anything here.
-            break;
-        case INTERNET_TO_HOST:
-            intentRequestListener.setUpConnectivityInternetToHost(dstIpAddress);
-            break;
-        case HOST_TO_HOST:
-            intentRequestListener.setUpConnectivityHostToHost(dstIpAddress,
-                    srcIpAddress, srcMacAddress, srcConnectPoint);
-            break;
-        case INTERNET_TO_INTERNET:
-            log.trace("This is transit traffic, "
-                    + "the intent should be preinstalled already");
-            break;
-        case DROP:
-            // TODO here should setUpDropPaccketIntent(...);
-            // We need a new type of intent here.
-            break;
-        case UNKNOWN:
-            log.trace("This is unknown traffic, so we do nothing");
-            break;
-        default:
-            break;
-        }
-    }
-
-    /**
-     * Classifies the traffic and return the traffic type.
-     *
-     * @param srcConnectPoint the connect point where the packet comes from
-     * @param dstIp the destination IP address in packet
-     * @return the traffic type which this packet belongs to
-     */
-    private TrafficType trafficTypeClassifier(ConnectPoint srcConnectPoint,
-                                              IpAddress dstIp) {
-        LocationType dstIpLocationType = getLocationType(dstIp);
-        Optional<Interface> srcInterface =
-                interfaceService.getInterfacesByPort(srcConnectPoint).stream().findFirst();
-
-        switch (dstIpLocationType) {
-        case INTERNET:
-            if (!srcInterface.isPresent()) {
-                return TrafficType.HOST_TO_INTERNET;
-            } else {
-                return TrafficType.INTERNET_TO_INTERNET;
-            }
-        case LOCAL:
-            if (!srcInterface.isPresent()) {
-                return TrafficType.HOST_TO_HOST;
-            } else {
-                // TODO Currently we only consider local public prefixes.
-                // In the future, we will consider the local private prefixes.
-                // If dstIpLocationType is a local private, we should return
-                // TrafficType.DROP.
-                return TrafficType.INTERNET_TO_HOST;
-            }
-        case NO_ROUTE:
-            return TrafficType.DROP;
-        default:
-            return TrafficType.UNKNOWN;
-        }
-    }
 }
diff --git a/apps/routing/src/main/java/org/onosproject/routing/impl/StaticRouter.java b/apps/routing/src/main/java/org/onosproject/routing/impl/StaticRouter.java
index 29526ff..3c86820 100644
--- a/apps/routing/src/main/java/org/onosproject/routing/impl/StaticRouter.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/impl/StaticRouter.java
@@ -18,10 +18,7 @@
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Service;
 import org.onlab.packet.IpAddress;
-import org.onlab.packet.MacAddress;
-import org.onosproject.net.ConnectPoint;
 import org.onosproject.routing.FibListener;
-import org.onosproject.routing.IntentRequestListener;
 import org.onosproject.routing.RouteEntry;
 import org.onosproject.routing.RoutingService;
 import org.onosproject.routing.StaticRoutingService;
@@ -49,11 +46,6 @@
     }
 
     @Override
-    public void addIntentRequestListener(IntentRequestListener intentRequestListener) {
-
-    }
-
-    @Override
     public void stop() {
 
     }
@@ -69,27 +61,11 @@
     }
 
     @Override
-    public LocationType getLocationType(IpAddress ipAddress) {
-        return null;
-    }
-
-    @Override
     public RouteEntry getLongestMatchableRouteEntry(IpAddress ipAddress) {
         return null;
     }
 
     @Override
-    public ConnectPoint getEgressConnectPoint(IpAddress dstIpAddress) {
-        return null;
-    }
-
-    @Override
-    public void packetReactiveProcessor(IpAddress dstIpAddress, IpAddress srcIpAddress,
-                                        ConnectPoint srcConnectPoint, MacAddress srcMacAddress) {
-
-    }
-
-    @Override
     public FibListener getFibListener() {
         return fibListener;
     }
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
index d8d8f45..eaabed3 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
@@ -15,118 +15,79 @@
  */
 package org.onosproject.sdnip;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import org.onlab.packet.Ethernet;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
 import org.onosproject.core.ApplicationId;
-import org.onosproject.incubator.net.intf.Interface;
-import org.onosproject.incubator.net.intf.InterfaceService;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.Host;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criterion;
-import org.onosproject.net.flow.criteria.IPCriterion;
-import org.onosproject.net.host.HostService;
-import org.onosproject.net.intent.Constraint;
 import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentService;
 import org.onosproject.net.intent.IntentState;
 import org.onosproject.net.intent.Key;
-import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.net.intent.PointToPointIntent;
-import org.onosproject.net.intent.constraint.PartialFailureConstraint;
-import org.onosproject.routing.FibListener;
-import org.onosproject.routing.FibUpdate;
-import org.onosproject.routing.IntentRequestListener;
-import org.onosproject.routing.config.RoutingConfigurationService;
+import org.onosproject.routing.IntentSynchronizationService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Collection;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Semaphore;
 
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static org.onlab.util.Tools.groupedThreads;
 
 /**
  * Synchronizes intents between the in-memory intent store and the
  * IntentService.
  */
-public class IntentSynchronizer implements FibListener, IntentRequestListener {
-    private static final int PRIORITY_OFFSET = 100;
-    private static final int PRIORITY_MULTIPLIER = 5;
-    protected static final ImmutableList<Constraint> CONSTRAINTS
-            = ImmutableList.of(new PartialFailureConstraint());
+public class IntentSynchronizer implements IntentSynchronizationService {
 
     private static final Logger log =
         LoggerFactory.getLogger(IntentSynchronizer.class);
 
     private final ApplicationId appId;
     private final IntentService intentService;
-    private final HostService hostService;
-    private final InterfaceService interfaceService;
-    private final Map<IntentKey, PointToPointIntent> peerIntents;
-    private final Map<IpPrefix, MultiPointToSinglePointIntent> routeIntents;
+
+    private final Map<Key, Intent> intents;
 
     //
     // State to deal with SDN-IP Leader election and pushing Intents
     //
     private final ExecutorService bgpIntentsSynchronizerExecutor;
-    private final Semaphore intentsSynchronizerSemaphore = new Semaphore(0);
     private volatile boolean isElectedLeader = false;
     private volatile boolean isActivatedLeader = false;
 
-    private final RoutingConfigurationService configService;
-
     /**
      * Class constructor.
      *
      * @param appId the Application ID
      * @param intentService the intent service
-     * @param hostService the host service
-     * @param configService the SDN-IP configuration service
-     * @param interfaceService the interface service
+     */
+    IntentSynchronizer(ApplicationId appId, IntentService intentService) {
+        this(appId, intentService,
+                newSingleThreadExecutor(groupedThreads("onos/sdnip", "sync")));
+    }
+
+    /**
+     * Class constructor.
+     *
+     * @param appId the Application ID
+     * @param intentService the intent service
+     * @param executorService executor service for synchronization thread
      */
     IntentSynchronizer(ApplicationId appId, IntentService intentService,
-                       HostService hostService,
-                       RoutingConfigurationService configService,
-                       InterfaceService interfaceService) {
+                       ExecutorService executorService) {
         this.appId = appId;
         this.intentService = intentService;
-        this.hostService = hostService;
-        this.interfaceService = interfaceService;
-        peerIntents = new ConcurrentHashMap<>();
-        routeIntents = new ConcurrentHashMap<>();
 
-        this.configService = configService;
+        intents = new ConcurrentHashMap<>();
 
-        bgpIntentsSynchronizerExecutor = Executors.newSingleThreadExecutor(
-                new ThreadFactoryBuilder()
-                .setNameFormat("sdnip-intents-synchronizer-%d").build());
+        bgpIntentsSynchronizerExecutor = executorService;
     }
 
     /**
      * Starts the synchronizer.
      */
     public void start() {
-        bgpIntentsSynchronizerExecutor.execute(this::doIntentSynchronizationThread);
+
     }
 
     /**
@@ -187,6 +148,28 @@
         }
     }
 
+    @Override
+    public void submit(Intent intent) {
+        synchronized (this) {
+            intents.put(intent.key(), intent);
+            if (isElectedLeader && isActivatedLeader) {
+                log.trace("SDN-IP Submitting intent: {}", intent);
+                intentService.submit(intent);
+            }
+        }
+    }
+
+    @Override
+    public void withdraw(Intent intent) {
+        synchronized (this) {
+            intents.remove(intent.key(), intent);
+            if (isElectedLeader && isActivatedLeader) {
+                log.trace("SDN-IP Withdrawing intent: {}", intent);
+                intentService.withdraw(intent);
+            }
+        }
+    }
+
     /**
      * Signals the synchronizer that the SDN-IP leadership has changed.
      *
@@ -203,778 +186,80 @@
         this.isActivatedLeader = false;
         this.isElectedLeader = true;
 
-        //
-        // Tell the Intents Synchronizer thread to start the synchronization
-        //
-        intentsSynchronizerSemaphore.release();
+        // Run the synchronization method off-thread
+        bgpIntentsSynchronizerExecutor.execute(this::synchronizeIntents);
     }
 
-    /**
-     * Gets the route intents.
-     *
-     * @return the route intents
-     */
-    public Collection<MultiPointToSinglePointIntent> getRouteIntents() {
-        List<MultiPointToSinglePointIntent> result = new LinkedList<>();
-
-        for (Map.Entry<IpPrefix, MultiPointToSinglePointIntent> entry :
-            routeIntents.entrySet()) {
-            result.add(entry.getValue());
-        }
-        return result;
-    }
-
-    /**
-     * Thread for Intent Synchronization.
-     */
-    private void doIntentSynchronizationThread() {
-        boolean interrupted = false;
-        try {
-            while (!interrupted) {
-                try {
-                    intentsSynchronizerSemaphore.acquire();
-                    //
-                    // Drain all permits, because a single synchronization is
-                    // sufficient.
-                    //
-                    intentsSynchronizerSemaphore.drainPermits();
-                } catch (InterruptedException e) {
-                    interrupted = true;
-                    break;
-                }
-                synchronizeIntents();
+    private void synchronizeIntents() {
+        Map<Key, Intent> serviceIntents = new HashMap<>();
+        intentService.getIntents().forEach(i -> {
+            if (i.appId().equals(appId)) {
+                serviceIntents.put(i.key(), i);
             }
-        } finally {
-            if (interrupted) {
-                Thread.currentThread().interrupt();
-            }
-        }
-    }
+        });
 
-    /**
-     * Submits a collection of point-to-point intents.
-     *
-     * @param intents the intents to submit
-     */
-    void submitPeerIntents(Collection<PointToPointIntent> intents) {
-        synchronized (this) {
-            // Store the intents in memory
-            for (PointToPointIntent intent : intents) {
-                peerIntents.put(new IntentKey(intent), intent);
-            }
+        List<Intent> intentsToAdd = new LinkedList<>();
+        List<Intent> intentsToRemove = new LinkedList<>();
 
-            // Push the intents
-            if (isElectedLeader && isActivatedLeader) {
-                log.debug("SDN-IP Submitting all Peer Intents...");
-                for (Intent intent : intents) {
-                    log.trace("SDN-IP Submitting intents: {}", intent);
-                    intentService.submit(intent);
-                }
-            }
-        }
-    }
-
-    /**
-     * Submits a MultiPointToSinglePointIntent for reactive routing.
-     *
-     * @param ipPrefix the IP prefix to match in a MultiPointToSinglePointIntent
-     * @param intent the intent to submit
-     */
-    void submitReactiveIntent(IpPrefix ipPrefix, MultiPointToSinglePointIntent intent) {
-        synchronized (this) {
-            // Store the intent in memory
-            routeIntents.put(ipPrefix, intent);
-
-            // Push the intent
-            if (isElectedLeader && isActivatedLeader) {
-                log.trace("SDN-IP submitting reactive routing intent: {}", intent);
-                intentService.submit(intent);
-            }
-        }
-    }
-
-    /**
-     * Generates a route intent for a prefix, the next hop IP address, and
-     * the next hop MAC address.
-     * <p/>
-     * This method will find the egress interface for the intent.
-     * 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 of the route to add
-     * @param nextHopIpAddress  IP address of the next hop
-     * @param nextHopMacAddress MAC address of the next hop
-     * @return the generated intent, or null if no intent should be submitted
-     */
-    private MultiPointToSinglePointIntent generateRouteIntent(
-            IpPrefix prefix,
-            IpAddress nextHopIpAddress,
-            MacAddress nextHopMacAddress) {
-
-        // Find the attachment point (egress interface) of the next hop
-        Interface egressInterface = interfaceService.getMatchingInterface(nextHopIpAddress);
-        if (egressInterface == null) {
-            log.warn("No outgoing interface found for {}",
-                     nextHopIpAddress);
-            return null;
-        }
-
-        //
-        // Generate the intent itself
-        //
-        Set<ConnectPoint> ingressPorts = new HashSet<>();
-        ConnectPoint egressPort = egressInterface.connectPoint();
-        log.debug("Generating intent for prefix {}, next hop mac {}",
-                  prefix, nextHopMacAddress);
-
-        for (Interface intf : interfaceService.getInterfaces()) {
-            // TODO this should be only peering interfaces
-            if (!intf.connectPoint().equals(egressInterface.connectPoint())) {
-                ConnectPoint srcPort = intf.connectPoint();
-                ingressPorts.add(srcPort);
-            }
-        }
-
-        // Match the destination IP prefix at the first hop
-        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
-        if (prefix.isIp4()) {
-            selector.matchEthType(Ethernet.TYPE_IPV4);
-            selector.matchIPDst(prefix);
-        } else {
-            selector.matchEthType(Ethernet.TYPE_IPV6);
-            selector.matchIPv6Dst(prefix);
-        }
-
-        // Rewrite the destination MAC address
-        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
-                .setEthDst(nextHopMacAddress);
-        if (!egressInterface.vlan().equals(VlanId.NONE)) {
-            treatment.setVlanId(egressInterface.vlan());
-            // If we set VLAN ID, we have to make sure a VLAN tag exists.
-            // TODO support no VLAN -> VLAN routing
-            selector.matchVlanId(VlanId.ANY);
-        }
-
-        int priority =
-            prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET;
-        Key key = Key.of(prefix.toString(), appId);
-        return MultiPointToSinglePointIntent.builder()
-                .appId(appId)
-                .key(key)
-                .selector(selector.build())
-                .treatment(treatment.build())
-                .ingressPoints(ingressPorts)
-                .egressPoint(egressPort)
-                .priority(priority)
-                .constraints(CONSTRAINTS)
-                .build();
-    }
-
-    @Override
-    public void setUpConnectivityInternetToHost(IpAddress hostIpAddress) {
-        checkNotNull(hostIpAddress);
-        Set<ConnectPoint> ingressPoints =
-                configService.getBgpPeerConnectPoints();
-
-        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
-
-        if (hostIpAddress.isIp4()) {
-            selector.matchEthType(Ethernet.TYPE_IPV4);
-        } else {
-            selector.matchEthType(Ethernet.TYPE_IPV6);
-        }
-
-        // Match the destination IP prefix at the first hop
-        IpPrefix ipPrefix = hostIpAddress.toIpPrefix();
-        selector.matchIPDst(ipPrefix);
-
-        // Rewrite the destination MAC address
-        MacAddress hostMac = null;
-        ConnectPoint egressPoint = null;
-        for (Host host : hostService.getHostsByIp(hostIpAddress)) {
-            if (host.mac() != null) {
-                hostMac = host.mac();
-                egressPoint = host.location();
-                break;
-            }
-        }
-        if (hostMac == null) {
-            hostService.startMonitoringIp(hostIpAddress);
-            return;
-        }
-
-        TrafficTreatment.Builder treatment =
-                DefaultTrafficTreatment.builder().setEthDst(hostMac);
-        Key key = Key.of(ipPrefix.toString(), appId);
-        int priority = ipPrefix.prefixLength() * PRIORITY_MULTIPLIER
-                + PRIORITY_OFFSET;
-        MultiPointToSinglePointIntent intent =
-                MultiPointToSinglePointIntent.builder()
-                .appId(appId)
-                .key(key)
-                .selector(selector.build())
-                .treatment(treatment.build())
-                .ingressPoints(ingressPoints)
-                .egressPoint(egressPoint)
-                .priority(priority)
-                .constraints(CONSTRAINTS)
-                .build();
-
-        log.trace("Generates ConnectivityInternetToHost intent {}", intent);
-        submitReactiveIntent(ipPrefix, intent);
-    }
-
-
-    @Override
-    public void update(Collection<FibUpdate> updates, Collection<FibUpdate> withdraws) {
-        //
-        // NOTE: Semantically, we MUST withdraw existing intents before
-        // submitting new intents.
-        //
-        synchronized (this) {
-            MultiPointToSinglePointIntent intent;
-
-            log.debug("SDN-IP submitting intents = {} withdrawing = {}",
-                     updates.size(), withdraws.size());
-
-            //
-            // Prepare the Intent batch operations for the intents to withdraw
-            //
-            for (FibUpdate withdraw : withdraws) {
-                checkArgument(withdraw.type() == FibUpdate.Type.DELETE,
-                              "FibUpdate with wrong type in withdraws list");
-
-                IpPrefix prefix = withdraw.entry().prefix();
-                intent = routeIntents.remove(prefix);
-                if (intent == null) {
-                    log.trace("SDN-IP No intent in routeIntents to delete " +
-                              "for prefix: {}", prefix);
-                    continue;
-                }
-                if (isElectedLeader && isActivatedLeader) {
-                    log.trace("SDN-IP Withdrawing intent: {}", intent);
-                    intentService.withdraw(intent);
-                }
-            }
-
-            //
-            // Prepare the Intent batch operations for the intents to submit
-            //
-            for (FibUpdate update : updates) {
-                checkArgument(update.type() == FibUpdate.Type.UPDATE,
-                              "FibUpdate with wrong type in updates list");
-
-                IpPrefix prefix = update.entry().prefix();
-                intent = generateRouteIntent(prefix, update.entry().nextHopIp(),
-                                             update.entry().nextHopMac());
-
-                if (intent == null) {
-                    // This preserves the old semantics - if an intent can't be
-                    // generated, we don't do anything with that prefix. But
-                    // perhaps we should withdraw the old intent anyway?
-                    continue;
-                }
-
-                MultiPointToSinglePointIntent oldIntent =
-                    routeIntents.put(prefix, intent);
-                if (isElectedLeader && isActivatedLeader) {
-                    if (oldIntent != null) {
-                        log.trace("SDN-IP Withdrawing old intent: {}",
-                                  oldIntent);
-                        intentService.withdraw(oldIntent);
-                    }
-                    log.trace("SDN-IP Submitting intent: {}", intent);
-                    intentService.submit(intent);
-                }
-            }
-        }
-    }
-
-    /**
-     * Synchronize the in-memory Intents with the Intents in the Intent
-     * framework.
-     */
-    void synchronizeIntents() {
-        synchronized (this) {
-
-            Map<IntentKey, Intent> localIntents = new HashMap<>();
-            Map<IntentKey, Intent> fetchedIntents = new HashMap<>();
-            Collection<Intent> storeInMemoryIntents = new LinkedList<>();
-            Collection<Intent> addIntents = new LinkedList<>();
-            Collection<Intent> deleteIntents = new LinkedList<>();
-
-            if (!isElectedLeader) {
-                return;         // Nothing to do: not the leader anymore
-            }
-            log.debug("SDN-IP synchronizing all intents...");
-
-            // Prepare the local intents
-            for (Intent intent : routeIntents.values()) {
-                localIntents.put(new IntentKey(intent), intent);
-            }
-            for (Intent intent : peerIntents.values()) {
-                localIntents.put(new IntentKey(intent), intent);
-            }
-
-            // Fetch all intents for this application
-            for (Intent intent : intentService.getIntents()) {
-                if (!intent.appId().equals(appId)) {
-                    continue;
-                }
-                fetchedIntents.put(new IntentKey(intent), intent);
-            }
-            if (log.isDebugEnabled()) {
-                for (Intent intent: fetchedIntents.values()) {
-                    log.trace("SDN-IP Intent Synchronizer: fetched intent: {}",
-                              intent);
-                }
-            }
-
-            computeIntentsDelta(localIntents, fetchedIntents,
-                                storeInMemoryIntents, addIntents,
-                                deleteIntents);
-
-            //
-            // Perform the actions:
-            // 1. Store in memory fetched intents that are same. Can be done
-            //    even if we are not the leader anymore
-            // 2. Delete intents: check if the leader before the operation
-            // 3. Add intents: check if the leader before the operation
-            //
-            for (Intent intent : storeInMemoryIntents) {
-                // Store the intent in memory based on its type
-                if (intent instanceof MultiPointToSinglePointIntent) {
-                    MultiPointToSinglePointIntent mp2pIntent =
-                        (MultiPointToSinglePointIntent) intent;
-                    // Find the IP prefix
-                    Criterion c =
-                        mp2pIntent.selector().getCriterion(Criterion.Type.IPV4_DST);
-                    if (c == null) {
-                        // Try IPv6
-                        c =
-                            mp2pIntent.selector().getCriterion(Criterion.Type.IPV6_DST);
-                    }
-                    if (c != null && c instanceof IPCriterion) {
-                        IPCriterion ipCriterion = (IPCriterion) c;
-                        IpPrefix ipPrefix = ipCriterion.ip();
-                        if (ipPrefix == null) {
-                            continue;
-                        }
-                        log.trace("SDN-IP Intent Synchronizer: updating " +
-                                  "in-memory Route Intent for prefix {}",
-                                  ipPrefix);
-                        routeIntents.put(ipPrefix, mp2pIntent);
-                    } else {
-                        log.warn("SDN-IP no IPV4_DST or IPV6_DST criterion found for Intent {}",
-                                 mp2pIntent.id());
-                    }
-                    continue;
-                }
-                if (intent instanceof PointToPointIntent) {
-                    PointToPointIntent p2pIntent = (PointToPointIntent) intent;
-                    log.trace("SDN-IP Intent Synchronizer: updating " +
-                              "in-memory Peer Intent {}", p2pIntent);
-                    peerIntents.put(new IntentKey(intent), p2pIntent);
-                    continue;
-                }
-            }
-
-            // Withdraw Intents
-            for (Intent intent : deleteIntents) {
-                intentService.withdraw(intent);
-                log.trace("SDN-IP Intent Synchronizer: withdrawing intent: {}",
-                      intent);
-            }
-            if (!isElectedLeader) {
-                log.trace("SDN-IP Intent Synchronizer: cannot withdraw intents: " +
-                          "not elected leader anymore");
-                isActivatedLeader = false;
-                return;
-            }
-
-            // Add Intents
-            for (Intent intent : addIntents) {
-                intentService.submit(intent);
-                log.trace("SDN-IP Intent Synchronizer: submitting intent: {}",
-                          intent);
-            }
-            if (!isElectedLeader) {
-                log.trace("SDN-IP Intent Synchronizer: cannot submit intents: " +
-                          "not elected leader anymore");
-                isActivatedLeader = false;
-                return;
-            }
-
-            if (isElectedLeader) {
-                isActivatedLeader = true;       // Allow push of Intents
+        for (Intent localIntent : intents.values()) {
+            Intent serviceIntent = serviceIntents.remove(localIntent.key());
+            if (serviceIntent == null) {
+                intentsToAdd.add(localIntent);
             } else {
-                isActivatedLeader = false;
-            }
-            log.debug("SDN-IP intent synchronization completed");
-        }
-    }
-
-    /**
-     * Computes the delta in two sets of Intents: local in-memory Intents,
-     * and intents fetched from the Intent framework.
-     *
-     * @param localIntents the local in-memory Intents
-     * @param fetchedIntents the Intents fetched from the Intent framework
-     * @param storeInMemoryIntents the Intents that should be stored in memory.
-     * Note: This Collection must be allocated by the caller, and it will
-     * be populated by this method.
-     * @param addIntents the Intents that should be added to the Intent
-     * framework. Note: This Collection must be allocated by the caller, and
-     * it will be populated by this method.
-     * @param deleteIntents the Intents that should be deleted from the Intent
-     * framework. Note: This Collection must be allocated by the caller, and
-     * it will be populated by this method.
-     */
-    private void computeIntentsDelta(
-                                final Map<IntentKey, Intent> localIntents,
-                                final Map<IntentKey, Intent> fetchedIntents,
-                                Collection<Intent> storeInMemoryIntents,
-                                Collection<Intent> addIntents,
-                                Collection<Intent> deleteIntents) {
-
-        //
-        // Compute the deltas between the LOCAL in-memory Intents and the
-        // FETCHED Intents:
-        //  - If an Intent is in both the LOCAL and FETCHED sets:
-        //    If the FETCHED Intent is WITHDRAWING or WITHDRAWN, then
-        //    the LOCAL Intent should be added/installed; otherwise the
-        //    FETCHED intent should be stored in the local memory
-        //    (i.e., override the LOCAL Intent) to preserve the original
-        //    Intent ID.
-        //  - if a LOCAL Intent is not in the FETCHED set, then the LOCAL
-        //    Intent should be added/installed.
-        //  - If a FETCHED Intent is not in the LOCAL set, then the FETCHED
-        //    Intent should be deleted/withdrawn.
-        //
-        for (Map.Entry<IntentKey, Intent> entry : localIntents.entrySet()) {
-            IntentKey intentKey = entry.getKey();
-            Intent localIntent = entry.getValue();
-            Intent fetchedIntent = fetchedIntents.get(intentKey);
-
-            if (fetchedIntent == null) {
-                //
-                // No FETCHED Intent found: push the LOCAL Intent.
-                //
-                addIntents.add(localIntent);
-                continue;
-            }
-
-            IntentState state =
-                intentService.getIntentState(fetchedIntent.key());
-            if (state == null ||
-                state == IntentState.WITHDRAWING ||
-                state == IntentState.WITHDRAWN) {
-                // The intent has been withdrawn but according to our route
-                // table it should be installed. We'll reinstall it.
-                addIntents.add(localIntent);
-                continue;
-            }
-            storeInMemoryIntents.add(fetchedIntent);
-        }
-
-        for (Map.Entry<IntentKey, Intent> entry : fetchedIntents.entrySet()) {
-            IntentKey intentKey = entry.getKey();
-            Intent fetchedIntent = entry.getValue();
-            Intent localIntent = localIntents.get(intentKey);
-
-            if (localIntent != null) {
-                continue;
-            }
-
-            IntentState state =
-                intentService.getIntentState(fetchedIntent.key());
-            if (state == null ||
-                state == IntentState.WITHDRAWING ||
-                state == IntentState.WITHDRAWN) {
-                // Nothing to do. The intent has been already withdrawn.
-                continue;
-            }
-            //
-            // No LOCAL Intent found: delete/withdraw the FETCHED Intent.
-            //
-            deleteIntents.add(fetchedIntent);
-        }
-    }
-
-    /**
-     * Helper class that can be used to compute the key for an Intent by
-     * by excluding the Intent ID.
-     */
-    static final class IntentKey {
-        private final Intent intent;
-
-        /**
-         * Constructor.
-         *
-         * @param intent the intent to use
-         */
-        IntentKey(Intent intent) {
-            checkArgument((intent instanceof MultiPointToSinglePointIntent) ||
-                          (intent instanceof PointToPointIntent),
-                          "Intent type not recognized", intent);
-            this.intent = intent;
-        }
-
-        /**
-         * Compares two Multi-Point to Single-Point Intents whether they
-         * represent same logical intention.
-         *
-         * @param intent1 the first Intent to compare
-         * @param intent2 the second Intent to compare
-         * @return true if both Intents represent same logical intention,
-         * otherwise false
-         */
-        static boolean equalIntents(MultiPointToSinglePointIntent intent1,
-                                    MultiPointToSinglePointIntent intent2) {
-            return Objects.equals(intent1.appId(), intent2.appId()) &&
-                Objects.equals(intent1.selector(), intent2.selector()) &&
-                Objects.equals(intent1.treatment(), intent2.treatment()) &&
-                Objects.equals(intent1.ingressPoints(), intent2.ingressPoints()) &&
-                Objects.equals(intent1.egressPoint(), intent2.egressPoint());
-        }
-
-        /**
-         * Compares two Point-to-Point Intents whether they represent
-         * same logical intention.
-         *
-         * @param intent1 the first Intent to compare
-         * @param intent2 the second Intent to compare
-         * @return true if both Intents represent same logical intention,
-         * otherwise false
-         */
-        static boolean equalIntents(PointToPointIntent intent1,
-                                    PointToPointIntent intent2) {
-            return Objects.equals(intent1.appId(), intent2.appId()) &&
-                Objects.equals(intent1.selector(), intent2.selector()) &&
-                Objects.equals(intent1.treatment(), intent2.treatment()) &&
-                Objects.equals(intent1.ingressPoint(), intent2.ingressPoint()) &&
-                Objects.equals(intent1.egressPoint(), intent2.egressPoint());
-        }
-
-        @Override
-        public int hashCode() {
-            if (intent instanceof PointToPointIntent) {
-                PointToPointIntent p2pIntent = (PointToPointIntent) intent;
-                return Objects.hash(p2pIntent.appId(),
-                                    p2pIntent.resources(),
-                                    p2pIntent.selector(),
-                                    p2pIntent.treatment(),
-                                    p2pIntent.constraints(),
-                                    p2pIntent.ingressPoint(),
-                                    p2pIntent.egressPoint());
-            }
-            if (intent instanceof MultiPointToSinglePointIntent) {
-                MultiPointToSinglePointIntent m2pIntent =
-                    (MultiPointToSinglePointIntent) intent;
-                return Objects.hash(m2pIntent.appId(),
-                                    m2pIntent.resources(),
-                                    m2pIntent.selector(),
-                                    m2pIntent.treatment(),
-                                    m2pIntent.constraints(),
-                                    m2pIntent.ingressPoints(),
-                                    m2pIntent.egressPoint());
-            }
-            checkArgument(false, "Intent type not recognized", intent);
-            return 0;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if ((obj == null) || (!(obj instanceof IntentKey))) {
-                return false;
-            }
-            IntentKey other = (IntentKey) obj;
-
-            if (this.intent instanceof PointToPointIntent) {
-                if (!(other.intent instanceof PointToPointIntent)) {
-                    return false;
+                IntentState state = intentService.getIntentState(serviceIntent.key());
+                if (!IntentUtils.equals(serviceIntent, localIntent) || state == null ||
+                        state == IntentState.WITHDRAW_REQ ||
+                        state == IntentState.WITHDRAWING ||
+                        state == IntentState.WITHDRAWN) {
+                    intentsToAdd.add(localIntent);
                 }
-                return equalIntents((PointToPointIntent) this.intent,
-                                    (PointToPointIntent) other.intent);
-            }
-            if (this.intent instanceof MultiPointToSinglePointIntent) {
-                if (!(other.intent instanceof MultiPointToSinglePointIntent)) {
-                    return false;
-                }
-                return equalIntents(
-                                (MultiPointToSinglePointIntent) this.intent,
-                                (MultiPointToSinglePointIntent) other.intent);
-            }
-            checkArgument(false, "Intent type not recognized", intent);
-            return false;
-        }
-    }
-
-    @Override
-    public void setUpConnectivityHostToHost(IpAddress dstIpAddress,
-                                            IpAddress srcIpAddress,
-                                            MacAddress srcMacAddress,
-                                            ConnectPoint srcConnectPoint) {
-        checkNotNull(dstIpAddress);
-        checkNotNull(srcIpAddress);
-        checkNotNull(srcMacAddress);
-        checkNotNull(srcConnectPoint);
-
-        IpPrefix srcIpPrefix = srcIpAddress.toIpPrefix();
-        IpPrefix dstIpPrefix = dstIpAddress.toIpPrefix();
-        ConnectPoint dstConnectPoint = null;
-        MacAddress dstMacAddress = null;
-
-        for (Host host : hostService.getHostsByIp(dstIpAddress)) {
-            if (host.mac() != null) {
-                dstMacAddress = host.mac();
-                dstConnectPoint = host.location();
-                break;
             }
         }
-        if (dstMacAddress == null) {
-            hostService.startMonitoringIp(dstIpAddress);
+
+        for (Intent serviceIntent : serviceIntents.values()) {
+            IntentState state = intentService.getIntentState(serviceIntent.key());
+            if (state != null && state != IntentState.WITHDRAW_REQ
+                    && state != IntentState.WITHDRAWING
+                    && state != IntentState.WITHDRAWN) {
+                intentsToRemove.add(serviceIntent);
+            }
+        }
+
+        log.debug("SDN-IP Intent Synchronizer: submitting {}, withdrawing {}",
+                intentsToAdd.size(), intentsToRemove.size());
+
+        // Withdraw Intents
+        for (Intent intent : intentsToRemove) {
+            intentService.withdraw(intent);
+            log.trace("SDN-IP Intent Synchronizer: withdrawing intent: {}",
+                    intent);
+        }
+        if (!isElectedLeader) {
+            log.debug("SDN-IP Intent Synchronizer: cannot withdraw intents: " +
+                    "not elected leader anymore");
+            isActivatedLeader = false;
             return;
         }
 
-        //
-        // Handle intent from source host to destination host
-        //
-        MultiPointToSinglePointIntent srcToDstIntent =
-                hostToHostIntentGenerator(dstIpAddress, dstConnectPoint,
-                                    dstMacAddress, srcConnectPoint);
-        submitReactiveIntent(dstIpPrefix, srcToDstIntent);
-
-        //
-        // Handle intent from destination host to source host
-        //
-
-        // Since we proactively handle the intent from destination host to
-        // source host, we should check whether there is an exiting intent
-        // first.
-        if (mp2pIntentExists(srcIpPrefix)) {
-            updateExistingMp2pIntent(srcIpPrefix, dstConnectPoint);
+        // Add Intents
+        for (Intent intent : intentsToAdd) {
+            intentService.submit(intent);
+            log.trace("SDN-IP Intent Synchronizer: submitting intent: {}",
+                    intent);
+        }
+        if (!isElectedLeader) {
+            log.debug("SDN-IP Intent Synchronizer: cannot submit intents: " +
+                    "not elected leader anymore");
+            isActivatedLeader = false;
             return;
+        }
+
+        if (isElectedLeader) {
+            isActivatedLeader = true;       // Allow push of Intents
         } else {
-            // There is no existing intent, create a new one.
-            MultiPointToSinglePointIntent dstToSrcIntent =
-                    hostToHostIntentGenerator(srcIpAddress, srcConnectPoint,
-                                        srcMacAddress, dstConnectPoint);
-            submitReactiveIntent(srcIpPrefix, dstToSrcIntent);
+            isActivatedLeader = false;
         }
+        log.debug("SDN-IP intent synchronization completed");
     }
 
-    /**
-     * Generates MultiPointToSinglePointIntent for both source host and
-     * destination host located in local SDN network.
-     *
-     * @param dstIpAddress the destination IP address
-     * @param dstConnectPoint the destination host connect point
-     * @param dstMacAddress the MAC address of destination host
-     * @param srcConnectPoint the connect point where packet-in from
-     * @return the generated MultiPointToSinglePointIntent
-     */
-    private MultiPointToSinglePointIntent hostToHostIntentGenerator(
-                                       IpAddress dstIpAddress,
-                                       ConnectPoint dstConnectPoint,
-                                       MacAddress dstMacAddress,
-                                       ConnectPoint srcConnectPoint) {
-        checkNotNull(dstIpAddress);
-        checkNotNull(dstConnectPoint);
-        checkNotNull(dstMacAddress);
-        checkNotNull(srcConnectPoint);
-
-        Set<ConnectPoint> ingressPoints = new HashSet<>();
-        ingressPoints.add(srcConnectPoint);
-        IpPrefix dstIpPrefix = dstIpAddress.toIpPrefix();
-
-        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
-        if (dstIpAddress.isIp4()) {
-            selector.matchEthType(Ethernet.TYPE_IPV4);
-            selector.matchIPDst(dstIpPrefix);
-        } else {
-            selector.matchEthType(Ethernet.TYPE_IPV6);
-            selector.matchIPv6Dst(dstIpPrefix);
-        }
-
-        // Rewrite the destination MAC address
-        TrafficTreatment.Builder treatment =
-                DefaultTrafficTreatment.builder().setEthDst(dstMacAddress);
-
-        Key key = Key.of(dstIpPrefix.toString(), appId);
-        int priority = dstIpPrefix.prefixLength() * PRIORITY_MULTIPLIER
-                + PRIORITY_OFFSET;
-        MultiPointToSinglePointIntent intent =
-                MultiPointToSinglePointIntent.builder()
-                .appId(appId)
-                .key(key)
-                .selector(selector.build())
-                .treatment(treatment.build())
-                .ingressPoints(ingressPoints)
-                .egressPoint(dstConnectPoint)
-                .priority(priority)
-                .constraints(CONSTRAINTS)
-                .build();
-
-        log.trace("Generates ConnectivityHostToHost = {} ", intent);
-        return intent;
-    }
-
-    @Override
-    public void updateExistingMp2pIntent(IpPrefix ipPrefix,
-                                         ConnectPoint ingressConnectPoint) {
-        checkNotNull(ipPrefix);
-        checkNotNull(ingressConnectPoint);
-
-        MultiPointToSinglePointIntent existingIntent =
-                getExistingMp2pIntent(ipPrefix);
-        if (existingIntent != null) {
-            Set<ConnectPoint> ingressPoints = existingIntent.ingressPoints();
-            // Add host connect point into ingressPoints of the existing intent
-            if (ingressPoints.add(ingressConnectPoint)) {
-                MultiPointToSinglePointIntent updatedMp2pIntent =
-                        MultiPointToSinglePointIntent.builder()
-                        .appId(appId)
-                        .key(existingIntent.key())
-                        .selector(existingIntent.selector())
-                        .treatment(existingIntent.treatment())
-                        .ingressPoints(ingressPoints)
-                        .egressPoint(existingIntent.egressPoint())
-                        .priority(existingIntent.priority())
-                        .constraints(CONSTRAINTS)
-                        .build();
-
-                log.trace("Update an existing MultiPointToSinglePointIntent "
-                        + "to new intent = {} ", updatedMp2pIntent);
-                submitReactiveIntent(ipPrefix, updatedMp2pIntent);
-            }
-            // If adding ingressConnectPoint to ingressPoints failed, it
-            // because between the time interval from checking existing intent
-            // to generating new intent, onos updated this intent due to other
-            // packet-in and the new intent also includes the
-            // ingressConnectPoint. This will not affect reactive routing.
-        }
-    }
-
-    @Override
-    public boolean mp2pIntentExists(IpPrefix ipPrefix) {
-        checkNotNull(ipPrefix);
-        return routeIntents.get(ipPrefix) != null;
-    }
-
-    /**
-     * Gets the existing MultiPointToSinglePointIntent from memory for a given
-     * IP prefix.
-     *
-     * @param ipPrefix the IP prefix used to find MultiPointToSinglePointIntent
-     * @return the MultiPointToSinglePointIntent if found, otherwise null
-     */
-    private MultiPointToSinglePointIntent getExistingMp2pIntent(IpPrefix
-                                                                ipPrefix) {
-        checkNotNull(ipPrefix);
-        return routeIntents.get(ipPrefix);
-    }
 }
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentUtils.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentUtils.java
new file mode 100644
index 0000000..8e2a3df
--- /dev/null
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentUtils.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdnip;
+
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.net.intent.PointToPointIntent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Utilities for dealing with intents.
+ */
+public final class IntentUtils {
+
+    private static final Logger log = LoggerFactory.getLogger(IntentUtils.class);
+
+    private IntentUtils() {
+
+    }
+
+    /**
+     * Checks if two intents represent the same value.
+     *
+     * <p>({@link Intent#equals(Object)} only checks ID equality)</p>
+     *
+     * <p>Both intents must be of the same type.</p>
+     *
+     * @param one first intent
+     * @param two second intent
+     * @return true if the two intents represent the same value, otherwise false
+     */
+    public static boolean equals(Intent one, Intent two) {
+        checkArgument(one.getClass() == two.getClass(),
+                "Intents are not the same type");
+
+        if (!(Objects.equals(one.appId(), two.appId()) &&
+                Objects.equals(one.key(), two.key()))) {
+            return false;
+        }
+
+        if (one instanceof MultiPointToSinglePointIntent) {
+            MultiPointToSinglePointIntent intent1 = (MultiPointToSinglePointIntent) one;
+            MultiPointToSinglePointIntent intent2 = (MultiPointToSinglePointIntent) two;
+
+            return Objects.equals(intent1.selector(), intent2.selector()) &&
+                    Objects.equals(intent1.treatment(), intent2.treatment()) &&
+                    Objects.equals(intent1.ingressPoints(), intent2.ingressPoints()) &&
+                    Objects.equals(intent1.egressPoint(), intent2.egressPoint());
+        } else if (one instanceof PointToPointIntent) {
+            PointToPointIntent intent1 = (PointToPointIntent) one;
+            PointToPointIntent intent2 = (PointToPointIntent) two;
+
+            return Objects.equals(intent1.selector(), intent2.selector()) &&
+                    Objects.equals(intent1.treatment(), intent2.treatment()) &&
+                    Objects.equals(intent1.ingressPoint(), intent2.ingressPoint()) &&
+                    Objects.equals(intent1.egressPoint(), intent2.egressPoint());
+        } else {
+            log.error("Unimplemented intent type");
+            return false;
+        }
+    }
+}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
index 459db2b..b2ce0f8 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
@@ -15,6 +15,8 @@
  */
 package org.onosproject.sdnip;
 
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.IPv4;
 import org.onlab.packet.IPv6;
@@ -22,16 +24,18 @@
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.TpPort;
 import org.onosproject.core.ApplicationId;
-import org.onosproject.net.config.NetworkConfigService;
 import org.onosproject.incubator.net.intf.Interface;
 import org.onosproject.incubator.net.intf.InterfaceService;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.config.NetworkConfigService;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.intent.Key;
 import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.routing.IntentSynchronizationService;
 import org.onosproject.routing.RoutingService;
 import org.onosproject.routing.config.BgpConfig;
 import org.slf4j.Logger;
@@ -49,18 +53,26 @@
 public class PeerConnectivityManager {
     private static final int PRIORITY_OFFSET = 1000;
 
+    private static final String SUFFIX_DST = "dst";
+    private static final String SUFFIX_SRC = "src";
+    private static final String SUFFIX_ICMP = "icmp";
+
     private static final Logger log = LoggerFactory.getLogger(
             PeerConnectivityManager.class);
 
     private static final short BGP_PORT = 179;
 
-    private final IntentSynchronizer intentSynchronizer;
+    private final IntentSynchronizationService intentSynchronizer;
     private final NetworkConfigService configService;
     private final InterfaceService interfaceService;
 
     private final ApplicationId appId;
     private final ApplicationId routerAppId;
 
+    // Just putting something random here for now. Figure out exactly what
+    // indexes we need when we start making use of them.
+    private final Multimap<BgpConfig.BgpSpeakerConfig, PointToPointIntent> peerIntents;
+
     /**
      * Creates a new PeerConnectivityManager.
      *
@@ -71,7 +83,7 @@
      * @param routerAppId        application ID
      */
     public PeerConnectivityManager(ApplicationId appId,
-                                   IntentSynchronizer intentSynchronizer,
+                                   IntentSynchronizationService intentSynchronizer,
                                    NetworkConfigService configService,
                                    ApplicationId routerAppId,
                                    InterfaceService interfaceService) {
@@ -80,6 +92,8 @@
         this.configService = configService;
         this.routerAppId = routerAppId;
         this.interfaceService = interfaceService;
+
+        peerIntents = HashMultimap.create();
     }
 
     /**
@@ -100,8 +114,6 @@
      * BGP speakers and external BGP peers.
      */
     private void setUpConnectivity() {
-        List<PointToPointIntent> intents = new ArrayList<>();
-
         BgpConfig config = configService.getConfig(routerAppId, RoutingService.CONFIG_CLASS);
 
         if (config == null) {
@@ -113,11 +125,12 @@
             log.debug("Start to set up BGP paths for BGP speaker: {}",
                     bgpSpeaker);
 
-            intents.addAll(buildSpeakerIntents(bgpSpeaker));
-        }
+            buildSpeakerIntents(bgpSpeaker).forEach(i -> {
+                peerIntents.put(bgpSpeaker, i);
+                intentSynchronizer.submit(i);
+            });
 
-        // Submit all the intents.
-        intentSynchronizer.submitPeerIntents(intents);
+        }
     }
 
     private Collection<PointToPointIntent> buildSpeakerIntents(BgpConfig.BgpSpeakerConfig speaker) {
@@ -167,8 +180,8 @@
         List<PointToPointIntent> intents = new ArrayList<>();
 
         TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
-
         TrafficSelector selector;
+        Key key;
 
         byte tcpProtocol;
         byte icmpProtocol;
@@ -188,8 +201,11 @@
                 null,
                 BGP_PORT);
 
+        key = buildKey(ipOne, ipTwo, SUFFIX_DST);
+
         intents.add(PointToPointIntent.builder()
                 .appId(appId)
+                .key(key)
                 .selector(selector)
                 .treatment(treatment)
                 .ingressPoint(portOne)
@@ -204,8 +220,11 @@
                 BGP_PORT,
                 null);
 
+        key = buildKey(ipOne, ipTwo, SUFFIX_SRC);
+
         intents.add(PointToPointIntent.builder()
                 .appId(appId)
+                .key(key)
                 .selector(selector)
                 .treatment(treatment)
                 .ingressPoint(portOne)
@@ -220,8 +239,11 @@
                 null,
                 BGP_PORT);
 
+        key = buildKey(ipTwo, ipOne, SUFFIX_DST);
+
         intents.add(PointToPointIntent.builder()
                 .appId(appId)
+                .key(key)
                 .selector(selector)
                 .treatment(treatment)
                 .ingressPoint(portTwo)
@@ -236,8 +258,11 @@
                 BGP_PORT,
                 null);
 
+        key = buildKey(ipTwo, ipOne, SUFFIX_SRC);
+
         intents.add(PointToPointIntent.builder()
                 .appId(appId)
+                .key(key)
                 .selector(selector)
                 .treatment(treatment)
                 .ingressPoint(portTwo)
@@ -252,8 +277,11 @@
                 null,
                 null);
 
+        key = buildKey(ipOne, ipTwo, SUFFIX_ICMP);
+
         intents.add(PointToPointIntent.builder()
                 .appId(appId)
+                .key(key)
                 .selector(selector)
                 .treatment(treatment)
                 .ingressPoint(portOne)
@@ -268,8 +296,11 @@
                 null,
                 null);
 
+        key = buildKey(ipTwo, ipOne, SUFFIX_ICMP);
+
         intents.add(PointToPointIntent.builder()
                 .appId(appId)
+                .key(key)
                 .selector(selector)
                 .treatment(treatment)
                 .ingressPoint(portTwo)
@@ -316,4 +347,27 @@
         return builder.build();
     }
 
+    /**
+     * Builds an intent Key for a point-to-point intent based off the source
+     * and destination IP address, as well as a suffix String to distinguish
+     * between different types of intents between the same source and
+     * destination.
+     *
+     * @param srcIp source IP address
+     * @param dstIp destination IP address
+     * @param suffix suffix string
+     * @return
+     */
+    private Key buildKey(IpAddress srcIp, IpAddress dstIp, String suffix) {
+        String keyString = new StringBuilder()
+                .append(srcIp.toString())
+                .append("-")
+                .append(dstIp.toString())
+                .append("-")
+                .append(suffix)
+                .toString();
+
+        return Key.of(keyString, appId);
+    }
+
 }
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java
index 3d1fe65..1b3eda9 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java
@@ -32,7 +32,9 @@
 import org.onosproject.incubator.net.intf.InterfaceService;
 import org.onosproject.net.host.HostService;
 import org.onosproject.net.intent.IntentService;
+import org.onosproject.routing.IntentSynchronizationService;
 import org.onosproject.routing.RoutingService;
+import org.onosproject.routing.SdnIpService;
 import org.onosproject.routing.config.RoutingConfigurationService;
 import org.slf4j.Logger;
 
@@ -79,6 +81,7 @@
 
     private IntentSynchronizer intentSynchronizer;
     private PeerConnectivityManager peerConnectivity;
+    private SdnIpFib fib;
 
     private LeadershipEventListener leadershipEventListener =
         new InnerLeadershipEventListener();
@@ -93,10 +96,7 @@
 
         localControllerNode = clusterService.getLocalNode();
 
-        intentSynchronizer = new IntentSynchronizer(appId, intentService,
-                                                    hostService,
-                                                    config,
-                                                    interfaceService);
+        intentSynchronizer = new IntentSynchronizer(appId, intentService);
         intentSynchronizer.start();
 
         peerConnectivity = new PeerConnectivityManager(appId,
@@ -106,8 +106,9 @@
                                                        interfaceService);
         peerConnectivity.start();
 
-        routingService.addFibListener(intentSynchronizer);
-        routingService.addIntentRequestListener(intentSynchronizer);
+        fib = new SdnIpFib(appId, interfaceService, intentSynchronizer);
+
+        routingService.addFibListener(fib);
         routingService.start();
 
         leadershipService.addListener(leadershipEventListener);
@@ -131,6 +132,11 @@
         intentSynchronizer.leaderChanged(isPrimary);
     }
 
+    @Override
+    public IntentSynchronizationService getIntentSynchronizationService() {
+        return intentSynchronizer;
+    }
+
     /**
      * Converts DPIDs of the form xx:xx:xx:xx:xx:xx:xx to OpenFlow provider
      * device URIs.
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java
new file mode 100644
index 0000000..c0001bd
--- /dev/null
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdnip;
+
+import com.google.common.collect.ImmutableList;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.net.intent.constraint.PartialFailureConstraint;
+import org.onosproject.routing.FibListener;
+import org.onosproject.routing.FibUpdate;
+import org.onosproject.routing.IntentSynchronizationService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * FIB component of SDN-IP.
+ */
+public class SdnIpFib implements FibListener {
+    private Logger log = LoggerFactory.getLogger(getClass());
+
+    private static final int PRIORITY_OFFSET = 100;
+    private static final int PRIORITY_MULTIPLIER = 5;
+    protected static final ImmutableList<Constraint> CONSTRAINTS
+            = ImmutableList.of(new PartialFailureConstraint());
+
+    private final Map<IpPrefix, MultiPointToSinglePointIntent> routeIntents;
+
+    private final ApplicationId appId;
+    private final InterfaceService interfaceService;
+    private final IntentSynchronizationService intentSynchronizer;
+
+    /**
+     * Class constructor.
+     *
+     * @param appId application ID to use when generating intents
+     * @param interfaceService interface service
+     * @param intentSynchronizer intent synchronizer
+     */
+    public SdnIpFib(ApplicationId appId, InterfaceService interfaceService,
+                    IntentSynchronizationService intentSynchronizer) {
+        routeIntents = new ConcurrentHashMap<>();
+
+        this.appId = appId;
+        this.interfaceService = interfaceService;
+        this.intentSynchronizer = intentSynchronizer;
+    }
+
+
+    @Override
+    public void update(Collection<FibUpdate> updates, Collection<FibUpdate> withdraws) {
+        int submitCount = 0, withdrawCount = 0;
+        //
+        // NOTE: Semantically, we MUST withdraw existing intents before
+        // submitting new intents.
+        //
+        synchronized (this) {
+            MultiPointToSinglePointIntent intent;
+
+            //
+            // Prepare the Intent batch operations for the intents to withdraw
+            //
+            for (FibUpdate withdraw : withdraws) {
+                checkArgument(withdraw.type() == FibUpdate.Type.DELETE,
+                        "FibUpdate with wrong type in withdraws list");
+
+                IpPrefix prefix = withdraw.entry().prefix();
+                intent = routeIntents.remove(prefix);
+                if (intent == null) {
+                    log.trace("SDN-IP No intent in routeIntents to delete " +
+                            "for prefix: {}", prefix);
+                    continue;
+                }
+                intentSynchronizer.withdraw(intent);
+                withdrawCount++;
+            }
+
+            //
+            // Prepare the Intent batch operations for the intents to submit
+            //
+            for (FibUpdate update : updates) {
+                checkArgument(update.type() == FibUpdate.Type.UPDATE,
+                        "FibUpdate with wrong type in updates list");
+
+                IpPrefix prefix = update.entry().prefix();
+                intent = generateRouteIntent(prefix, update.entry().nextHopIp(),
+                        update.entry().nextHopMac());
+
+                if (intent == null) {
+                    // This preserves the old semantics - if an intent can't be
+                    // generated, we don't do anything with that prefix. But
+                    // perhaps we should withdraw the old intent anyway?
+                    continue;
+                }
+
+                routeIntents.put(prefix, intent);
+                intentSynchronizer.submit(intent);
+                submitCount++;
+            }
+
+            log.debug("SDN-IP submitted {}/{}, withdrew = {}/{}", submitCount,
+                    updates.size(), withdrawCount, withdraws.size());
+        }
+    }
+
+    /**
+     * Generates a route intent for a prefix, the next hop IP address, and
+     * the next hop MAC address.
+     * <p/>
+     * This method will find the egress interface for the intent.
+     * 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 of the route to add
+     * @param nextHopIpAddress  IP address of the next hop
+     * @param nextHopMacAddress MAC address of the next hop
+     * @return the generated intent, or null if no intent should be submitted
+     */
+    private MultiPointToSinglePointIntent generateRouteIntent(
+            IpPrefix prefix,
+            IpAddress nextHopIpAddress,
+            MacAddress nextHopMacAddress) {
+
+        // Find the attachment point (egress interface) of the next hop
+        Interface egressInterface = interfaceService.getMatchingInterface(nextHopIpAddress);
+        if (egressInterface == null) {
+            log.warn("No outgoing interface found for {}",
+                    nextHopIpAddress);
+            return null;
+        }
+
+        // Generate the intent itself
+        Set<ConnectPoint> ingressPorts = new HashSet<>();
+        ConnectPoint egressPort = egressInterface.connectPoint();
+        log.debug("Generating intent for prefix {}, next hop mac {}",
+                prefix, nextHopMacAddress);
+
+        for (Interface intf : interfaceService.getInterfaces()) {
+            // TODO this should be only peering interfaces
+            if (!intf.connectPoint().equals(egressInterface.connectPoint())) {
+                ConnectPoint srcPort = intf.connectPoint();
+                ingressPorts.add(srcPort);
+            }
+        }
+
+        // Match the destination IP prefix at the first hop
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        if (prefix.isIp4()) {
+            selector.matchEthType(Ethernet.TYPE_IPV4);
+            selector.matchIPDst(prefix);
+        } else {
+            selector.matchEthType(Ethernet.TYPE_IPV6);
+            selector.matchIPv6Dst(prefix);
+        }
+
+        // Rewrite the destination MAC address
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
+                .setEthDst(nextHopMacAddress);
+        if (!egressInterface.vlan().equals(VlanId.NONE)) {
+            treatment.setVlanId(egressInterface.vlan());
+            // If we set VLAN ID, we have to make sure a VLAN tag exists.
+            // TODO support no VLAN -> VLAN routing
+            selector.matchVlanId(VlanId.ANY);
+        }
+
+        int priority =
+                prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET;
+        Key key = Key.of(prefix.toString(), appId);
+        return MultiPointToSinglePointIntent.builder()
+                .appId(appId)
+                .key(key)
+                .selector(selector.build())
+                .treatment(treatment.build())
+                .ingressPoints(ingressPorts)
+                .egressPoint(egressPort)
+                .priority(priority)
+                .constraints(CONSTRAINTS)
+                .build();
+    }
+
+}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/PrimaryChangeCommand.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/PrimaryChangeCommand.java
index 72cc112..7a17cfe 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/PrimaryChangeCommand.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/PrimaryChangeCommand.java
@@ -18,7 +18,7 @@
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
 import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.sdnip.SdnIpService;
+import org.onosproject.routing.SdnIpService;
 
 /**
  * Command to change whether this SDNIP instance is primary or not.
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java
index fc5782e..6dc3ce1 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java
@@ -16,6 +16,7 @@
 package org.onosproject.sdnip;
 
 import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.MoreExecutors;
 import org.junit.Before;
 import org.junit.Test;
 import org.onlab.junit.TestUtils;
@@ -27,10 +28,9 @@
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
+import org.onosproject.TestApplicationId;
 import org.onosproject.core.ApplicationId;
-import org.onosproject.net.config.NetworkConfigService;
 import org.onosproject.incubator.net.intf.Interface;
-import org.onosproject.incubator.net.intf.InterfaceService;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.PortNumber;
@@ -43,20 +43,13 @@
 import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentService;
 import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.Key;
 import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.routing.FibEntry;
-import org.onosproject.routing.FibUpdate;
 import org.onosproject.routing.RouteEntry;
-import org.onosproject.routing.config.BgpPeer;
-import org.onosproject.routing.config.RoutingConfigurationService;
-import org.onosproject.sdnip.IntentSynchronizer.IntentKey;
 
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
 
 import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.expect;
@@ -64,11 +57,8 @@
 import static org.easymock.EasyMock.reset;
 import static org.easymock.EasyMock.verify;
 import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.onosproject.sdnip.TestIntentServiceHelper.eqExceptId;
 
 /**
  * This class tests the intent synchronization function in the
@@ -76,10 +66,7 @@
  */
 public class IntentSyncTest extends AbstractIntentTest {
 
-    private RoutingConfigurationService routingConfig;
-    private InterfaceService interfaceService;
     private IntentService intentService;
-    private NetworkConfigService configService;
 
     private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
             DeviceId.deviceId("of:0000000000000001"),
@@ -100,65 +87,18 @@
     private IntentSynchronizer intentSynchronizer;
     private final Set<Interface> interfaces = Sets.newHashSet();
 
-    private static final ApplicationId APPID = new ApplicationId() {
-        @Override
-        public short id() {
-            return 1;
-        }
-
-        @Override
-        public String name() {
-            return "SDNIP";
-        }
-    };
+    private static final ApplicationId APPID = TestApplicationId.create("SDNIP");
 
     @Before
     public void setUp() throws Exception {
         super.setUp();
 
-        routingConfig = createMock(RoutingConfigurationService.class);
-        interfaceService = createMock(InterfaceService.class);
-        configService = createMock(NetworkConfigService.class);
-
-        // These will set expectations on routingConfig
         setUpInterfaceService();
-        setUpBgpPeers();
-
-        replay(routingConfig);
-        replay(interfaceService);
 
         intentService = createMock(IntentService.class);
 
         intentSynchronizer = new IntentSynchronizer(APPID, intentService,
-                                                    null, routingConfig,
-                                                    interfaceService);
-    }
-
-    /**
-     * Sets up BGP peers in external networks.
-     */
-    private void setUpBgpPeers() {
-
-        Map<IpAddress, BgpPeer> peers = new HashMap<>();
-
-        String peerSw1Eth1 = "192.168.10.1";
-        peers.put(IpAddress.valueOf(peerSw1Eth1),
-                  new BgpPeer("00:00:00:00:00:00:00:01", 1, peerSw1Eth1));
-
-        // Two BGP peers are connected to switch 2 port 1.
-        String peer1Sw2Eth1 = "192.168.20.1";
-        peers.put(IpAddress.valueOf(peer1Sw2Eth1),
-                  new BgpPeer("00:00:00:00:00:00:00:02", 1, peer1Sw2Eth1));
-
-        String peer2Sw2Eth1 = "192.168.20.2";
-        peers.put(IpAddress.valueOf(peer2Sw2Eth1),
-                  new BgpPeer("00:00:00:00:00:00:00:02", 1, peer2Sw2Eth1));
-
-        String peer1Sw4Eth1 = "192.168.40.1";
-        peers.put(IpAddress.valueOf(peer1Sw4Eth1),
-                  new BgpPeer("00:00:00:00:00:00:00:04", 1, peer1Sw4Eth1));
-
-        expect(routingConfig.getBgpPeers()).andReturn(peers).anyTimes();
+                MoreExecutors.newDirectExecutorService());
     }
 
     /**
@@ -200,267 +140,13 @@
                                           MacAddress.valueOf("00:00:00:00:00:04"),
                                           VlanId.vlanId((short) 1));
 
-        expect(interfaceService.getInterfacesByPort(SW4_ETH1)).andReturn(
-                Collections.singleton(sw4Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.40.1")))
-                .andReturn(sw4Eth1).anyTimes();
-
         interfaces.add(sw4Eth1);
-
-        expect(interfaceService.getInterfacesByPort(SW1_ETH1)).andReturn(
-                Collections.singleton(sw1Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.10.1")))
-                .andReturn(sw1Eth1).anyTimes();
-        expect(interfaceService.getInterfacesByPort(SW2_ETH1)).andReturn(
-                Collections.singleton(sw2Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.20.1")))
-                .andReturn(sw2Eth1).anyTimes();
-        expect(interfaceService.getInterfacesByPort(SW3_ETH1)).andReturn(
-                Collections.singleton(sw3Eth1)).anyTimes();
-        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.30.1")))
-                .andReturn(sw3Eth1).anyTimes();
-        expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
     }
 
     /**
-     * Tests adding a FIB entry to the IntentSynchronizer.
-     *
-     * We verify that the synchronizer records the correct state and that the
-     * correct intent is submitted to the IntentService.
-     *
-     * @throws TestUtilsException
-     */
-    @Test
-    public void testFibAdd() throws TestUtilsException {
-        FibEntry fibEntry = new FibEntry(
-                Ip4Prefix.valueOf("1.1.1.0/24"),
-                Ip4Address.valueOf("192.168.10.1"),
-                MacAddress.valueOf("00:00:00:00:00:01"));
-
-        // Construct a MultiPointToSinglePointIntent intent
-        TrafficSelector.Builder selectorBuilder =
-                DefaultTrafficSelector.builder();
-        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
-                fibEntry.prefix());
-
-        TrafficTreatment.Builder treatmentBuilder =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
-
-        Set<ConnectPoint> ingressPoints = new HashSet<>();
-        ingressPoints.add(SW2_ETH1);
-        ingressPoints.add(SW3_ETH1);
-        ingressPoints.add(SW4_ETH1);
-
-        MultiPointToSinglePointIntent intent =
-                MultiPointToSinglePointIntent.builder()
-                        .appId(APPID)
-                        .selector(selectorBuilder.build())
-                        .treatment(treatmentBuilder.build())
-                        .ingressPoints(ingressPoints)
-                        .egressPoint(SW1_ETH1)
-                        .constraints(IntentSynchronizer.CONSTRAINTS)
-                        .build();
-
-        // Setup the expected intents
-        intentService.submit(eqExceptId(intent));
-        replay(intentService);
-
-        intentSynchronizer.leaderChanged(true);
-        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
-
-        FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE,
-                                            fibEntry);
-        intentSynchronizer.update(Collections.singleton(fibUpdate),
-                                  Collections.emptyList());
-
-        assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
-        Intent firstIntent =
-                intentSynchronizer.getRouteIntents().iterator().next();
-        IntentKey firstIntentKey = new IntentKey(firstIntent);
-        IntentKey intentKey = new IntentKey(intent);
-        assertTrue(firstIntentKey.equals(intentKey));
-        verify(intentService);
-    }
-
-    /**
-     * Tests adding a FIB entry with to a next hop in a VLAN.
-     *
-     * We verify that the synchronizer records the correct state and that the
-     * correct intent is submitted to the IntentService.
-     *
-     * @throws TestUtilsException
-     */
-    @Test
-    public void testFibAddWithVlan() throws TestUtilsException {
-        FibEntry fibEntry = new FibEntry(
-                Ip4Prefix.valueOf("3.3.3.0/24"),
-                Ip4Address.valueOf("192.168.40.1"),
-                MacAddress.valueOf("00:00:00:00:00:04"));
-
-        // Construct a MultiPointToSinglePointIntent intent
-        TrafficSelector.Builder selectorBuilder =
-                DefaultTrafficSelector.builder();
-        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4)
-                       .matchIPDst(fibEntry.prefix())
-                       .matchVlanId(VlanId.ANY);
-
-        TrafficTreatment.Builder treatmentBuilder =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:04"))
-                        .setVlanId(VlanId.vlanId((short) 1));
-
-        Set<ConnectPoint> ingressPoints = new HashSet<>();
-        ingressPoints.add(SW1_ETH1);
-        ingressPoints.add(SW2_ETH1);
-        ingressPoints.add(SW3_ETH1);
-
-        MultiPointToSinglePointIntent intent =
-                MultiPointToSinglePointIntent.builder()
-                        .appId(APPID)
-                        .selector(selectorBuilder.build())
-                        .treatment(treatmentBuilder.build())
-                        .ingressPoints(ingressPoints)
-                        .egressPoint(SW4_ETH1)
-                        .constraints(IntentSynchronizer.CONSTRAINTS)
-                        .build();
-
-        // Setup the expected intents
-        intentService.submit(eqExceptId(intent));
-
-        replay(intentService);
-
-        // Run the test
-        intentSynchronizer.leaderChanged(true);
-        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
-        FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
-
-        intentSynchronizer.update(Collections.singleton(fibUpdate),
-                                  Collections.emptyList());
-
-        // Verify
-        assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
-        Intent firstIntent =
-            intentSynchronizer.getRouteIntents().iterator().next();
-        IntentKey firstIntentKey = new IntentKey(firstIntent);
-        IntentKey intentKey = new IntentKey(intent);
-        assertTrue(firstIntentKey.equals(intentKey));
-        verify(intentService);
-    }
-
-    /**
-     * Tests updating a FIB entry.
-     *
-     * We verify that the synchronizer records the correct state and that the
-     * correct intent is submitted to the IntentService.
-     *
-     * @throws TestUtilsException
-     */
-    @Test
-    public void testFibUpdate() throws TestUtilsException {
-        // Firstly add a route
-        testFibAdd();
-
-        Intent addedIntent =
-                intentSynchronizer.getRouteIntents().iterator().next();
-
-        // Start to construct a new route entry and new intent
-        FibEntry fibEntryUpdate = new FibEntry(
-                Ip4Prefix.valueOf("1.1.1.0/24"),
-                Ip4Address.valueOf("192.168.20.1"),
-                MacAddress.valueOf("00:00:00:00:00:02"));
-
-        // Construct a new MultiPointToSinglePointIntent intent
-        TrafficSelector.Builder selectorBuilderNew =
-                DefaultTrafficSelector.builder();
-        selectorBuilderNew.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
-                fibEntryUpdate.prefix());
-
-        TrafficTreatment.Builder treatmentBuilderNew =
-                DefaultTrafficTreatment.builder();
-        treatmentBuilderNew.setEthDst(MacAddress.valueOf("00:00:00:00:00:02"));
-
-
-        Set<ConnectPoint> ingressPointsNew = new HashSet<>();
-        ingressPointsNew.add(SW1_ETH1);
-        ingressPointsNew.add(SW3_ETH1);
-        ingressPointsNew.add(SW4_ETH1);
-
-        MultiPointToSinglePointIntent intentNew =
-                MultiPointToSinglePointIntent.builder()
-                        .appId(APPID)
-                        .selector(selectorBuilderNew.build())
-                        .treatment(treatmentBuilderNew.build())
-                        .ingressPoints(ingressPointsNew)
-                        .egressPoint(SW2_ETH1)
-                        .constraints(IntentSynchronizer.CONSTRAINTS)
-                        .build();
-
-        // Set up test expectation
-        reset(intentService);
-        // Setup the expected intents
-        intentService.withdraw(eqExceptId(addedIntent));
-        intentService.submit(eqExceptId(intentNew));
-        replay(intentService);
-
-        // Call the update() method in IntentSynchronizer class
-        intentSynchronizer.leaderChanged(true);
-        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
-        FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE,
-                                                  fibEntryUpdate);
-        intentSynchronizer.update(Collections.singletonList(fibUpdate),
-                                  Collections.emptyList());
-
-        // Verify
-        assertEquals(intentSynchronizer.getRouteIntents().size(), 1);
-        Intent firstIntent =
-                intentSynchronizer.getRouteIntents().iterator().next();
-        IntentKey firstIntentKey = new IntentKey(firstIntent);
-        IntentKey intentNewKey = new IntentKey(intentNew);
-        assertTrue(firstIntentKey.equals(intentNewKey));
-        verify(intentService);
-    }
-
-    /**
-     * Tests deleting a FIB entry.
-     *
-     * We verify that the synchronizer records the correct state and that the
-     * correct intent is withdrawn from the IntentService.
-     *
-     * @throws TestUtilsException
-     */
-    @Test
-    public void testFibDelete() throws TestUtilsException {
-        // Firstly add a route
-        testFibAdd();
-
-        Intent addedIntent =
-                intentSynchronizer.getRouteIntents().iterator().next();
-
-        // Construct the existing route entry
-        FibEntry fibEntry = new FibEntry(
-                Ip4Prefix.valueOf("1.1.1.0/24"), null, null);
-
-        // Set up expectation
-        reset(intentService);
-        // Setup the expected intents
-        intentService.withdraw(eqExceptId(addedIntent));
-        replay(intentService);
-
-        // Call the update() method in IntentSynchronizer class
-        intentSynchronizer.leaderChanged(true);
-        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
-        FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.DELETE, fibEntry);
-        intentSynchronizer.update(Collections.emptyList(),
-                                  Collections.singletonList(fibUpdate));
-
-        // Verify
-        assertEquals(intentSynchronizer.getRouteIntents().size(), 0);
-        verify(intentService);
-    }
-
-    /**
-     * This method tests the behavior of intent Synchronizer.
+     * Tests the synchronization behavior of intent synchronizer. We set up
+     * a discrepancy between the intent service state and the intent
+     * synchronizer's state and ensure that this is reconciled correctly.
      *
      * @throws TestUtilsException
      */
@@ -529,27 +215,13 @@
         // Compose a intent, which is equal to intent5 but the id is different.
         MultiPointToSinglePointIntent intent5New =
                 staticIntentBuilder(intent5, routeEntry5, "00:00:00:00:00:01");
-        assertThat(IntentSynchronizer.IntentKey.equalIntents(
-                        intent5, intent5New),
-                   is(true));
+        assertThat(IntentUtils.equals(intent5, intent5New), is(true));
         assertFalse(intent5.equals(intent5New));
 
         MultiPointToSinglePointIntent intent6 = intentBuilder(
                 routeEntry6.prefix(), "00:00:00:00:00:01",  SW1_ETH1);
 
-        // Set up the routeIntents field in IntentSynchronizer class
-        ConcurrentHashMap<IpPrefix, MultiPointToSinglePointIntent>
-            routeIntents =  new ConcurrentHashMap<>();
-        routeIntents.put(routeEntry1.prefix(), intent1);
-        routeIntents.put(routeEntry3.prefix(), intent3);
-        routeIntents.put(routeEntry4Update.prefix(), intent4Update);
-        routeIntents.put(routeEntry5.prefix(), intent5New);
-        routeIntents.put(routeEntry6.prefix(), intent6);
-        routeIntents.put(routeEntry7.prefix(), intent7);
-        TestUtils.setField(intentSynchronizer, "routeIntents", routeIntents);
-
         // Set up expectation
-        reset(intentService);
         Set<Intent> intents = new HashSet<>();
         intents.add(intent1);
         expect(intentService.getIntentState(intent1.key()))
@@ -568,9 +240,9 @@
                 .andReturn(IntentState.WITHDRAWING).anyTimes();
         expect(intentService.getIntents()).andReturn(intents).anyTimes();
 
+        // These are the operations that should be done to the intentService
+        // during synchronization
         intentService.withdraw(intent2);
-        intentService.withdraw(intent4);
-
         intentService.submit(intent3);
         intentService.submit(intent4Update);
         intentService.submit(intent6);
@@ -578,16 +250,101 @@
         replay(intentService);
 
         // Start the test
-        intentSynchronizer.leaderChanged(true);
-        intentSynchronizer.synchronizeIntents();
 
-        // Verify
-        assertEquals(intentSynchronizer.getRouteIntents().size(), 6);
-        assertTrue(intentSynchronizer.getRouteIntents().contains(intent1));
-        assertTrue(intentSynchronizer.getRouteIntents().contains(intent3));
-        assertTrue(intentSynchronizer.getRouteIntents().contains(intent4Update));
-        assertTrue(intentSynchronizer.getRouteIntents().contains(intent5));
-        assertTrue(intentSynchronizer.getRouteIntents().contains(intent6));
+        // Simulate some input from the clients. The intent synchronizer has not
+        // gained the global leadership yet, but it will remember this input for
+        // when it does.
+        intentSynchronizer.submit(intent1);
+        intentSynchronizer.submit(intent2);
+        intentSynchronizer.withdraw(intent2);
+        intentSynchronizer.submit(intent3);
+        intentSynchronizer.submit(intent4);
+        intentSynchronizer.submit(intent4Update);
+        intentSynchronizer.submit(intent5);
+        intentSynchronizer.submit(intent6);
+        intentSynchronizer.submit(intent7);
+
+        // Give the leadership to the intent synchronizer. It will now attempt
+        // to synchronize the intents in the store with the intents it has
+        // recorded based on the earlier user input.
+        intentSynchronizer.leaderChanged(true);
+
+        verify(intentService);
+    }
+
+    /**
+     * Tests the behavior of the submit API, both when the synchronizer has
+     * leadership and when it does not.
+     */
+    @Test
+    public void testSubmit() {
+        IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
+        Intent intent = intentBuilder(prefix, "00:00:00:00:00:01", SW1_ETH1);
+
+        // Set up expectations
+        intentService.submit(intent);
+        expect(intentService.getIntents()).andReturn(Collections.emptyList())
+                .anyTimes();
+        replay(intentService);
+
+        // Give the intent synchronizer leadership so it will submit intents
+        // to the intent service
+        intentSynchronizer.leaderChanged(true);
+
+        // Test the submit
+        intentSynchronizer.submit(intent);
+
+        verify(intentService);
+
+        // Now we'll remove leadership from the intent synchronizer and verify
+        // that it does not submit any intents to the intent service when we
+        // call the submit API
+        reset(intentService);
+        replay(intentService);
+
+        intentSynchronizer.leaderChanged(false);
+
+        intentSynchronizer.submit(intent);
+
+        verify(intentService);
+    }
+
+    /**
+     * Tests the behavior of the withdraw API, both when the synchronizer has
+     * leadership and when it does not.
+     */
+    @Test
+    public void testWithdraw() {
+        IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
+        Intent intent = intentBuilder(prefix, "00:00:00:00:00:01", SW1_ETH1);
+
+        // Submit an intent first so we can withdraw it later
+        intentService.submit(intent);
+        intentService.withdraw(intent);
+        expect(intentService.getIntents()).andReturn(Collections.emptyList())
+                .anyTimes();
+        replay(intentService);
+
+        // Give the intent synchronizer leadership so it will submit intents
+        // to the intent service
+        intentSynchronizer.leaderChanged(true);
+
+        // Test the submit then withdraw
+        intentSynchronizer.submit(intent);
+        intentSynchronizer.withdraw(intent);
+
+        verify(intentService);
+
+        // Now we'll remove leadership from the intent synchronizer and verify
+        // that it does not withdraw any intents to the intent service when we
+        // call the withdraw API
+        reset(intentService);
+        replay(intentService);
+
+        intentSynchronizer.leaderChanged(false);
+
+        intentSynchronizer.submit(intent);
+        intentSynchronizer.withdraw(intent);
 
         verify(intentService);
     }
@@ -607,10 +364,10 @@
         TrafficSelector.Builder selectorBuilder =
                 DefaultTrafficSelector.builder();
         if (ipPrefix.isIp4()) {
-            selectorBuilder.matchEthType(Ethernet.TYPE_IPV4);   // IPv4
+            selectorBuilder.matchEthType(Ethernet.TYPE_IPV4);
             selectorBuilder.matchIPDst(ipPrefix);
         } else {
-            selectorBuilder.matchEthType(Ethernet.TYPE_IPV6);   // IPv6
+            selectorBuilder.matchEthType(Ethernet.TYPE_IPV6);
             selectorBuilder.matchIPv6Dst(ipPrefix);
         }
 
@@ -628,11 +385,12 @@
         MultiPointToSinglePointIntent intent =
                 MultiPointToSinglePointIntent.builder()
                         .appId(APPID)
+                        .key(Key.of(ipPrefix.toString(), APPID))
                         .selector(selectorBuilder.build())
                         .treatment(treatmentBuilder.build())
                         .ingressPoints(ingressPoints)
                         .egressPoint(egressPoint)
-                        .constraints(IntentSynchronizer.CONSTRAINTS)
+                        .constraints(SdnIpFib.CONSTRAINTS)
                         .build();
         return intent;
     }
@@ -646,7 +404,7 @@
      * @return the newly constructed MultiPointToSinglePointIntent
      * @throws TestUtilsException
      */
-    private  MultiPointToSinglePointIntent staticIntentBuilder(
+    private MultiPointToSinglePointIntent staticIntentBuilder(
             MultiPointToSinglePointIntent intent, RouteEntry routeEntry,
             String nextHopMacAddress) throws TestUtilsException {
 
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
index d89c3c2..c4b2daa 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
@@ -19,7 +19,6 @@
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
-import org.onlab.junit.TestUtils;
 import org.onlab.junit.TestUtils.TestUtilsException;
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.IPv4;
@@ -28,13 +27,14 @@
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.TpPort;
 import org.onlab.packet.VlanId;
+import org.onosproject.TestApplicationId;
 import org.onosproject.core.ApplicationId;
-import org.onosproject.net.config.NetworkConfigService;
 import org.onosproject.incubator.net.intf.Interface;
 import org.onosproject.incubator.net.intf.InterfaceService;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigService;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
@@ -42,8 +42,9 @@
 import org.onosproject.net.host.InterfaceIpAddress;
 import org.onosproject.net.intent.AbstractIntentTest;
 import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.Key;
 import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.routing.IntentSynchronizationService;
 import org.onosproject.routing.config.BgpConfig;
 import org.onosproject.routing.config.BgpPeer;
 import org.onosproject.routing.config.BgpSpeaker;
@@ -71,26 +72,15 @@
  */
 public class PeerConnectivityManagerTest extends AbstractIntentTest {
 
-    private static final ApplicationId APPID = new ApplicationId() {
-        @Override
-        public short id() {
-            return 0;
-        }
-
-        @Override
-        public String name() {
-            return "foo";
-        }
-    };
+    private static final ApplicationId APPID = TestApplicationId.create("foo");
 
     private static final ApplicationId CONFIG_APP_ID = APPID;
 
     private PeerConnectivityManager peerConnectivityManager;
-    private IntentSynchronizer intentSynchronizer;
+    private IntentSynchronizationService intentSynchronizer;
     private RoutingConfigurationService routingConfig;
     private InterfaceService interfaceService;
     private NetworkConfigService networkConfigService;
-    private IntentService intentService;
 
     private Set<BgpConfig.BgpSpeakerConfig> bgpSpeakers;
     private Map<String, Interface> interfaces;
@@ -98,8 +88,6 @@
 
     private BgpConfig bgpConfig;
 
-    private Map<String, Interface> configuredInterfaces;
-    private Map<IpAddress, BgpPeer> configuredPeers;
     private List<PointToPointIntent> intentList;
 
     private final String dpid1 = "00:00:00:00:00:00:00:01";
@@ -136,7 +124,7 @@
         // These will set expectations on routingConfig and interfaceService
         bgpSpeakers = setUpBgpSpeakers();
         interfaces = Collections.unmodifiableMap(setUpInterfaces());
-        peers = Collections.unmodifiableMap(setUpPeers());
+        peers = setUpPeers();
 
         initPeerConnectivity();
         intentList = setUpIntentList();
@@ -169,11 +157,11 @@
      * Sets up logical interfaces, which emulate the configured interfaces
      * in SDN-IP application.
      *
-     * @return configured interfaces as a MAP from Interface name to Interface
+     * @return configured interfaces as a map from interface name to Interface
      */
     private Map<String, Interface> setUpInterfaces() {
 
-        configuredInterfaces = new HashMap<>();
+        Map<String, Interface> configuredInterfaces = new HashMap<>();
 
         String interfaceSw1Eth1 = "s1-eth1";
         InterfaceIpAddress ia1 =
@@ -242,7 +230,7 @@
      */
     private Map<IpAddress, BgpPeer> setUpPeers() {
 
-        configuredPeers = new HashMap<>();
+        Map<IpAddress, BgpPeer> configuredPeers = new HashMap<>();
 
         String peerSw1Eth1 = "192.168.10.1";
         configuredPeers.put(IpAddress.valueOf(peerSw1Eth1),
@@ -266,14 +254,12 @@
      * @return point to point intent list
      */
     private List<PointToPointIntent> setUpIntentList() {
-
         intentList = new ArrayList<>();
 
         setUpBgpIntents();
         setUpIcmpIntents();
 
         return intentList;
-
     }
 
     /**
@@ -306,8 +292,12 @@
             builder.matchTcpDst(TpPort.tpPort(dstTcpPort));
         }
 
+        Key key = Key.of(srcPrefix.split("/")[0] + "-" + dstPrefix.split("/")[0]
+                + "-" + ((srcTcpPort == null) ? "dst" : "src"), APPID);
+
         PointToPointIntent intent = PointToPointIntent.builder()
                 .appId(APPID)
+                .key(key)
                 .selector(builder.build())
                 .treatment(noTreatment)
                 .ingressPoint(srcConnectPoint)
@@ -392,8 +382,12 @@
                 .matchIPDst(IpPrefix.valueOf(dstPrefix))
                 .build();
 
+        Key key = Key.of(srcPrefix.split("/")[0] + "-" + dstPrefix.split("/")[0]
+                + "-" + "icmp", APPID);
+
         PointToPointIntent intent = PointToPointIntent.builder()
                 .appId(APPID)
+                .key(key)
                 .selector(selector)
                 .treatment(noTreatment)
                 .ingressPoint(srcConnectPoint)
@@ -434,19 +428,14 @@
         expect(routingConfig.getBgpPeers()).andReturn(peers).anyTimes();
         expect(bgpConfig.bgpSpeakers()).andReturn(bgpSpeakers).anyTimes();
         replay(bgpConfig);
-        expect(networkConfigService.getConfig(APPID, BgpConfig.class)).andReturn(bgpConfig).anyTimes();
+        expect(networkConfigService.getConfig(APPID, BgpConfig.class))
+                .andReturn(bgpConfig).anyTimes();
         replay(networkConfigService);
         replay(routingConfig);
         replay(interfaceService);
 
-        intentService = createMock(IntentService.class);
-        replay(intentService);
-
-        intentSynchronizer = new IntentSynchronizer(APPID, intentService,
-                                                    null, routingConfig,
-                                                    interfaceService);
-        intentSynchronizer.leaderChanged(true);
-        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);
+        intentSynchronizer = createMock(IntentSynchronizationService.class);
+        replay(intentSynchronizer);
 
         peerConnectivityManager =
             new PeerConnectivityManager(APPID, intentSynchronizer,
@@ -464,20 +453,18 @@
      */
     @Test
     public void testConnectionSetup() {
-
-        reset(intentService);
+        reset(intentSynchronizer);
 
         // Setup the expected intents
         for (Intent intent : intentList) {
-            intentService.submit(eqExceptId(intent));
+            intentSynchronizer.submit(eqExceptId(intent));
         }
-        replay(intentService);
+        replay(intentSynchronizer);
 
         // Running the interface to be tested.
         peerConnectivityManager.start();
 
-        verify(intentService);
-
+        verify(intentSynchronizer);
     }
 
     /**
@@ -488,7 +475,7 @@
         reset(interfaceService);
 
         expect(interfaceService.getInterfaces()).andReturn(
-                Sets.<Interface>newHashSet()).anyTimes();
+                Sets.newHashSet()).anyTimes();
         expect(interfaceService.getInterfacesByPort(s2Eth1))
                 .andReturn(Collections.emptySet()).anyTimes();
         expect(interfaceService.getInterfacesByPort(s1Eth1))
@@ -508,10 +495,10 @@
 
         replay(interfaceService);
 
-        reset(intentService);
-        replay(intentService);
+        reset(intentSynchronizer);
+        replay(intentSynchronizer);
         peerConnectivityManager.start();
-        verify(intentService);
+        verify(intentSynchronizer);
     }
 
     /**
@@ -527,10 +514,10 @@
         expect(routingConfig.getBgpPeers()).andReturn(peers).anyTimes();
         replay(routingConfig);
 
-        reset(intentService);
-        replay(intentService);
+        reset(intentSynchronizer);
+        replay(intentSynchronizer);
         peerConnectivityManager.start();
-        verify(intentService);
+        verify(intentSynchronizer);
     }
 
     /**
@@ -540,7 +527,7 @@
     @Test
     public void testNoPeerInterface() {
         String peerSw100Eth1 = "192.168.200.1";
-        configuredPeers.put(IpAddress.valueOf(peerSw100Eth1),
+        peers.put(IpAddress.valueOf(peerSw100Eth1),
                 new BgpPeer("00:00:00:00:00:00:01:00", 1, peerSw100Eth1));
         testConnectionSetup();
     }
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java
new file mode 100644
index 0000000..5466d52
--- /dev/null
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java
@@ -0,0 +1,417 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdnip;
+
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.intent.AbstractIntentTest;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.routing.FibEntry;
+import org.onosproject.routing.FibUpdate;
+import org.onosproject.routing.IntentSynchronizationService;
+import org.onosproject.routing.config.BgpPeer;
+import org.onosproject.routing.config.RoutingConfigurationService;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reset;
+import static org.easymock.EasyMock.verify;
+import static org.onosproject.sdnip.TestIntentServiceHelper.eqExceptId;
+
+/**
+ * Unit tests for SdnIpFib.
+ */
+public class SdnIpFibTest extends AbstractIntentTest {
+
+    private RoutingConfigurationService routingConfig;
+    private InterfaceService interfaceService;
+
+    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 SdnIpFib sdnipFib;
+    private IntentSynchronizationService intentSynchronizer;
+    private final Set<Interface> interfaces = Sets.newHashSet();
+
+    private static final ApplicationId APPID = TestApplicationId.create("SDNIP");
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        routingConfig = createMock(RoutingConfigurationService.class);
+        interfaceService = createMock(InterfaceService.class);
+
+        // These will set expectations on routingConfig and interfaceService
+        setUpInterfaceService();
+        setUpBgpPeers();
+
+        replay(routingConfig);
+        replay(interfaceService);
+
+        intentSynchronizer = createMock(IntentSynchronizationService.class);
+
+        sdnipFib = new SdnIpFib(APPID, interfaceService, intentSynchronizer);
+    }
+
+    /**
+     * Sets up BGP peers in external networks.
+     */
+    private void setUpBgpPeers() {
+
+        Map<IpAddress, BgpPeer> peers = new HashMap<>();
+
+        String peerSw1Eth1 = "192.168.10.1";
+        peers.put(IpAddress.valueOf(peerSw1Eth1),
+                new BgpPeer("00:00:00:00:00:00:00:01", 1, peerSw1Eth1));
+
+        // Two BGP peers are connected to switch 2 port 1.
+        String peer1Sw2Eth1 = "192.168.20.1";
+        peers.put(IpAddress.valueOf(peer1Sw2Eth1),
+                new BgpPeer("00:00:00:00:00:00:00:02", 1, peer1Sw2Eth1));
+
+        String peer2Sw2Eth1 = "192.168.20.2";
+        peers.put(IpAddress.valueOf(peer2Sw2Eth1),
+                new BgpPeer("00:00:00:00:00:00:00:02", 1, peer2Sw2Eth1));
+
+        String peer1Sw4Eth1 = "192.168.40.1";
+        peers.put(IpAddress.valueOf(peer1Sw4Eth1),
+                new BgpPeer("00:00:00:00:00:00:00:04", 1, peer1Sw4Eth1));
+
+        expect(routingConfig.getBgpPeers()).andReturn(peers).anyTimes();
+    }
+
+    /**
+     * Sets up InterfaceService.
+     */
+    private void setUpInterfaceService() {
+        Set<InterfaceIpAddress> interfaceIpAddresses1 = Sets.newHashSet();
+        interfaceIpAddresses1.add(new InterfaceIpAddress(
+                IpAddress.valueOf("192.168.10.101"),
+                IpPrefix.valueOf("192.168.10.0/24")));
+        Interface sw1Eth1 = new Interface(SW1_ETH1,
+                interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"),
+                VlanId.NONE);
+        interfaces.add(sw1Eth1);
+
+        Set<InterfaceIpAddress> interfaceIpAddresses2 = Sets.newHashSet();
+        interfaceIpAddresses2.add(
+                new InterfaceIpAddress(IpAddress.valueOf("192.168.20.101"),
+                        IpPrefix.valueOf("192.168.20.0/24")));
+        Interface sw2Eth1 = new Interface(SW2_ETH1,
+                interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
+                VlanId.NONE);
+        interfaces.add(sw2Eth1);
+
+        Set<InterfaceIpAddress> interfaceIpAddresses3 = Sets.newHashSet();
+        interfaceIpAddresses3.add(
+                new InterfaceIpAddress(IpAddress.valueOf("192.168.30.101"),
+                        IpPrefix.valueOf("192.168.30.0/24")));
+        Interface sw3Eth1 = new Interface(SW3_ETH1,
+                interfaceIpAddresses3, MacAddress.valueOf("00:00:00:00:00:03"),
+                VlanId.NONE);
+        interfaces.add(sw3Eth1);
+
+        InterfaceIpAddress interfaceIpAddress4 =
+                new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"),
+                        IpPrefix.valueOf("192.168.40.0/24"));
+        Interface sw4Eth1 = new Interface(SW4_ETH1,
+                Sets.newHashSet(interfaceIpAddress4),
+                MacAddress.valueOf("00:00:00:00:00:04"),
+                VlanId.vlanId((short) 1));
+
+        expect(interfaceService.getInterfacesByPort(SW4_ETH1)).andReturn(
+                Collections.singleton(sw4Eth1)).anyTimes();
+        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.40.1")))
+                .andReturn(sw4Eth1).anyTimes();
+
+        interfaces.add(sw4Eth1);
+
+        expect(interfaceService.getInterfacesByPort(SW1_ETH1)).andReturn(
+                Collections.singleton(sw1Eth1)).anyTimes();
+        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.10.1")))
+                .andReturn(sw1Eth1).anyTimes();
+        expect(interfaceService.getInterfacesByPort(SW2_ETH1)).andReturn(
+                Collections.singleton(sw2Eth1)).anyTimes();
+        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.20.1")))
+                .andReturn(sw2Eth1).anyTimes();
+        expect(interfaceService.getInterfacesByPort(SW3_ETH1)).andReturn(
+                Collections.singleton(sw3Eth1)).anyTimes();
+        expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.30.1")))
+                .andReturn(sw3Eth1).anyTimes();
+        expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
+    }
+
+    /**
+     * Tests adding a FIB entry to the IntentSynchronizer.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is submitted to the IntentService.
+     */
+    @Test
+    public void testFibAdd() {
+        IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
+        FibEntry fibEntry = new FibEntry(prefix,
+                Ip4Address.valueOf("192.168.10.1"),
+                MacAddress.valueOf("00:00:00:00:00:01"));
+
+        // Construct a MultiPointToSinglePointIntent intent
+        TrafficSelector.Builder selectorBuilder =
+                DefaultTrafficSelector.builder();
+        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
+                fibEntry.prefix());
+
+        TrafficTreatment.Builder treatmentBuilder =
+                DefaultTrafficTreatment.builder();
+        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
+
+        Set<ConnectPoint> ingressPoints = new HashSet<>();
+        ingressPoints.add(SW2_ETH1);
+        ingressPoints.add(SW3_ETH1);
+        ingressPoints.add(SW4_ETH1);
+
+        MultiPointToSinglePointIntent intent =
+                MultiPointToSinglePointIntent.builder()
+                        .appId(APPID)
+                        .key(Key.of(prefix.toString(), APPID))
+                        .selector(selectorBuilder.build())
+                        .treatment(treatmentBuilder.build())
+                        .ingressPoints(ingressPoints)
+                        .egressPoint(SW1_ETH1)
+                        .constraints(SdnIpFib.CONSTRAINTS)
+                        .build();
+
+        // Setup the expected intents
+        intentSynchronizer.submit(eqExceptId(intent));
+        replay(intentSynchronizer);
+
+        // Send in the UPDATE FibUpdate
+        FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
+        sdnipFib.update(Collections.singleton(fibUpdate), Collections.emptyList());
+
+        verify(intentSynchronizer);
+    }
+
+    /**
+     * Tests adding a FIB entry with to a next hop in a VLAN.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is submitted to the IntentService.
+     */
+    @Test
+    public void testFibAddWithVlan() {
+        IpPrefix prefix = Ip4Prefix.valueOf("3.3.3.0/24");
+        FibEntry fibEntry = new FibEntry(prefix,
+                Ip4Address.valueOf("192.168.40.1"),
+                MacAddress.valueOf("00:00:00:00:00:04"));
+
+        // Construct a MultiPointToSinglePointIntent intent
+        TrafficSelector.Builder selectorBuilder =
+                DefaultTrafficSelector.builder();
+        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPDst(fibEntry.prefix())
+                .matchVlanId(VlanId.ANY);
+
+        TrafficTreatment.Builder treatmentBuilder =
+                DefaultTrafficTreatment.builder();
+        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:04"))
+                .setVlanId(VlanId.vlanId((short) 1));
+
+        Set<ConnectPoint> ingressPoints = new HashSet<>();
+        ingressPoints.add(SW1_ETH1);
+        ingressPoints.add(SW2_ETH1);
+        ingressPoints.add(SW3_ETH1);
+
+        MultiPointToSinglePointIntent intent =
+                MultiPointToSinglePointIntent.builder()
+                        .appId(APPID)
+                        .key(Key.of(prefix.toString(), APPID))
+                        .selector(selectorBuilder.build())
+                        .treatment(treatmentBuilder.build())
+                        .ingressPoints(ingressPoints)
+                        .egressPoint(SW4_ETH1)
+                        .constraints(SdnIpFib.CONSTRAINTS)
+                        .build();
+
+        // Setup the expected intents
+        intentSynchronizer.submit(eqExceptId(intent));
+
+        replay(intentSynchronizer);
+
+        // Send in the UPDATE FibUpdate
+        FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
+        sdnipFib.update(Collections.singleton(fibUpdate), Collections.emptyList());
+
+        verify(intentSynchronizer);
+    }
+
+    /**
+     * Tests updating a FIB entry.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is submitted to the IntentService.
+     */
+    @Test
+    public void testFibUpdate() {
+        // Firstly add a route
+        testFibAdd();
+
+        IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
+
+        // Start to construct a new route entry and new intent
+        FibEntry fibEntryUpdate = new FibEntry(prefix,
+                Ip4Address.valueOf("192.168.20.1"),
+                MacAddress.valueOf("00:00:00:00:00:02"));
+
+        // Construct a new MultiPointToSinglePointIntent intent
+        TrafficSelector.Builder selectorBuilderNew =
+                DefaultTrafficSelector.builder();
+        selectorBuilderNew.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
+                fibEntryUpdate.prefix());
+
+        TrafficTreatment.Builder treatmentBuilderNew =
+                DefaultTrafficTreatment.builder();
+        treatmentBuilderNew.setEthDst(MacAddress.valueOf("00:00:00:00:00:02"));
+
+        Set<ConnectPoint> ingressPointsNew = new HashSet<>();
+        ingressPointsNew.add(SW1_ETH1);
+        ingressPointsNew.add(SW3_ETH1);
+        ingressPointsNew.add(SW4_ETH1);
+
+        MultiPointToSinglePointIntent intentNew =
+                MultiPointToSinglePointIntent.builder()
+                        .appId(APPID)
+                        .key(Key.of(prefix.toString(), APPID))
+                        .selector(selectorBuilderNew.build())
+                        .treatment(treatmentBuilderNew.build())
+                        .ingressPoints(ingressPointsNew)
+                        .egressPoint(SW2_ETH1)
+                        .constraints(SdnIpFib.CONSTRAINTS)
+                        .build();
+
+        // Set up test expectation
+        reset(intentSynchronizer);
+
+        // Setup the expected intents
+        intentSynchronizer.submit(eqExceptId(intentNew));
+        replay(intentSynchronizer);
+
+        // Send in the UPDATE FibUpdate
+        FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE,
+                fibEntryUpdate);
+        sdnipFib.update(Collections.singletonList(fibUpdate),
+                Collections.emptyList());
+
+        verify(intentSynchronizer);
+    }
+
+    /**
+     * Tests deleting a FIB entry.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is withdrawn from the IntentService.
+     */
+    @Test
+    public void testFibDelete() {
+        // Firstly add a route
+        testFibAdd();
+
+        IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
+
+        // Construct the existing route entry
+        FibEntry fibEntry = new FibEntry(prefix, null, null);
+
+        // Construct the existing MultiPointToSinglePoint intent
+        TrafficSelector.Builder selectorBuilder =
+                DefaultTrafficSelector.builder();
+        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
+                fibEntry.prefix());
+
+        TrafficTreatment.Builder treatmentBuilder =
+                DefaultTrafficTreatment.builder();
+        treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
+
+        Set<ConnectPoint> ingressPoints = new HashSet<>();
+        ingressPoints.add(SW2_ETH1);
+        ingressPoints.add(SW3_ETH1);
+        ingressPoints.add(SW4_ETH1);
+
+        MultiPointToSinglePointIntent addedIntent =
+                MultiPointToSinglePointIntent.builder()
+                        .appId(APPID)
+                        .key(Key.of(prefix.toString(), APPID))
+                        .selector(selectorBuilder.build())
+                        .treatment(treatmentBuilder.build())
+                        .ingressPoints(ingressPoints)
+                        .egressPoint(SW1_ETH1)
+                        .constraints(SdnIpFib.CONSTRAINTS)
+                        .build();
+
+        // Set up expectation
+        reset(intentSynchronizer);
+        // Setup the expected intents
+        intentSynchronizer.withdraw(eqExceptId(addedIntent));
+        replay(intentSynchronizer);
+
+        // Send in the DELETE FibUpdate
+        FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.DELETE, fibEntry);
+        sdnipFib.update(Collections.emptyList(), Collections.singletonList(fibUpdate));
+
+        verify(intentSynchronizer);
+    }
+}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/TestIntentServiceHelper.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/TestIntentServiceHelper.java
index 69b18aa..7f825e8 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/TestIntentServiceHelper.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/TestIntentServiceHelper.java
@@ -17,7 +17,6 @@
 
 import org.easymock.IArgumentMatcher;
 import org.onosproject.net.intent.Intent;
-import org.onosproject.sdnip.IntentSynchronizer.IntentKey;
 
 import static org.easymock.EasyMock.reportMatcher;
 
@@ -53,8 +52,6 @@
      * the solution is to use an EasyMock matcher that verifies that all the
      * value properties of the provided intent match the expected values, but
      * ignores the intent ID when testing equality.
-     *
-     * FIXME this currently does not take key into account
      */
     private static final class IdAgnosticIntentMatcher implements
                 IArgumentMatcher {
@@ -86,9 +83,7 @@
             Intent providedIntent = (Intent) object;
             providedString = providedIntent.toString();
 
-            IntentKey thisIntentKey = new IntentKey(intent);
-            IntentKey providedIntentKey = new IntentKey(providedIntent);
-            return thisIntentKey.equals(providedIntentKey);
+            return IntentUtils.equals(intent, providedIntent);
         }
     }
 
diff --git a/core/store/dist/src/main/java/org/onosproject/store/ecmap/EventuallyConsistentMapImpl.java b/core/store/dist/src/main/java/org/onosproject/store/ecmap/EventuallyConsistentMapImpl.java
index 7835f3e..f1e0dbd 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/ecmap/EventuallyConsistentMapImpl.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/ecmap/EventuallyConsistentMapImpl.java
@@ -521,7 +521,7 @@
             return;
         }
         peers.forEach(node ->
-            senderPending.computeIfAbsent(node, unusedKey -> new EventAccumulator(node)).add(event)
+                        senderPending.computeIfAbsent(node, unusedKey -> new EventAccumulator(node)).add(event)
         );
     }
 
@@ -574,8 +574,10 @@
             return;
         }
         try {
-            log.debug("Received anti-entropy advertisement from {} for {} with {} entries in it",
-                    mapName, ad.sender(), ad.digest().size());
+            if (log.isTraceEnabled()) {
+                log.trace("Received anti-entropy advertisement from {} for {} with {} entries in it",
+                        mapName, ad.sender(), ad.digest().size());
+            }
             antiEntropyCheckLocalItems(ad).forEach(this::notifyListeners);
 
             if (!lightweightAntiEntropy) {
