diff --git a/apps/vpls/BUCK b/apps/vpls/BUCK
index 471e91c..eb1ddec 100644
--- a/apps/vpls/BUCK
+++ b/apps/vpls/BUCK
@@ -6,7 +6,7 @@
     '//cli:onos-cli',
     '//utils/rest:onlab-rest',
     '//incubator/api:onos-incubator-api',
-    '//apps/intentsync:onos-apps-intentsync',
+    '//core/store/serializers:onos-core-serializers'
 ]
 
 TEST_DEPS = [
diff --git a/apps/vpls/pom.xml b/apps/vpls/pom.xml
index f3dd04f..dbe5ac4 100644
--- a/apps/vpls/pom.xml
+++ b/apps/vpls/pom.xml
@@ -35,7 +35,6 @@
         <onos.app.category>Traffic Steering</onos.app.category>
         <onos.app.title>VLAN L2 Broadcast Network App</onos.app.title>
         <onos.app.url>http://onosproject.org</onos.app.url>
-        <onos.app.requires>org.onosproject.intentsynchronizer</onos.app.requires>
     </properties>
 
     <dependencies>
@@ -45,21 +44,11 @@
         </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
-            <artifactId>onos-apps-intentsync</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.onosproject</groupId>
             <artifactId>onos-api</artifactId>
             <scope>test</scope>
             <classifier>tests</classifier>
         </dependency>
         <dependency>
-            <groupId>org.onosproject</groupId>
-            <artifactId>onos-app-sdnip</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
             <groupId>org.easymock</groupId>
             <artifactId>easymock</artifactId>
             <scope>test</scope>
@@ -73,6 +62,15 @@
             <groupId>org.apache.karaf.shell</groupId>
             <artifactId>org.apache.karaf.shell.console</artifactId>
         </dependency>
-
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-core-serializers</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-cli</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
 </project>
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java b/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java
deleted file mode 100644
index 94b819a..0000000
--- a/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.vpls;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import org.onlab.packet.MacAddress;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.EncapsulationType;
-import org.onosproject.net.FilteredConnectPoint;
-import org.onosproject.net.Host;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.intent.ConnectivityIntent;
-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.SinglePointToMultiPointIntent;
-import org.onosproject.net.intent.constraint.EncapsulationConstraint;
-import org.onosproject.net.intent.constraint.PartialFailureConstraint;
-import org.onosproject.intentsync.IntentSynchronizationService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-
-import static org.onosproject.net.EncapsulationType.*;
-
-/**
- * Synchronizes intents between the in-memory intent store and the
- * IntentService.
- */
-public class IntentInstaller {
-    private static final String SUBMIT =
-            "Submitting intents to the Intent Synchronizer";
-    private static final String WITHDRAW =
-            "Withdrawing intents to the Intent Synchronizer";
-    private static final String SP2MP =
-            "Building sp2mp intent from {}";
-    private static final String MP2SP =
-            "Building mp2sp intent to {}";
-
-    private static final Logger log = LoggerFactory.getLogger(
-            IntentInstaller.class);
-
-    private static final int PRIORITY_OFFSET = 1000;
-
-    private static final Set<IntentState> WITHDRAWN_INTENT_STATES =
-            ImmutableSet.of(IntentState.WITHDRAWN,
-                            IntentState.WITHDRAW_REQ,
-                            IntentState.WITHDRAWING);
-
-    static final String PREFIX_BROADCAST = "brc";
-    static final String PREFIX_UNICAST = "uni";
-    static final String SEPARATOR = "-";
-
-    private final ApplicationId appId;
-    private final IntentSynchronizationService intentSynchronizer;
-    private final IntentService intentService;
-
-    public static final ImmutableList<Constraint> PARTIAL_FAILURE_CONSTRAINT =
-            ImmutableList.of(new PartialFailureConstraint());
-
-    /**
-     * Class constructor.
-     *
-     * @param appId              the Application ID
-     * @param intentService      the intent service
-     * @param intentSynchronizer the intent synchronizer service
-     */
-    public IntentInstaller(ApplicationId appId, IntentService intentService,
-                           IntentSynchronizationService intentSynchronizer) {
-        this.appId = appId;
-        this.intentService = intentService;
-        this.intentSynchronizer = intentSynchronizer;
-    }
-
-    /**
-     * Requests to install the intents passed as argument to the Intent Service.
-     *
-     * @param intents intents to be submitted
-     */
-    protected void submitIntents(Collection<Intent> intents) {
-        log.debug(SUBMIT);
-        intents.forEach(intentSynchronizer::submit);
-    }
-
-    /**
-     * Requests to withdraw the intents passed as argument to the Intent Service.
-     *
-     * @param intents intents to be withdraw
-     */
-    protected void withdrawIntents(Collection<Intent> intents) {
-        log.debug(WITHDRAW);
-        intents.forEach(intentSynchronizer::withdraw);
-    }
-
-    /**
-     * Returns list of intents belongs to a VPLS.
-     *
-     * @param name the name of the VPLS
-     * @return the list of intents belonging to a VPLS
-     */
-    protected List<Intent> getIntentsFromVpls(String name) {
-        List<Intent> intents = Lists.newArrayList();
-
-        intentService.getIntents().forEach(intent -> {
-            if (intent.key().toString().startsWith(name)) {
-                intents.add(intent);
-            }
-        });
-
-        return intents;
-    }
-
-    /**
-     * Builds a broadcast intent.
-     *
-     * @param key key to identify the intent
-     * @param src the source connect point
-     * @param dsts the destination connect points
-     * @param encap the encapsulation type
-     * @return the generated single-point to multi-point intent
-     */
-    protected SinglePointToMultiPointIntent buildBrcIntent(Key key,
-                                                           FilteredConnectPoint src,
-                                                           Set<FilteredConnectPoint> dsts,
-                                                           EncapsulationType encap) {
-        log.debug("Building broadcast intent {} for source {}", SP2MP, src);
-
-        SinglePointToMultiPointIntent.Builder intentBuilder;
-
-        TrafficSelector selector = DefaultTrafficSelector.builder()
-                .matchEthDst(MacAddress.BROADCAST)
-                .build();
-
-        intentBuilder = SinglePointToMultiPointIntent.builder()
-                .appId(appId)
-                .key(key)
-                .selector(selector)
-                .filteredIngressPoint(src)
-                .filteredEgressPoints(dsts)
-                .constraints(PARTIAL_FAILURE_CONSTRAINT)
-                .priority(PRIORITY_OFFSET);
-
-        setEncap(intentBuilder, PARTIAL_FAILURE_CONSTRAINT, encap);
-
-        return intentBuilder.build();
-    }
-
-    /**
-     * Builds a unicast intent.
-     *
-     * @param key key to identify the intent
-     * @param srcs the source Connect Points
-     * @param dst the destination Connect Point
-     * @param host destination Host
-     * @param encap the encapsulation type
-     * @return the generated multi-point to single-point intent
-     */
-    protected MultiPointToSinglePointIntent buildUniIntent(Key key,
-                                                           Set<FilteredConnectPoint> srcs,
-                                                           FilteredConnectPoint dst,
-                                                           Host host,
-                                                           EncapsulationType encap) {
-        log.debug("Building unicast intent {} for destination {}", MP2SP, dst);
-
-        MultiPointToSinglePointIntent.Builder intentBuilder;
-
-        TrafficSelector selector = DefaultTrafficSelector.builder()
-                .matchEthDst(host.mac())
-                .build();
-
-        intentBuilder = MultiPointToSinglePointIntent.builder()
-                .appId(appId)
-                .key(key)
-                .selector(selector)
-                .filteredIngressPoints(srcs)
-                .filteredEgressPoint(dst)
-                .constraints(PARTIAL_FAILURE_CONSTRAINT)
-                .priority(PRIORITY_OFFSET);
-
-        setEncap(intentBuilder, PARTIAL_FAILURE_CONSTRAINT, encap);
-
-        return intentBuilder.build();
-    }
-
-    /**
-     * Builds an intent key either for single-point to multi-point or
-     * multi-point to single-point intents, based on a prefix that defines
-     * the type of intent, the single connect point representing the single
-     * source or destination for that intent, the name of the VPLS the intent
-     * belongs to, and the destination host MAC address the intent reaches.
-     *
-     * @param prefix the key prefix
-     * @param cPoint the connect point identifying the source/destination
-     * @param vplsName the name of the VPLS
-     * @param hostMac the source/destination MAC address
-     * @return the key to identify the intent
-     */
-    protected Key buildKey(String prefix,
-                           ConnectPoint cPoint,
-                           String vplsName,
-                           MacAddress hostMac) {
-        String keyString = vplsName +
-                SEPARATOR +
-                prefix +
-                SEPARATOR +
-                cPoint.deviceId() +
-                SEPARATOR +
-                cPoint.port() +
-                SEPARATOR +
-                hostMac;
-
-        return Key.of(keyString, appId);
-    }
-
-    /**
-     * Returns true if the specified intent exists; false otherwise.
-     *
-     * @param intentKey the intent key
-     * @return true if the intent exists; false otherwise
-     */
-    protected boolean intentExists(Key intentKey) {
-        if (intentService.getIntent(intentKey) == null) {
-            return false;
-        }
-
-        // Intent does not exist if intent withdrawn
-        IntentState currentIntentState = intentService.getIntentState(intentKey);
-        return !WITHDRAWN_INTENT_STATES.contains(currentIntentState);
-
-    }
-
-    /**
-     * Sets one or more encapsulation constraints on the intent builder given.
-     *
-     * @param builder the intent builder
-     * @param constraints the existing intent constraints
-     * @param encap the encapsulation type to be set
-     */
-    public static void setEncap(ConnectivityIntent.Builder builder,
-                                List<Constraint> constraints,
-                                EncapsulationType encap) {
-        // Constraints might be an immutable list, so a new modifiable list
-        // is created
-        List<Constraint> newConstraints = new ArrayList<>(constraints);
-
-        // Remove any encapsulation constraint if already in the list
-        constraints.stream()
-                .filter(c -> c instanceof EncapsulationConstraint)
-                .forEach(newConstraints::remove);
-
-        // if the new encapsulation is different from NONE, a new encapsulation
-        // constraint should be added to the list
-        if (!encap.equals(NONE)) {
-            newConstraints.add(new EncapsulationConstraint(encap));
-        }
-
-        // Submit new constraint list as immutable list
-        builder.constraints(ImmutableList.copyOf(newConstraints));
-    }
-}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java b/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java
deleted file mode 100644
index af47248..0000000
--- a/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.vpls;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onosproject.app.ApplicationService;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.incubator.net.intf.Interface;
-import org.onosproject.incubator.net.intf.InterfaceEvent;
-import org.onosproject.incubator.net.intf.InterfaceListener;
-import org.onosproject.incubator.net.intf.InterfaceService;
-import org.onosproject.net.EncapsulationType;
-import org.onosproject.net.FilteredConnectPoint;
-import org.onosproject.net.Host;
-import org.onosproject.net.config.NetworkConfigEvent;
-import org.onosproject.net.config.NetworkConfigListener;
-import org.onosproject.net.config.NetworkConfigService;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.criteria.Criterion;
-import org.onosproject.net.flow.criteria.VlanIdCriterion;
-import org.onosproject.net.host.HostEvent;
-import org.onosproject.net.host.HostListener;
-import org.onosproject.net.host.HostService;
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentService;
-import org.onosproject.net.intent.Key;
-import org.onosproject.intentsync.IntentSynchronizationService;
-import org.onosproject.vpls.config.VplsConfigService;
-import org.slf4j.Logger;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import static org.onosproject.vpls.IntentInstaller.PREFIX_BROADCAST;
-import static org.onosproject.vpls.IntentInstaller.PREFIX_UNICAST;
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Application to create L2 broadcast overlay networks using VLANs.
- */
-@Component(immediate = true)
-public class Vpls {
-    static final String VPLS_APP = "org.onosproject.vpls";
-
-    private static final String HOST_FCP_NOT_FOUND =
-            "Filtered connected point for host {} not found";
-    private static final String HOST_EVENT = "Received HostEvent {}";
-    private static final String INTF_CONF_EVENT =
-            "Received InterfaceConfigEvent {}";
-    private static final String NET_CONF_EVENT =
-            "Received NetworkConfigEvent {}";
-
-    private final Logger log = getLogger(getClass());
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected ApplicationService applicationService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected CoreService coreService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected HostService hostService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected IntentService intentService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected InterfaceService interfaceService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected IntentSynchronizationService intentSynchronizer;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected NetworkConfigService configService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected VplsConfigService vplsConfigService;
-
-    private final HostListener hostListener = new InternalHostListener();
-
-    private final InternalInterfaceListener interfaceListener =
-            new InternalInterfaceListener();
-
-    private final InternalNetworkConfigListener configListener =
-            new InternalNetworkConfigListener();
-
-    private IntentInstaller intentInstaller;
-
-    private ApplicationId appId;
-
-    @Activate
-    public void activate() {
-        appId = coreService.registerApplication(VPLS_APP);
-
-        intentInstaller = new IntentInstaller(appId,
-                                              intentService,
-                                              intentSynchronizer);
-
-        applicationService.registerDeactivateHook(appId, () -> {
-            intentSynchronizer.removeIntentsByAppId(appId);
-        });
-
-        hostService.addListener(hostListener);
-        interfaceService.addListener(interfaceListener);
-        configService.addListener(configListener);
-
-        setupConnectivity(false);
-
-        log.info("Activated");
-    }
-
-    @Deactivate
-    public void deactivate() {
-        hostService.removeListener(hostListener);
-        interfaceService.removeListener(interfaceListener);
-        configService.removeListener(configListener);
-        intentSynchronizer.removeIntentsByAppId(appId);
-        log.info("Deactivated");
-    }
-
-    /**
-     * Sets up connectivity for all VPLSs.
-     *
-     * @param isNetworkConfigEvent true if this function is triggered
-     *                             by NetworkConfigEvent; false otherwise
-     */
-    private void setupConnectivity(boolean isNetworkConfigEvent) {
-        SetMultimap<String, Interface> networkInterfaces =
-                vplsConfigService.ifacesByVplsName();
-
-        Set<String> vplsAffectedByApi =
-                new HashSet<>(vplsConfigService.vplsAffectedByApi());
-
-        if (isNetworkConfigEvent && vplsAffectedByApi.isEmpty()) {
-            vplsAffectedByApi.addAll(vplsConfigService.vplsNamesOld());
-        }
-
-        networkInterfaces.asMap().forEach((vplsName, interfaces) -> {
-            Set<Host> hosts = Sets.newHashSet();
-            interfaces.forEach(intf -> {
-                // Add hosts that belongs to the specific VPLS
-                hostService.getConnectedHosts(intf.connectPoint())
-                        .stream()
-                        .filter(host -> host.vlan().equals(intf.vlan()))
-                        .forEach(hosts::add);
-            });
-
-            EncapsulationType encap =
-                    vplsConfigService.encap(vplsName);
-
-            setupConnectivity(vplsName, interfaces, hosts, encap,
-                              vplsAffectedByApi.contains(vplsName));
-            vplsAffectedByApi.remove(vplsName);
-        });
-
-        if (!vplsAffectedByApi.isEmpty()) {
-            for (String vplsName : vplsAffectedByApi) {
-                withdrawIntents(vplsName, Lists.newArrayList());
-            }
-        }
-    }
-
-    /**
-     * Sets up connectivity for specific VPLS.
-     *
-     * @param vplsName      the VPLS name
-     * @param interfaces    the interfaces that belong to the VPLS
-     * @param hosts         the hosts that belong to the VPLS
-     * @param encap         the encapsulation type
-     * @param affectedByApi true if this function is triggered from the APIs;
-     *                      false otherwise
-     */
-    private void setupConnectivity(String vplsName,
-                                   Collection<Interface> interfaces,
-                                   Set<Host> hosts,
-                                   EncapsulationType encap,
-                                   boolean affectedByApi) {
-
-        List<Intent> intents = Lists.newArrayList();
-        List<Key> keys = Lists.newArrayList();
-        Set<FilteredConnectPoint> fcPoints = buildFCPoints(interfaces);
-
-        intents.addAll(buildBroadcastIntents(
-                vplsName, fcPoints, encap, affectedByApi));
-        intents.addAll(buildUnicastIntents(
-                vplsName, hosts, fcPoints, encap, affectedByApi));
-
-        if (affectedByApi) {
-            intents.forEach(intent -> keys.add(intent.key()));
-            withdrawIntents(vplsName, keys);
-        }
-
-        intentInstaller.submitIntents(intents);
-    }
-
-    /**
-     * Withdraws intents belonging to a VPLS, given a VPLS name.
-     *
-     * @param vplsName the VPLS name
-     * @param keys     the keys of the intents to be installed
-     */
-    private void withdrawIntents(String vplsName, List<Key> keys) {
-        List<Intent> intents = Lists.newArrayList();
-
-        intentInstaller.getIntentsFromVpls(vplsName)
-                .forEach(intent -> {
-                    if (!keys.contains(intent.key())) {
-                        intents.add(intent);
-                    }
-                });
-
-        intentInstaller.withdrawIntents(intents);
-    }
-
-    /**
-     * Sets up broadcast intents between any given filtered connect point.
-     *
-     * @param vplsName      the VPLS name
-     * @param fcPoints      the set of filtered connect points
-     * @param encap         the encapsulation type
-     * @param affectedByApi true if the function triggered from APIs;
-     *                      false otherwise
-     * @return the set of broadcast intents
-     */
-    private Set<Intent> buildBroadcastIntents(String vplsName,
-                                              Set<FilteredConnectPoint> fcPoints,
-                                              EncapsulationType encap,
-                                              boolean affectedByApi) {
-        Set<Intent> intents = Sets.newHashSet();
-        fcPoints.forEach(point -> {
-            Set<FilteredConnectPoint> otherPoints =
-                    fcPoints.stream()
-                            .filter(fcp -> !fcp.equals(point))
-                            .collect(Collectors.toSet());
-
-            Key brcKey = intentInstaller.buildKey(PREFIX_BROADCAST,
-                                                  point.connectPoint(),
-                                                  vplsName,
-                                                  MacAddress.BROADCAST);
-
-            if ((!intentInstaller.intentExists(brcKey) || affectedByApi)
-                    && !otherPoints.isEmpty()) {
-                intents.add(intentInstaller.buildBrcIntent(brcKey,
-                                                           point,
-                                                           otherPoints,
-                                                           encap));
-            }
-        });
-
-        return ImmutableSet.copyOf(intents);
-    }
-
-    /**
-     * Sets up unicast intents between any given filtered connect point.
-     *
-     * @param vplsName      the VPLS name
-     * @param hosts         the set of destination hosts
-     * @param fcPoints      the set of filtered connect points
-     * @param encap         the encapsulation type
-     * @param affectedByApi true if the function triggered from APIs;
-     *                      false otherwise
-     * @return the set of unicast intents
-     */
-    private Set<Intent> buildUnicastIntents(String vplsName,
-                                            Set<Host> hosts,
-                                            Set<FilteredConnectPoint> fcPoints,
-                                            EncapsulationType encap,
-                                            boolean affectedByApi) {
-        Set<Intent> intents = Sets.newHashSet();
-        hosts.forEach(host -> {
-            FilteredConnectPoint hostPoint = getHostPoint(host, fcPoints);
-
-            if (hostPoint == null) {
-                log.warn(HOST_FCP_NOT_FOUND, host);
-                return;
-            }
-
-            Set<FilteredConnectPoint> otherPoints =
-                    fcPoints.stream()
-                            .filter(fcp -> !fcp.equals(hostPoint))
-                            .collect(Collectors.toSet());
-
-            Key uniKey = intentInstaller.buildKey(PREFIX_UNICAST,
-                                                  host.location(),
-                                                  vplsName,
-                                                  host.mac());
-
-            if ((!intentInstaller.intentExists(uniKey) || affectedByApi) &&
-                    !otherPoints.isEmpty()) {
-                intents.add(intentInstaller.buildUniIntent(uniKey,
-                                                           otherPoints,
-                                                           hostPoint,
-                                                           host,
-                                                           encap));
-            }
-        });
-
-        return ImmutableSet.copyOf(intents);
-    }
-
-    /**
-     * Returns the filtered connect point associated to a given host.
-     *
-     * @param host the target host
-     * @param fcps the filtered connected points
-     * @return null if not found; the filtered connect point otherwise
-     */
-    private FilteredConnectPoint getHostPoint(Host host,
-                                              Set<FilteredConnectPoint> fcps) {
-        return fcps.stream()
-                .filter(fcp -> fcp.connectPoint().equals(host.location()))
-                .filter(fcp -> {
-                    VlanIdCriterion vlanCriterion =
-                            (VlanIdCriterion) fcp.trafficSelector().
-                                    getCriterion(Criterion.Type.VLAN_VID);
-                    return vlanCriterion == null ||
-                            vlanCriterion.vlanId().equals(host.vlan());
-                })
-                .findFirst()
-                .orElse(null);
-    }
-
-    /**
-     * Computes a set of filtered connect points from a list of given interfaces.
-     *
-     * @param interfaces the interfaces to compute
-     * @return the set of filtered connect points
-     */
-    private Set<FilteredConnectPoint> buildFCPoints(Collection<Interface> interfaces) {
-        // Build all filtered connected points in the VPLS
-        return interfaces
-                .stream()
-                .map(intf -> {
-                    TrafficSelector.Builder selectorBuilder =
-                            DefaultTrafficSelector.builder();
-                    if (!intf.vlan().equals(VlanId.NONE)) {
-                        selectorBuilder.matchVlanId(intf.vlan());
-                    }
-                    return new FilteredConnectPoint(intf.connectPoint(),
-                                                    selectorBuilder.build());
-                })
-                .collect(Collectors.toSet());
-    }
-
-    /**
-     * Listener for host events.
-     */
-    private class InternalHostListener implements HostListener {
-        @Override
-        public void event(HostEvent event) {
-            log.debug(HOST_EVENT, event);
-            switch (event.type()) {
-                case HOST_ADDED:
-                case HOST_UPDATED:
-                case HOST_REMOVED:
-                    setupConnectivity(false);
-                    break;
-
-                default:
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Listener for interface configuration events.
-     */
-    private class InternalInterfaceListener implements InterfaceListener {
-        @Override
-        public void event(InterfaceEvent event) {
-            log.debug(INTF_CONF_EVENT, event);
-            switch (event.type()) {
-                case INTERFACE_ADDED:
-                case INTERFACE_UPDATED:
-                case INTERFACE_REMOVED:
-                    setupConnectivity(false);
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Listener for VPLS configuration events.
-     */
-    private class InternalNetworkConfigListener implements NetworkConfigListener {
-        @Override
-        public void event(NetworkConfigEvent event) {
-            if (event.configClass() == VplsConfigService.CONFIG_CLASS) {
-                log.debug(NET_CONF_EVENT, event.configClass());
-                switch (event.type()) {
-                    case CONFIG_ADDED:
-                    case CONFIG_UPDATED:
-                    case CONFIG_REMOVED:
-                        setupConnectivity(true);
-                        break;
-                    default:
-                        break;
-                }
-            }
-        }
-    }
-}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/VplsManager.java b/apps/vpls/src/main/java/org/onosproject/vpls/VplsManager.java
new file mode 100644
index 0000000..58ea4a2
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/VplsManager.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2015-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vpls;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.Host;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostService;
+import org.onosproject.store.StoreDelegate;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.api.VplsOperationService;
+import org.onosproject.vpls.api.VplsOperation;
+import org.onosproject.vpls.api.Vpls;
+import org.onosproject.vpls.api.VplsStore;
+import org.onosproject.vpls.store.VplsStoreEvent;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Set;
+
+import static java.util.Objects.*;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Application to create L2 broadcast overlay networks using VLANs.
+ */
+@Component(immediate = true)
+@Service
+public class VplsManager implements Vpls {
+    public static final String VPLS_APP = "org.onosproject.vpls";
+    private static final String UNSUPPORTED_STORE_EVENT_TYPE =
+            "Unsupported store event type {}.";
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VplsStore vplsStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VplsOperationService operationService;
+
+    private StoreDelegate<VplsStoreEvent> vplsStoreDelegate;
+    private HostListener vplsHostListener;
+
+    @Activate
+    public void activate() {
+        vplsStoreDelegate = new VplsStoreDelegate();
+        vplsHostListener = new VplsHostListener();
+
+        vplsStore.setDelegate(vplsStoreDelegate);
+        hostService.addListener(vplsHostListener);
+    }
+
+    @Deactivate
+    public void deactivate() {
+        vplsStore.unsetDelegate(vplsStoreDelegate);
+        hostService.removeListener(vplsHostListener);
+    }
+
+    @Override
+    public VplsData createVpls(String vplsName, EncapsulationType encapsulationType) {
+        requireNonNull(vplsName);
+        requireNonNull(encapsulationType);
+
+        if (vplsStore.getVpls(vplsName) != null) {
+            return null;
+        }
+
+        VplsData vplsData = VplsData.of(vplsName, encapsulationType);
+        vplsStore.addVpls(vplsData);
+
+        return vplsData;
+    }
+
+    @Override
+    public VplsData removeVpls(VplsData vplsData) {
+        requireNonNull(vplsData);
+        vplsData.state(VplsData.VplsState.REMOVING);
+        vplsStore.removeVpls(vplsData);
+        return vplsData;
+    }
+
+    @Override
+    public void addInterfaces(VplsData vplsData, Collection<Interface> interfaces) {
+        requireNonNull(vplsData);
+        requireNonNull(interfaces);
+        vplsData.addInterfaces(interfaces);
+        updateVplsStatus(vplsData, VplsData.VplsState.UPDATING);
+    }
+
+    @Override
+    public void addInterface(VplsData vplsData, Interface iface) {
+        requireNonNull(vplsData);
+        requireNonNull(iface);
+        vplsData.addInterface(iface);
+        updateVplsStatus(vplsData, VplsData.VplsState.UPDATING);
+    }
+
+    @Override
+    public void setEncapsulationType(VplsData vplsData, EncapsulationType encapsulationType) {
+        requireNonNull(vplsData);
+        requireNonNull(encapsulationType);
+        if (vplsData.encapsulationType().equals(encapsulationType)) {
+            // Encap type not changed.
+            return;
+        }
+        vplsData.encapsulationType(encapsulationType);
+        updateVplsStatus(vplsData, VplsData.VplsState.UPDATING);
+    }
+
+    @Override
+    public VplsData getVpls(String vplsName) {
+        requireNonNull(vplsName);
+        return vplsStore.getVpls(vplsName);
+    }
+
+    @Override
+    public Collection<Interface> removeInterfaces(VplsData vplsData, Collection<Interface> interfaces) {
+        requireNonNull(vplsData);
+        requireNonNull(interfaces);
+        vplsData.removeInterfaces(interfaces);
+        updateVplsStatus(vplsData, VplsData.VplsState.UPDATING);
+        return interfaces;
+    }
+
+    @Override
+    public Interface removeInterface(VplsData vplsData, Interface iface) {
+        requireNonNull(vplsData);
+        requireNonNull(iface);
+        vplsData.removeInterface(iface);
+        updateVplsStatus(vplsData, VplsData.VplsState.UPDATING);
+        return iface;
+    }
+
+    @Override
+    public void removeAllVpls() {
+        Set<VplsData> allVplses = ImmutableSet.copyOf(vplsStore.getAllVpls());
+        allVplses.forEach(this::removeVpls);
+    }
+
+    @Override
+    public Collection<VplsData> getAllVpls() {
+        return ImmutableSet.copyOf(vplsStore.getAllVpls());
+    }
+
+    /**
+     * Updates VPLS status to the store.
+     *
+     * @param vplsData the VPLS
+     * @param vplsState the new state to the VPLS
+     */
+    private void updateVplsStatus(VplsData vplsData, VplsData.VplsState vplsState) {
+        vplsData.state(vplsState);
+        vplsStore.updateVpls(vplsData);
+    }
+
+    /**
+     * A listener for host events.
+     * Updates a VPLS if host added or removed.
+     */
+    class VplsHostListener implements HostListener {
+        @Override
+        public void event(HostEvent event) {
+            Host host = event.subject();
+            Interface iface = getHostInterface(host);
+            if (iface == null) {
+                return;
+            }
+            VplsData vplsData = vplsStore.getAllVpls().stream()
+                    .filter(v -> v.interfaces().contains(iface))
+                    .findFirst()
+                    .orElse(null);
+            if (vplsData == null) {
+                // the host does not related to any vpls
+                return;
+            }
+            updateVplsStatus(vplsData, VplsData.VplsState.UPDATING);
+        }
+
+        /**
+         * Gets the network interface of the host.
+         *
+         * @param host the host
+         * @return the network interface of the host; null if no network
+         * interface found
+         */
+        private Interface getHostInterface(Host host) {
+            Set<Interface> interfaces = interfaceService.getInterfaces();
+            return interfaces.stream()
+                    .filter(iface -> iface.connectPoint().equals(host.location()) &&
+                            iface.vlan().equals(host.vlan()))
+                    .findFirst()
+                    .orElse(null);
+        }
+    }
+
+    /**
+     * Store delegate for VPLS store.
+     * Handles VPLS store event and generate VPLS operation according to event
+     * type.
+     */
+    class VplsStoreDelegate implements StoreDelegate<VplsStoreEvent> {
+
+        @Override
+        public void notify(VplsStoreEvent event) {
+            VplsOperation vplsOperation;
+            VplsOperation.Operation op;
+            VplsData vplsData = event.subject();
+            switch (event.type()) {
+                case ADD:
+                    op = VplsOperation.Operation.ADD;
+                    break;
+                case REMOVE:
+                    op = VplsOperation.Operation.REMOVE;
+                    break;
+                case UPDATE:
+                    if (vplsData.state() == VplsData.VplsState.FAILED ||
+                            vplsData.state() == VplsData.VplsState.ADDED ||
+                            vplsData.state() == VplsData.VplsState.REMOVED) {
+                        // Update the state only. Nothing to do if it is updated
+                        // to ADDED, REMOVED or FAILED
+                        op = null;
+                    } else {
+                        op = VplsOperation.Operation.UPDATE;
+                    }
+                    break;
+                default:
+                    log.warn(UNSUPPORTED_STORE_EVENT_TYPE, event.type());
+                    return;
+            }
+            if (op != null) {
+                vplsOperation = VplsOperation.of(vplsData, op);
+                operationService.submit(vplsOperation);
+            }
+        }
+    }
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/VplsNeighbourHandler.java b/apps/vpls/src/main/java/org/onosproject/vpls/VplsNeighbourHandler.java
index de4365f..8a3ac7d 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/VplsNeighbourHandler.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/VplsNeighbourHandler.java
@@ -15,12 +15,13 @@
  */
 package org.onosproject.vpls;
 
-import com.google.common.collect.SetMultimap;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.incubator.net.intf.Interface;
@@ -30,16 +31,20 @@
 import org.onosproject.incubator.net.neighbour.NeighbourMessageContext;
 import org.onosproject.incubator.net.neighbour.NeighbourMessageHandler;
 import org.onosproject.incubator.net.neighbour.NeighbourResolutionService;
+import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.Host;
 import org.onosproject.net.config.NetworkConfigEvent;
 import org.onosproject.net.config.NetworkConfigListener;
 import org.onosproject.net.config.NetworkConfigService;
-import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.host.HostService;
-import org.onosproject.vpls.config.VplsConfigService;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.api.VplsStore;
 import org.slf4j.Logger;
 
+import java.util.Collection;
+import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import static org.slf4j.LoggerFactory.getLogger;
 
@@ -58,16 +63,13 @@
     protected CoreService coreService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected DeviceService deviceService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected InterfaceService interfaceService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected NeighbourResolutionService neighbourService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected VplsConfigService vplsConfigService;
+    protected VplsStore vplsStore;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected NetworkConfigService configService;
@@ -88,7 +90,7 @@
 
     @Activate
     protected void activate() {
-        appId = coreService.registerApplication(Vpls.VPLS_APP);
+        appId = coreService.registerApplication(VplsManager.VPLS_APP);
         interfaceService.addListener(interfaceListener);
         configService.addListener(configListener);
         configNeighbourHandler();
@@ -101,18 +103,16 @@
         neighbourService.unregisterNeighbourHandlers(appId);
     }
 
-    private void configNeighbourHandler() {
+    /**
+     * Registers neighbour handler to all available interfaces.
+     */
+    protected void configNeighbourHandler() {
         neighbourService.unregisterNeighbourHandlers(appId);
-        Set<Interface> interfaces = vplsConfigService.allIfaces();
-
-        interfaceService.getInterfaces()
-                .stream()
-                .filter(interfaces::contains)
-                .forEach(intf -> {
-                    neighbourService.registerNeighbourHandler(intf,
-                                                              neighbourHandler,
-                                                              appId);
-                });
+        interfaceService
+                .getInterfaces()
+                .forEach(intf -> neighbourService.registerNeighbourHandler(intf,
+                                                                       neighbourHandler,
+                                                                       appId));
     }
 
     /**
@@ -123,16 +123,13 @@
         @Override
         public void handleMessage(NeighbourMessageContext context,
                                   HostService hostService) {
-
             switch (context.type()) {
                 case REQUEST:
                     handleRequest(context);
                     break;
-
                 case REPLY:
                     handleReply(context, hostService);
                     break;
-
                 default:
                     log.warn(UNKNOWN_CONTEXT, context.type());
                     break;
@@ -146,16 +143,15 @@
      * @param context the message context
      */
     protected void handleRequest(NeighbourMessageContext context) {
-        SetMultimap<String, Interface> interfaces =
-                vplsConfigService.ifacesByVplsName(context.vlan(),
-                                                   context.inPort());
-        if (interfaces != null) {
-            interfaces.values().stream()
+        // Find target VPLS first, then broadcast to all interface of this VPLS
+        VplsData vplsData = findVpls(context);
+        if (vplsData != null) {
+            vplsData.interfaces().stream()
                     .filter(intf -> !context.inPort().equals(intf.connectPoint()))
                     .forEach(context::forward);
-
         } else {
-            log.debug(CAN_NOT_FIND_VPLS, context.inPort(), context.vlan());
+            log.warn(CAN_NOT_FIND_VPLS, context.inPort(), context.vlan());
+            context.drop();
         }
     }
 
@@ -167,21 +163,66 @@
      */
     protected void handleReply(NeighbourMessageContext context,
                                HostService hostService) {
-        Set<Host> hosts = hostService.getHostsByMac(context.dstMac());
-        SetMultimap<String, Interface> interfaces =
-                vplsConfigService.ifacesByVplsName(context.vlan(),
-                                                   context.inPort());
-        if (interfaces != null) {
-            hosts.forEach(host -> interfaces.values().stream()
-                    .filter(intf -> intf.connectPoint().equals(host.location()))
-                    .filter(intf -> intf.vlan().equals(host.vlan()))
-                    .forEach(context::forward));
+        // Find target VPLS, then reply to the host
+        VplsData vplsData = findVpls(context);
+        if (vplsData != null) {
+            MacAddress dstMac = context.dstMac();
+            Set<Host> hosts = hostService.getHostsByMac(dstMac);
+            hosts = hosts.stream()
+                    .filter(host -> vplsData.interfaces().contains(getHostInterface(host)))
+                    .collect(Collectors.toSet());
+
+            // reply to all host in same VPLS
+            hosts.stream()
+                    .map(this::getHostInterface)
+                    .filter(Objects::nonNull)
+                    .forEach(context::forward);
         } else {
-            log.debug(CAN_NOT_FIND_VPLS, context.inPort(), context.vlan());
+            // this might be happened when we remove an interface from VPLS
+            // just ignore this message
+            log.warn(CAN_NOT_FIND_VPLS, context.inPort(), context.vlan());
+            context.drop();
         }
     }
 
     /**
+     * Finds the VPLS with given neighbour message context.
+     *
+     * @param context the neighbour message context
+     * @return the VPLS for specific neighbour message context
+     */
+    private VplsData findVpls(NeighbourMessageContext context) {
+        Collection<VplsData> vplses = vplsStore.getAllVpls();
+        for (VplsData vplsData : vplses) {
+            Set<Interface> interfaces = vplsData.interfaces();
+            ConnectPoint port = context.inPort();
+            VlanId vlanId = context.vlan();
+            boolean match = interfaces.stream()
+                    .anyMatch(iface -> iface.connectPoint().equals(port) &&
+                            iface.vlan().equals(vlanId));
+            if (match) {
+                return vplsData;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Finds the network interface related to the host.
+     *
+     * @param host the host
+     * @return the interface related to the host
+     */
+    private Interface getHostInterface(Host host) {
+        Set<Interface> interfaces = interfaceService.getInterfaces();
+        return interfaces.stream()
+                .filter(iface -> iface.connectPoint().equals(host.location()) &&
+                                 iface.vlan().equals(host.vlan()))
+                .findFirst()
+                .orElse(null);
+    }
+
+    /**
      * Listener for interface configuration events.
      */
     private class VplsInterfaceListener implements InterfaceListener {
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/VplsOperationManager.java b/apps/vpls/src/main/java/org/onosproject/vpls/VplsOperationManager.java
new file mode 100644
index 0000000..4c0262d
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/VplsOperationManager.java
@@ -0,0 +1,645 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vpls;
+
+import com.google.common.collect.Maps;
+import com.google.common.collect.Queues;
+import com.google.common.collect.Sets;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.util.Tools;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.LeadershipEvent;
+import org.onosproject.cluster.LeadershipEventListener;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.net.Host;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentEvent;
+import org.onosproject.net.intent.IntentException;
+import org.onosproject.net.intent.IntentListener;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.IntentUtils;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.net.intent.SinglePointToMultiPointIntent;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.api.VplsOperationException;
+import org.onosproject.vpls.api.VplsOperationService;
+import org.onosproject.vpls.api.VplsOperation;
+import org.onosproject.vpls.api.VplsStore;
+import org.onosproject.vpls.intent.VplsIntentUtility;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Deque;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.onlab.util.BoundedThreadPool.newFixedThreadPool;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * An implementation of VplsOperationService.
+ * Handles the execution order of the VPLS operations generated by the
+ * application.
+ */
+@Component(immediate = true)
+@Service
+public class VplsOperationManager implements VplsOperationService {
+    private static final int NUM_THREADS = 4;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentService intentService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LeadershipService leadershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VplsStore vplsStore;
+
+    private final Logger log = getLogger(getClass());
+    protected Map<String, Deque<VplsOperation>> pendingVplsOperations;
+    protected final Map<String, VplsOperation> runningOperations = Maps.newHashMap();
+    protected ScheduledExecutorService schedulerExecutor;
+    protected ExecutorService workerExecutor;
+    protected ApplicationId appId;
+    protected boolean isLeader;
+    protected NodeId localNodeId;
+    protected LeadershipEventListener leadershipEventListener;
+
+    @Activate
+    public void activate() {
+        appId = coreService.registerApplication(VplsManager.VPLS_APP);
+        localNodeId = clusterService.getLocalNode().id();
+
+        leadershipEventListener = new InternalLeadershipListener();
+        leadershipService.addListener(leadershipEventListener);
+        leadershipService.runForLeadership(appId.name());
+        pendingVplsOperations = Maps.newConcurrentMap();
+
+        // Thread pool for VplsOperationExecutor
+        workerExecutor = newFixedThreadPool(NUM_THREADS,
+                                            groupedThreads("onos/apps/vpls",
+                                                           "worker-%d",
+                                                           log));
+        // A single thread pool for VplsOperationScheduler
+        schedulerExecutor = Executors.newScheduledThreadPool(1,
+                                                             groupedThreads("onos/apps/vpls",
+                                                                            "scheduler-%d",
+                                                                            log));
+        // Start the scheduler
+        schedulerExecutor.scheduleAtFixedRate(new VplsOperationScheduler(),
+                                              0,
+                                              500,
+                                              TimeUnit.MILLISECONDS);
+
+    }
+
+    @Deactivate
+    public void deactivate() {
+        pendingVplsOperations.clear();
+        runningOperations.clear();
+        leadershipService.removeListener(leadershipEventListener);
+        schedulerExecutor.shutdown();
+        workerExecutor.shutdown();
+
+        // remove all intents from VPLS application when deactivated
+        Tools.stream(intentService.getIntents())
+                .filter(intent -> intent.appId().equals(appId))
+                .forEach(intentService::withdraw);
+    }
+
+    @Override
+    public void submit(VplsOperation vplsOperation) {
+        if (isLeader) {
+            // Only leader can execute operation
+            addVplsOperation(vplsOperation);
+        }
+    }
+
+    /**
+     * Adds a VPLS operation to the queue of pending operations.
+     *
+     * @param vplsOperation the VPLS operation to add
+     */
+    private void addVplsOperation(VplsOperation vplsOperation) {
+        VplsData vplsData = vplsOperation.vpls();
+        pendingVplsOperations.compute(vplsData.name(), (name, opQueue) -> {
+            opQueue = opQueue == null ? Queues.newArrayDeque() : opQueue;
+
+            // If the operation already exist in queue, ignore it.
+            if (opQueue.contains(vplsOperation)) {
+                return opQueue;
+            }
+            opQueue.add(vplsOperation);
+            return opQueue;
+        });
+    }
+
+    /**
+     * Optimizes the VPLS operation queue and return a single VPLS operation to
+     * execute.
+     *
+     * @param operations the queue to be optimized
+     * @return optimized VPLS operation from the queue
+     */
+    protected static VplsOperation getOptimizedVplsOperation(Deque<VplsOperation> operations) {
+        if (operations.isEmpty()) {
+            return null;
+        }
+        // no need to optimize if the queue contains only one operation
+        if (operations.size() == 1) {
+            return operations.getFirst();
+        }
+
+        final VplsOperation firstOperation = operations.peekFirst();
+        final VplsOperation lastOperation = operations.peekLast();
+        final VplsOperation.Operation firstOp = firstOperation.op();
+        final VplsOperation.Operation lastOp = lastOperation.op();
+
+        if (firstOp.equals(VplsOperation.Operation.REMOVE)) {
+            if (lastOp.equals(VplsOperation.Operation.REMOVE)) {
+                // case 1: both first and last operation are REMOVE; do remove
+                return firstOperation;
+            } else if (lastOp.equals(VplsOperation.Operation.ADD)) {
+                // case 2: if first is REMOVE, and last is ADD; do update
+                return VplsOperation.of(lastOperation.vpls(),
+                                                 VplsOperation.Operation.UPDATE);
+            } else {
+                // case 3: first is REMOVE, last is UPDATE; do update
+                return lastOperation;
+            }
+        } else if (firstOp.equals(VplsOperation.Operation.ADD)) {
+            if (lastOp.equals(VplsOperation.Operation.REMOVE)) {
+                // case 4: first is ADD, last is REMOVE; nothing to do
+                return null;
+            } else if (lastOp.equals(VplsOperation.Operation.ADD)) {
+                // case 5: both first and last are ADD, do add
+                return VplsOperation.of(lastOperation.vpls(),
+                                                 VplsOperation.Operation.ADD);
+            } else {
+                // case 6: first is ADD and last is update, do add
+                return VplsOperation.of(lastOperation.vpls(),
+                                                 VplsOperation.Operation.ADD);
+            }
+        } else {
+            if (lastOp.equals(VplsOperation.Operation.REMOVE)) {
+                // case 7: last is remove, do remove
+                return lastOperation;
+            } else if (lastOp.equals(VplsOperation.Operation.ADD)) {
+                // case 8: do update only
+                return VplsOperation.of(lastOperation.vpls(),
+                                                 VplsOperation.Operation.UPDATE);
+            } else {
+                // case 9: from UPDATE to UPDATE
+                // only need last UPDATE operation
+                return VplsOperation.of(lastOperation.vpls(),
+                                                 VplsOperation.Operation.UPDATE);
+            }
+        }
+    }
+
+    /**
+     * Scheduler for VPLS operation.
+     * Processes a batch of VPLS operations in a period.
+     */
+    class VplsOperationScheduler implements Runnable {
+        private static final String UNKNOWN_STATE =
+                "Unknown state {} for success consumer";
+        private static final String OP_EXEC_ERR =
+                "Error when executing VPLS operation {}, error: {}";
+
+        /**
+         * Process a batch of VPLS operations.
+         */
+        @Override
+        public void run() {
+            Set<String> vplsNames = pendingVplsOperations.keySet();
+            vplsNames.forEach(vplsName -> {
+                VplsOperation operation;
+                synchronized (runningOperations) {
+                    // Only one operation for a VPLS at the same time
+                    if (runningOperations.containsKey(vplsName)) {
+                        return;
+                    }
+                    Deque<VplsOperation> operations = pendingVplsOperations.remove(vplsName);
+                    operation = getOptimizedVplsOperation(operations);
+                    if (operation == null) {
+                        // Nothing to do, this only happened when we add a VPLS
+                        // and remove it before batch operations been processed.
+                        return;
+                    }
+                    runningOperations.put(vplsName, operation);
+                }
+
+                VplsOperationExecutor operationExecutor =
+                        new VplsOperationExecutor(operation);
+                operationExecutor.setConsumers(
+                        (vplsOperation) -> {
+                            // Success consumer
+                            VplsData vplsData = vplsOperation.vpls();
+                            log.debug("VPLS operation success: {}", vplsOperation);
+                            switch (vplsData.state()) {
+                                case ADDING:
+                                case UPDATING:
+                                    vplsData.state(VplsData.VplsState.ADDED);
+                                    vplsStore.updateVpls(vplsData);
+                                    break;
+                                case REMOVING:
+                                    // The VPLS information does not exists in
+                                    // store. No need to update the store.
+                                    break;
+                                default:
+                                    log.warn(UNKNOWN_STATE, vplsData.state());
+                                    vplsData.state(VplsData.VplsState.FAILED);
+                                    vplsStore.updateVpls(vplsData);
+                                    break;
+                            }
+                            runningOperations.remove(vplsName);
+                        },
+                        (vplsOperationException) -> {
+                            // Error consumer
+                            VplsOperation vplsOperation =
+                                    vplsOperationException.vplsOperation();
+                            log.debug("VPLS operation failed: {}", vplsOperation);
+                            VplsData vplsData = vplsOperation.vpls();
+                            vplsData.state(VplsData.VplsState.FAILED);
+                            vplsStore.updateVpls(vplsData);
+                            log.error(OP_EXEC_ERR,
+                                      vplsOperation.toString(),
+                                      vplsOperationException.getMessage());
+                            runningOperations.remove(vplsName);
+                        });
+                log.debug("Applying operation: {}", operation);
+                workerExecutor.execute(operationExecutor);
+            });
+        }
+    }
+
+    /**
+     * Direction for Intent installation.
+     */
+    private enum Direction {
+        ADD,
+        REMOVE
+    }
+
+    /**
+     * VPLS operation executor.
+     * Installs, updates or removes Intents according to the given VPLS operation.
+     */
+    class VplsOperationExecutor implements Runnable {
+        private static final String UNKNOWN_OP = "Unknown operation.";
+        private static final String UNKNOWN_INTENT_DIR = "Unknown Intent install direction.";
+        private static final int OPERATION_TIMEOUT = 10;
+        private VplsOperation vplsOperation;
+        private Consumer<VplsOperation> successConsumer;
+        private Consumer<VplsOperationException> errorConsumer;
+        private VplsOperationException error;
+
+        public VplsOperationExecutor(VplsOperation vplsOperation) {
+            this.vplsOperation = vplsOperation;
+            this.error = null;
+        }
+
+        /**
+         * Sets success consumer and error consumer for this executor.
+         *
+         * @param successConsumer the success consumer
+         * @param errorConsumer the error consumer
+         */
+        public void setConsumers(Consumer<VplsOperation> successConsumer,
+                                 Consumer<VplsOperationException> errorConsumer) {
+            this.successConsumer = successConsumer;
+            this.errorConsumer = errorConsumer;
+
+        }
+
+        @Override
+        public void run() {
+            switch (vplsOperation.op()) {
+                case ADD:
+                    installVplsIntents();
+                    break;
+                case REMOVE:
+                    removeVplsIntents();
+                    break;
+                case UPDATE:
+                    updateVplsIntents();
+                    break;
+                default:
+                    this.error = new VplsOperationException(vplsOperation,
+                                                            UNKNOWN_OP);
+                    break;
+            }
+
+            if (this.error != null) {
+                errorConsumer.accept(this.error);
+            } else {
+                successConsumer.accept(vplsOperation);
+            }
+        }
+
+        /**
+         * Updates Intents of the VPLS.
+         */
+        private void updateVplsIntents() {
+            // check which part we need to update
+            // if we update host only, we don't need to reinstall
+            // every Intents
+            Set<Intent> intentsToInstall = Sets.newHashSet();
+            Set<Intent> intentsToUninstall = Sets.newHashSet();
+            VplsData vplsData = vplsOperation.vpls();
+            Set<Intent> currentIntents = getCurrentIntents();
+
+            // Compares broadcast Intents
+            Set<Intent> currentBrcIntents = currentIntents.stream()
+                    .filter(intent -> intent instanceof SinglePointToMultiPointIntent)
+                    .collect(Collectors.toSet());
+            Set<Intent> targetBrcIntents = VplsIntentUtility.buildBrcIntents(vplsData, appId);
+            if (!intentSetEquals(currentBrcIntents, targetBrcIntents)) {
+                // If broadcast Intents changes, it means some network
+                // interfaces or encapsulation constraint changed; Need to
+                // reinstall all intents
+                removeVplsIntents();
+                installVplsIntents();
+                return;
+            }
+
+            // Compares unicast Intents
+            Set<Intent> currentUniIntents = currentIntents.stream()
+                    .filter(intent -> intent instanceof MultiPointToSinglePointIntent)
+                    .collect(Collectors.toSet());
+            Set<Intent> targetUniIntents = VplsIntentUtility.buildUniIntents(vplsData,
+                                                                             hostsFromVpls(),
+                                                                             appId);
+
+            // New unicast Intents to install
+            targetUniIntents.forEach(intent -> {
+                if (!currentUniIntents.contains(intent)) {
+                    intentsToInstall.add(intent);
+                }
+            });
+
+            // Old unicast Intents to remove
+            currentUniIntents.forEach(intent -> {
+                if (!targetUniIntents.contains(intent)) {
+                    intentsToUninstall.add(intent);
+                }
+            });
+            applyIntentsSync(intentsToUninstall, Direction.REMOVE);
+            applyIntentsSync(intentsToInstall, Direction.ADD);
+        }
+
+        private Set<Host> hostsFromVpls() {
+            VplsData vplsData = vplsOperation.vpls();
+            Set<Interface> interfaces = vplsData.interfaces();
+            return interfaces.stream()
+                    .map(this::hostsFromInterface)
+                    .flatMap(Collection::stream)
+                    .collect(Collectors.toSet());
+        }
+
+        private Set<Host> hostsFromInterface(Interface iface) {
+            return hostService.getConnectedHosts(iface.connectPoint())
+                    .stream()
+                    .filter(host -> host.vlan().equals(iface.vlan()))
+                    .collect(Collectors.toSet());
+        }
+
+        /**
+         * Applies Intents synchronously with a specific direction.
+         *
+         * @param intents the Intents
+         * @param direction the direction
+         */
+        private void applyIntentsSync(Set<Intent> intents, Direction direction) {
+            Set<Key> pendingIntentKeys = intents.stream()
+                    .map(Intent::key).collect(Collectors.toSet());
+            IntentCompleter completer;
+
+            switch (direction) {
+                case ADD:
+                    completer = new IntentCompleter(pendingIntentKeys,
+                                                    IntentEvent.Type.INSTALLED);
+                    intentService.addListener(completer);
+                    intents.forEach(intentService::submit);
+                    break;
+                case REMOVE:
+                    completer = new IntentCompleter(pendingIntentKeys,
+                                                    IntentEvent.Type.WITHDRAWN);
+                    intentService.addListener(completer);
+                    intents.forEach(intentService::withdraw);
+                    break;
+                default:
+                    this.error = new VplsOperationException(this.vplsOperation,
+                                                            UNKNOWN_INTENT_DIR);
+                    return;
+            }
+
+            try {
+                // Wait until Intent operation completed
+                completer.complete();
+            } catch (VplsOperationException e) {
+                this.error = e;
+            } finally {
+                intentService.removeListener(completer);
+            }
+        }
+
+        /**
+         * Checks if two sets of Intents are equal.
+         *
+         * @param intentSet1 the first set of Intents
+         * @param intentSet2 the second set of Intents
+         * @return true if both set of Intents are equal; otherwise false
+         */
+        private boolean intentSetEquals(Set<Intent> intentSet1, Set<Intent> intentSet2) {
+            if (intentSet1.size() != intentSet2.size()) {
+                return false;
+            }
+            for (Intent intent1 : intentSet1) {
+                if (intentSet2.stream()
+                        .noneMatch(intent2 -> IntentUtils.intentsAreEqual(intent1, intent2))) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        /**
+         * Retrieves installed Intents from IntentService which related to
+         * specific VPLS.
+         *
+         * @return the Intents which related to the VPLS
+         */
+        private Set<Intent> getCurrentIntents() {
+            VplsData vplsData = vplsOperation.vpls();
+            String vplsName = vplsData.name();
+            return Tools.stream(intentService.getIntents())
+                    .filter(intent -> intent.key().toString().startsWith(vplsName))
+                    .collect(Collectors.toSet());
+        }
+
+        /**
+         * Generates unicast Intents and broadcast Intents for the VPLS.
+         *
+         * @return Intents for the VPLS
+         */
+        private Set<Intent> generateVplsIntents() {
+            VplsData vplsData = vplsOperation.vpls();
+            Set<Intent> brcIntents = VplsIntentUtility.buildBrcIntents(vplsData, appId);
+            Set<Intent> uniIntent = VplsIntentUtility.buildUniIntents(vplsData, hostsFromVpls(), appId);
+
+            return Stream.concat(brcIntents.stream(), uniIntent.stream())
+                    .collect(Collectors.toSet());
+        }
+
+        /**
+         * Removes all Intents from the VPLS.
+         */
+        private void removeVplsIntents() {
+            Set<Intent> intentsToWithdraw = getCurrentIntents();
+            applyIntentsSync(intentsToWithdraw, Direction.REMOVE);
+        }
+
+        /**
+         * Installs Intents of the VPLS.
+         */
+        private void installVplsIntents() {
+            Set<Intent> intentsToInstall = generateVplsIntents();
+            applyIntentsSync(intentsToInstall, Direction.ADD);
+        }
+
+        /**
+         * Helper class which monitors if all Intent operations are completed.
+         */
+        class IntentCompleter implements IntentListener {
+            private static final String INTENT_COMPILE_ERR = "Got {} from intent completer";
+            private CompletableFuture<Void> completableFuture;
+            private Set<Key> pendingIntentKeys;
+            private IntentEvent.Type expectedEventType;
+
+            /**
+             * Initialize completer with given Intent keys and expect Intent
+             * event type.
+             *
+             * @param pendingIntentKeys the Intent keys to wait
+             * @param expectedEventType expect Intent event type
+             */
+            public IntentCompleter(Set<Key> pendingIntentKeys, IntentEvent.Type expectedEventType) {
+                this.completableFuture = new CompletableFuture<>();
+                this.pendingIntentKeys = Sets.newConcurrentHashSet(pendingIntentKeys);
+                this.expectedEventType = expectedEventType;
+            }
+
+            @Override
+            public void event(IntentEvent event) {
+                Intent intent = event.subject();
+                // Intent failed, throw an exception to completable future
+                if (event.type() == IntentEvent.Type.CORRUPT ||
+                        event.type() == IntentEvent.Type.FAILED) {
+                    completableFuture.completeExceptionally(new IntentException(intent.toString()));
+                    return;
+                }
+                // If event type matched to expected type, remove from pending
+                if (event.type() == expectedEventType) {
+                    Key key = intent.key();
+                    pendingIntentKeys.remove(key);
+                }
+                if (pendingIntentKeys.isEmpty()) {
+                    completableFuture.complete(null);
+                }
+            }
+
+            /**
+             * Waits until all pending Intents completed ot timeout.
+             */
+            public void complete() {
+                // If no pending Intent keys, complete directly
+                if (pendingIntentKeys.isEmpty()) {
+                    return;
+                }
+                try {
+                    completableFuture.get(OPERATION_TIMEOUT, TimeUnit.SECONDS);
+                } catch (TimeoutException | InterruptedException |
+                         ExecutionException | IntentException e) {
+                    // TODO: handle errors more carefully
+                    log.warn(INTENT_COMPILE_ERR, e.toString());
+                    throw new VplsOperationException(vplsOperation, e.toString());
+                }
+            }
+        }
+    }
+
+    /**
+     * A listener for leadership events.
+     * Only the leader can process VPLS operation in the ONOS cluster.
+     */
+    private class InternalLeadershipListener implements LeadershipEventListener {
+        private static final String LEADER_CHANGE = "Change leader to {}";
+
+        @Override
+        public void event(LeadershipEvent event) {
+            switch (event.type()) {
+                case LEADER_CHANGED:
+                case LEADER_AND_CANDIDATES_CHANGED:
+                    isLeader = localNodeId.equals(event.subject().leaderNodeId());
+                    if (isLeader) {
+                        log.debug(LEADER_CHANGE, localNodeId);
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        @Override
+        public boolean isRelevant(LeadershipEvent event) {
+            return event.subject().topic().equals(appId.name());
+        }
+    }
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/api/Vpls.java b/apps/vpls/src/main/java/org/onosproject/vpls/api/Vpls.java
new file mode 100644
index 0000000..5dec2b2
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/api/Vpls.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vpls.api;
+
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.net.EncapsulationType;
+
+import java.util.Collection;
+
+public interface Vpls {
+
+    /**
+     * Creates a new VPLS.
+     *
+     * @param vplsName the name of the VPLS
+     * @param encapsulationType the encapsulation type
+     * @return a VPLS instance if the operation is successful; null otherwise
+     */
+    VplsData createVpls(String vplsName, EncapsulationType encapsulationType);
+
+    /**
+     * Removes a VPLS.
+     *
+     * @param vplsData the VPLS to be removed
+     * @return the VPLS removed if the operation is successful; null otherwise
+     */
+    VplsData removeVpls(VplsData vplsData);
+
+    /**
+     * Adds network interfaces to a VPLS.
+     *
+     * @param vplsData the VPLS to which the interfaces have to be added to
+     * @param interfaces the interfaces to add
+     */
+    void addInterfaces(VplsData vplsData, Collection<Interface> interfaces);
+
+    /**
+     * Adds a network interface to a VPLS.
+     *
+     * @param vplsData the VPLS to which the interface has to be added to
+     * @param iface the interface to add
+     */
+    void addInterface(VplsData vplsData, Interface iface);
+
+    /**
+     * Sets an encapsulation type for a VPLS.
+     *
+     * @param vplsData the VPLS for which the encapsulation has to be set
+     * @param encapsulationType the encapsulation type
+     */
+    void setEncapsulationType(VplsData vplsData, EncapsulationType encapsulationType);
+
+    /**
+     * Retrieves a VPLS.
+     *
+     * @param vplsName the name of the VPLS
+     * @return the VPLS instance if the VPLS exists; null otherwise
+     */
+    VplsData getVpls(String vplsName);
+
+    /**
+     * Gets all VPLSs.
+     *
+     * @return a collection of VPLSs
+     */
+    Collection<VplsData> getAllVpls();
+
+    /**
+     * Removes the interfaces specified from a VPLS.
+     *
+     * @param vplsData the VPLS from which the interfaces are to be removed
+     * @param interfaces the interfaces to remove
+     * @return the interfaces removed
+     */
+    Collection<Interface> removeInterfaces(VplsData vplsData, Collection<Interface> interfaces);
+
+    /**
+     * Removes the interface specified from a VPLS.
+     *
+     * @param vplsData the VPLS from which the interface is to be removed
+     * @param iface the interface to remove
+     * @return the interface removed
+     */
+    Interface removeInterface(VplsData vplsData, Interface iface);
+
+    /**
+     * Removes all VPLSs and cleans up the VPLS configuration.
+     */
+    void removeAllVpls();
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/api/VplsData.java b/apps/vpls/src/main/java/org/onosproject/vpls/api/VplsData.java
new file mode 100644
index 0000000..bba9d78
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/api/VplsData.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vpls.api;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.net.EncapsulationType;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Set;
+
+import static java.util.Objects.*;
+
+/**
+ * Class stores a VPLS information.
+ */
+public final class VplsData {
+    /**
+     * States of a VPLS.
+     */
+    public enum VplsState {
+        UPDATING,
+        ADDING,
+        REMOVING,
+        ADDED,
+        REMOVED,
+        FAILED
+    }
+
+    private String name;
+    private Set<Interface> interfaces;
+    private EncapsulationType encapsulationType;
+    private VplsState state;
+
+    /**
+     * Constructs a VPLS data by given name and encapsulation type.
+     *
+     * @param name the given name
+     * @param encapType the encapsulation type
+     */
+    private VplsData(String name, EncapsulationType encapType) {
+        this.name = name;
+        this.encapsulationType = encapType;
+        this.interfaces = Sets.newHashSet();
+        this.state = VplsState.ADDING;
+    }
+
+    /**
+     * Creates a VPLS data by given name.
+     * The encapsulation type of the VPLS will be NONE.
+     *
+     * @param name the given name
+     * @return the VPLS data
+     */
+    public static VplsData of(String name) {
+        requireNonNull(name);
+        return new VplsData(name, EncapsulationType.NONE);
+    }
+
+    /**
+     * Creates a VPLS data by given name and encapsulation type.
+     *
+     * @param name the given name
+     * @param encapType the encapsulation type
+     * @return the VPLS data
+     */
+    public static VplsData of(String name, EncapsulationType encapType) {
+        requireNonNull(name);
+        if (encapType == null) {
+            return new VplsData(name, EncapsulationType.NONE);
+        } else {
+            return new VplsData(name, encapType);
+        }
+    }
+
+    /**
+     * Creates a copy of VPLS data.
+     *
+     * @param vplsData the VPLS data
+     * @return the copy of the VPLS data
+     */
+    public static VplsData of(VplsData vplsData) {
+        requireNonNull(vplsData);
+        VplsData vplsDataCopy = new VplsData(vplsData.name(), vplsData.encapsulationType());
+        vplsDataCopy.addInterfaces(vplsData.interfaces());
+        return vplsData;
+    }
+
+    /**
+     * Gets name of the VPLS.
+     *
+     * @return the name of the VPLS
+     */
+    public String name() {
+        return name;
+    }
+
+    public Set<Interface> interfaces() {
+        return ImmutableSet.copyOf(interfaces);
+    }
+
+    public EncapsulationType encapsulationType() {
+        return encapsulationType;
+    }
+
+    public void addInterfaces(Collection<Interface> interfaces) {
+        requireNonNull(interfaces);
+        this.interfaces.addAll(interfaces);
+    }
+
+    public void addInterface(Interface iface) {
+        requireNonNull(iface);
+        this.interfaces.add(iface);
+    }
+
+    public void removeInterfaces(Collection<Interface> interfaces) {
+        requireNonNull(interfaces);
+        this.interfaces.removeAll(interfaces);
+    }
+
+    public void removeInterface(Interface iface) {
+        requireNonNull(iface);
+        this.interfaces.remove(iface);
+    }
+
+    public void encapsulationType(EncapsulationType encapType) {
+        this.encapsulationType = encapType;
+    }
+
+    public VplsState state() {
+        return state;
+    }
+
+    public void state(VplsState state) {
+        this.state = state;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("name", name)
+                .add("interfaces", interfaces)
+                .add("encap type", encapsulationType)
+                .add("state", state)
+                .toString();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof VplsData)) {
+            return false;
+        }
+        VplsData other = (VplsData) obj;
+        return Objects.equals(other.name, this.name) &&
+                Objects.equals(other.interfaces, this.interfaces) &&
+                Objects.equals(other.encapsulationType, this.encapsulationType);
+    }
+
+    @Override
+    public int hashCode() {
+        return hash(name, interfaces, encapsulationType);
+    }
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/api/VplsOperation.java b/apps/vpls/src/main/java/org/onosproject/vpls/api/VplsOperation.java
new file mode 100644
index 0000000..abc5025
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/api/VplsOperation.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vpls.api;
+
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+import static java.util.Objects.*;
+
+/**
+ * Operation for VPLS.
+ */
+public class VplsOperation {
+
+    /**
+     * The operation type.
+     */
+    public enum Operation {
+        REMOVE,
+        ADD,
+        UPDATE
+    }
+
+    private VplsData vplsData;
+    private Operation op;
+
+    /**
+     * Defines a VPLS operation by binding a given VPLS and operation type.
+     *
+     * @param vplsData the VPLS
+     * @param op the operation
+     */
+    protected VplsOperation(VplsData vplsData, Operation op) {
+        requireNonNull(vplsData);
+        requireNonNull(op);
+        // Make a copy of the VPLS data to ensure other thread won't change it.
+        this.vplsData = VplsData.of(vplsData);
+        this.op = op;
+    }
+
+    /**
+     * Defines a VPLS operation by binding a given VPLS and operation type.
+     *
+     * @param vplsData the VPLS
+     * @param op the operation
+     * @return the VPLS operation
+     */
+    public static VplsOperation of(VplsData vplsData, Operation op) {
+        return new VplsOperation(vplsData, op);
+    }
+
+    /**
+     * Retrieves the VPLS from the operation.
+     *
+     * @return the VPLS
+     */
+    public VplsData vpls() {
+        return vplsData;
+    }
+
+    /**
+     * Retrieves the operation type from the operation.
+     *
+     * @return the operation type
+     */
+    public Operation op() {
+        return op;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("vplsData", vplsData.toString())
+                .add("op", op.toString())
+                .toString();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof VplsOperation)) {
+            return false;
+        }
+        VplsOperation other = (VplsOperation) obj;
+        return Objects.equals(other.vplsData, this.vplsData) &&
+                Objects.equals(other.op, this.op);
+    }
+
+    @Override
+    public int hashCode() {
+        return hash(vplsData, op);
+    }
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/api/VplsOperationException.java b/apps/vpls/src/main/java/org/onosproject/vpls/api/VplsOperationException.java
new file mode 100644
index 0000000..95dfdfa
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/api/VplsOperationException.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vpls.api;
+
+/**
+ * Exception for VPLS operation.
+ */
+public class VplsOperationException extends RuntimeException {
+    private static final long serialVersionUID = 4514685940685335886L;
+    private VplsOperation vplsOperation;
+
+    /**
+     * Constructs a VPLS operation exception with given VPLS operation and
+     * message.
+     *
+     * @param operation the VPLS operation
+     * @param msg the description of the exception
+     */
+    public VplsOperationException(VplsOperation operation, String msg) {
+        super(msg);
+        this.vplsOperation = operation;
+    }
+
+    /**
+     * Gets VPLS operation for this exception.
+     * @return the VPLS operation
+     */
+    public VplsOperation vplsOperation() {
+        return vplsOperation;
+    }
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java b/apps/vpls/src/main/java/org/onosproject/vpls/api/VplsOperationService.java
similarity index 62%
copy from apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java
copy to apps/vpls/src/main/java/org/onosproject/vpls/api/VplsOperationService.java
index b5d6ec9..3044f7e 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/api/VplsOperationService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Laboratory
+ * Copyright 2017-present Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,17 @@
  * limitations under the License.
  */
 
+package org.onosproject.vpls.api;
+
 /**
- * Configuration service implementation for VPLS.
+ * Service for application submitting VPLS operation.
  */
-package org.onosproject.vpls.config.impl;
+public interface VplsOperationService {
+
+    /**
+     * Submits a VPLS operation.
+     *
+     * @param vplsOperation the VPLS operation to submit
+     */
+    void submit(VplsOperation vplsOperation);
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/api/VplsStore.java b/apps/vpls/src/main/java/org/onosproject/vpls/api/VplsStore.java
new file mode 100644
index 0000000..caf7550
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/api/VplsStore.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vpls.api;
+
+import org.onosproject.store.Store;
+import org.onosproject.store.StoreDelegate;
+import org.onosproject.vpls.store.VplsStoreEvent;
+
+import java.util.Collection;
+
+/**
+ * Definition of the operations regarding the management of the VPLS elements.
+ */
+public interface VplsStore extends Store<VplsStoreEvent, StoreDelegate<VplsStoreEvent>> {
+    /**
+     * Adds a VPLS to the configuration.
+     *
+     * @param vplsData the VPLS to add
+     */
+    void addVpls(VplsData vplsData);
+
+    /**
+     * Removes a VPLS from the configuration.
+     *
+     * @param vplsData the VPLS to remove
+     */
+    void removeVpls(VplsData vplsData);
+
+    /**
+     * Updates a VPLS.
+     *
+     * @param vplsData the VPLS to update
+     */
+    void updateVpls(VplsData vplsData);
+
+    /**
+     * Gets a VPLS by name.
+     *
+     * @param vplsName the VPLS name
+     * @return the VPLS instance if it exists; null otherwise
+     */
+    VplsData getVpls(String vplsName);
+
+    /**
+     * Gets all the VPLSs.
+     *
+     * @return all the VPLSs
+     */
+    Collection<VplsData> getAllVpls();
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java b/apps/vpls/src/main/java/org/onosproject/vpls/api/package-info.java
similarity index 79%
rename from apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java
rename to apps/vpls/src/main/java/org/onosproject/vpls/api/package-info.java
index b5d6ec9..91d3937 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/api/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Laboratory
+ * Copyright 2017-present Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,6 +15,6 @@
  */
 
 /**
- * Configuration service implementation for VPLS.
+ * APIs for VPLS.
  */
-package org.onosproject.vpls.config.impl;
+package org.onosproject.vpls.api;
\ No newline at end of file
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsCommand.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsCommand.java
index d4bfa8d..4718453 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsCommand.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsCommand.java
@@ -15,24 +15,24 @@
  */
 package org.onosproject.vpls.cli;
 
-import com.google.common.collect.Lists;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
 import org.onosproject.cli.AbstractShellCommand;
 import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
 import org.onosproject.net.EncapsulationType;
-import org.onosproject.vpls.config.VplsConfigService;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.api.Vpls;
 
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
-import java.util.Optional;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import static com.google.common.base.Strings.isNullOrEmpty;
 
+
 /**
  * CLI to interact with the VPLS application.
  */
@@ -85,7 +85,8 @@
                     " not found" + RESET;
 
     private static final String VPLS_DISPLAY = "VPLS name: " + BOLD +
-            "%s" + RESET + "\nAssociated interfaces: %s\nEncapsulation: %s";
+            "%s" + RESET + "\nAssociated interfaces: %s\nEncapsulation: %s\n" +
+            "State: %s";
 
     private static final String VPLS_NOT_FOUND =
             COLOR_ERROR + "VPLS " + BOLD + "%s" + RESET + COLOR_ERROR +
@@ -93,15 +94,13 @@
 
     private static final String IFACE_NOT_ASSOCIATED =
             COLOR_ERROR + "Interface " + BOLD + "%s" + RESET + COLOR_ERROR +
-                    " cannot be removed from VPLS " + BOLD + "%s" + RESET +
-                    COLOR_ERROR + ". The interface is associated to another" +
-                    "VPLS (" + BOLD + "%s" + RESET + COLOR_ERROR + ")" + RESET;
+                    " cannot be removed from VPLS " + BOLD + "%s" + RESET + ".";
 
-    private static VplsConfigService vplsConfigService =
-            get(VplsConfigService.class);
+    protected static Vpls vpls;
+    protected static InterfaceService interfaceService;
 
     @Argument(index = 0, name = "command", description = "Command name (add-if|" +
-            "clean|create|delete|list|rem-if|set-encap|show)",
+            "create|delete|list|rem-if|set-encap|show)",
             required = true, multiValued = false)
     String command = null;
 
@@ -116,15 +115,19 @@
 
     @Override
     protected void execute() {
+        if (vpls == null) {
+            vpls = get(Vpls.class);
+        }
+        if (interfaceService == null) {
+            interfaceService = get(InterfaceService.class);
+        }
+
         VplsCommandEnum enumCommand = VplsCommandEnum.enumFromString(command);
         if (enumCommand != null) {
             switch (enumCommand) {
                 case ADD_IFACE:
                     addIface(vplsName, optArg);
                     break;
-                case CLEAN:
-                    clean();
-                    break;
                 case CREATE:
                     create(vplsName);
                     break;
@@ -143,6 +146,9 @@
                 case SHOW:
                     show(vplsName);
                     break;
+                case CLEAN:
+                    cleanVpls();
+                    break;
                 default:
                     print(VPLS_COMMAND_NOT_FOUND, command);
             }
@@ -157,7 +163,7 @@
      * @param vplsName the name of the VLPS
      * @param ifaceName the name of the interface to add
      */
-    private void addIface(String vplsName, String ifaceName) {
+    protected void addIface(String vplsName, String ifaceName) {
         if (vplsName == null) {
             print(INSERT_VPLS_NAME);
             return;
@@ -166,28 +172,24 @@
             print(INSERT_INTERFACE);
             return;
         }
-        if (!vplsExists(vplsName)) {
+
+        Interface iface = getInterface(ifaceName);
+        VplsData vplsData = vpls.getVpls(vplsName);
+
+        if (vplsData == null) {
             print(VPLS_NOT_FOUND, vplsName);
             return;
         }
-        if (!ifaceExists(ifaceName)) {
+        if (iface == null) {
             print(IFACE_NOT_FOUND, ifaceName);
             return;
         }
-        if (isIfaceAssociated(ifaceName)) {
+        if (isIfaceAssociated(iface)) {
             print(IFACE_ALREADY_ASSOCIATED,
-                  ifaceName, vplsNameFromIfaceName(ifaceName));
+                  ifaceName, getVplsByInterface(iface).name());
             return;
         }
-
-        vplsConfigService.addIface(vplsName, ifaceName);
-    }
-
-    /**
-     * Cleans the VPLS configuration.
-     */
-    private void clean() {
-        vplsConfigService.cleanVplsConfig();
+        vpls.addInterface(vplsData, iface);
     }
 
     /**
@@ -195,16 +197,17 @@
      *
      * @param vplsName the name of the VLPS
      */
-    private void create(String vplsName) {
+    protected void create(String vplsName) {
         if (vplsName == null || vplsName.isEmpty()) {
             print(INSERT_VPLS_NAME);
             return;
         }
-        if (vplsExists(vplsName)) {
+        VplsData vplsData = vpls.getVpls(vplsName);
+        if (vplsData != null) {
             print(VPLS_ALREADY_EXISTS, vplsName);
             return;
         }
-        vplsConfigService.addVpls(vplsName, Sets.newHashSet(), null);
+        vpls.createVpls(vplsName, EncapsulationType.NONE);
     }
 
     /**
@@ -212,23 +215,26 @@
      *
      * @param vplsName the name of the VLPS
      */
-    private void delete(String vplsName) {
+    protected void delete(String vplsName) {
         if (vplsName == null) {
             print(INSERT_VPLS_NAME);
             return;
         }
-        if (!vplsExists(vplsName)) {
+        VplsData vplsData = vpls.getVpls(vplsName);
+        if (vplsData == null) {
             print(VPLS_NOT_FOUND, vplsName);
             return;
         }
-        vplsConfigService.removeVpls(vplsName);
+        vpls.removeVpls(vplsData);
     }
 
     /**
      * Lists the configured VPLSs.
      */
-    private void list() {
-        List<String> vplsNames = Lists.newArrayList(vplsConfigService.vplsNames());
+    protected void list() {
+        List<String> vplsNames = vpls.getAllVpls().stream()
+                .map(VplsData::name)
+                .collect(Collectors.toList());
         Collections.sort(vplsNames);
 
         vplsNames.forEach(vpls -> {
@@ -242,7 +248,7 @@
      * @param vplsName the name of the VLPS
      * @param ifaceName the name of the interface to remove
      */
-    private void removeIface(String vplsName, String ifaceName) {
+    protected void removeIface(String vplsName, String ifaceName) {
         if (vplsName == null) {
             print(INSERT_VPLS_NAME);
             return;
@@ -251,20 +257,21 @@
             print(INSERT_INTERFACE);
             return;
         }
-        if (!vplsExists(vplsName)) {
+        VplsData vplsData = vpls.getVpls(vplsName);
+        Interface iface = getInterface(ifaceName);
+        if (vplsData == null) {
             print(VPLS_NOT_FOUND, vplsName);
             return;
         }
-        if (!ifaceExists(ifaceName)) {
+        if (iface == null) {
             print(IFACE_NOT_FOUND, ifaceName);
             return;
         }
-        String vplsNameFromIfaceName = vplsNameFromIfaceName(ifaceName);
-        if (!vplsNameFromIfaceName.equals(vplsName)) {
-            print(IFACE_NOT_ASSOCIATED, ifaceName, vplsName, vplsNameFromIfaceName);
+        if (!vplsData.interfaces().contains(iface)) {
+            print(IFACE_NOT_ASSOCIATED, ifaceName, vplsName);
             return;
         }
-        vplsConfigService.removeIface(ifaceName);
+        vpls.removeInterface(vplsData, iface);
     }
 
     /**
@@ -273,7 +280,7 @@
      * @param vplsName the name of the VPLS
      * @param encap the encapsulation type
      */
-    private void setEncap(String vplsName, String encap) {
+    protected void setEncap(String vplsName, String encap) {
         if (vplsName == null) {
             print(INSERT_VPLS_NAME);
             return;
@@ -282,7 +289,8 @@
             print(INSERT_ENCAP_TYPE);
             return;
         }
-        if (!vplsExists(vplsName)) {
+        VplsData vplsData = vpls.getVpls(vplsName);
+        if (vplsData == null) {
             print(VPLS_NOT_FOUND, vplsName);
             return;
         }
@@ -292,7 +300,7 @@
             print(ENCAP_NOT_FOUND, encap);
             return;
         }
-        vplsConfigService.setEncap(vplsName, encap);
+        vpls.setEncapsulationType(vplsData, encapType);
     }
 
     /**
@@ -300,113 +308,88 @@
      *
      * @param vplsName the name of the VPLS
      */
-    private void show(String vplsName) {
-        List<String> vplsNames = Lists.newArrayList(vplsConfigService.vplsNames());
-        Collections.sort(vplsNames);
-
-        Map<String, EncapsulationType> encapByVplsName =
-                vplsConfigService.encapByVplsName();
-
+    protected void show(String vplsName) {
         if (!isNullOrEmpty(vplsName)) {
             // A VPLS name is provided. Check first if the VPLS exists
-            if (vplsExists(vplsName)) {
+            VplsData vplsData = vpls.getVpls(vplsName);
+            if (vplsData != null) {
+                Set<String> ifaceNames = vplsData.interfaces().stream()
+                        .map(Interface::name)
+                        .collect(Collectors.toSet());
                 print(VPLS_DISPLAY,
                       vplsName,
-                      ifacesFromVplsName(vplsName).toString(),
-                      encapByVplsName.get(vplsName).toString());
+                      ifaceNames,
+                      vplsData.encapsulationType().toString(),
+                      vplsData.state());
             } else {
                 print(VPLS_NOT_FOUND, vplsName);
             }
         } else {
+            Collection<VplsData> vplses = vpls.getAllVpls();
             // No VPLS names are provided. Display all VPLSs configured
             print(SEPARATOR);
-            vplsNames.forEach(v -> {
+            vplses.forEach(vplsData -> {
+                Set<String> ifaceNames = vplsData.interfaces().stream()
+                        .map(Interface::name)
+                        .collect(Collectors.toSet());
                 print(VPLS_DISPLAY,
-                      v,
-                      ifacesFromVplsName(v).toString(),
-                      encapByVplsName.get(v).toString());
+                      vplsData.name(),
+                      ifaceNames,
+                      vplsData.encapsulationType().toString(),
+                      vplsData.state());
                 print(SEPARATOR);
             });
         }
     }
 
     /**
-     * States if a VPLS exists or not.
-     *
-     * @param vplsName the name of the VPLS
-     * @return true if the VPLS exists; false otherwise
+     * Remove all VPLS.
      */
-    private static boolean vplsExists(String vplsName) {
-        return vplsConfigService.vplsNames().contains(vplsName);
+    protected void cleanVpls() {
+        vpls.removeAllVpls();
     }
 
-    /**
-     * States if an interface is defined or not in the system.
-     *
-     * @param ifaceName the name of the interface
-     * @return true if the interface is defined; false otherwise
-     */
-    private static boolean ifaceExists(String ifaceName) {
-        return vplsConfigService.allIfaces()
-                .stream()
-                .anyMatch(iface -> iface.name().equals(ifaceName));
-    }
 
     /**
      * States if an interface is already associated to a VPLS.
      *
-     * @param ifaceName the name of the interface
+     * @param iface the interface
      * @return true if the interface is already associated to a VPLS; false
      * otherwise
      */
-    private static boolean isIfaceAssociated(String ifaceName) {
-        return vplsConfigService.ifaces()
+    private static boolean isIfaceAssociated(Interface iface) {
+        return vpls.getAllVpls()
                 .stream()
-                .anyMatch(iface -> iface.name().equals(ifaceName));
+                .map(VplsData::interfaces)
+                .flatMap(Collection::stream)
+                .anyMatch(iface::equals);
     }
 
     /**
-     * Returns the name of a VPLS, given the name of an interface associated to
-     * it.
+     * Gets a network interface by given interface name.
      *
-     * @param ifaceName the name of the interface
-     * @return the name of the VPLS that has the interface configured; null if
-     * the interface does not exist or is not associated to any VPLS
+     * @param interfaceName the interface name
+     * @return the network interface
      */
-    private static String vplsNameFromIfaceName(String ifaceName) {
-        String vplsName = null;
-
-        Optional<String> optVplsName = vplsConfigService.ifacesByVplsName()
-                .entries()
-                .stream()
-                .filter((entry -> entry.getValue().name().equals(ifaceName)))
-                .map(Map.Entry::getKey)
-                .findFirst();
-
-        if (optVplsName.isPresent()) {
-            vplsName = optVplsName.get();
-        }
-
-        return vplsName;
+    private Interface getInterface(String interfaceName) {
+        // FIXME: only returns first interface it found
+        // multiple interface with same name not support
+        return interfaceService.getInterfaces().stream()
+                .filter(iface -> iface.name().equals(interfaceName))
+                .findFirst()
+                .orElse(null);
     }
 
     /**
-     * Returns a list of interfaces associated to a VPLS, given a VPLS name.
+     * Gets a VPLS related to the network interface.
      *
-     * @param vplsName the name of the VPLS
-     * @return the set of interfaces associated to the given VPLS; null if the
-     * VPLS is not found
+     * @param iface the network interface
+     * @return the VPLS related to the network interface
      */
-    private static Set<String> ifacesFromVplsName(String vplsName) {
-        if (!vplsExists(vplsName)) {
-            return null;
-        }
-        SetMultimap<String, Interface> ifacesByVplsName =
-                vplsConfigService.ifacesByVplsName();
-        Set<String> ifaceNames = Sets.newHashSet();
-
-        ifacesByVplsName.get(vplsName).forEach(iface -> ifaceNames.add(iface.name()));
-
-        return ifaceNames;
+    private VplsData getVplsByInterface(Interface iface) {
+        return vpls.getAllVpls().stream()
+                .filter(vplsData -> vplsData.interfaces().contains(iface))
+                .findFirst()
+                .orElse(null);
     }
 }
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsCommandEnum.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsCommandEnum.java
index dfdaadf..c1ccb2b 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsCommandEnum.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/VplsCommandEnum.java
@@ -25,13 +25,13 @@
  */
 public enum VplsCommandEnum {
     ADD_IFACE("add-if"),
-    CLEAN("clean"),
     CREATE("create"),
     DELETE("delete"),
     LIST("list"),
     REMOVE_IFACE("rem-if"),
     SET_ENCAP("set-encap"),
-    SHOW("show");
+    SHOW("show"),
+    CLEAN("clean");
 
     private final String command;
 
@@ -40,7 +40,7 @@
      *
      * @param command the text representing the command
      */
-    private VplsCommandEnum(final String command) {
+    VplsCommandEnum(final String command) {
         this.command = command;
     }
 
@@ -56,7 +56,7 @@
      */
     public static List<String> toStringList() {
         return Arrays.stream(values())
-                .map(c -> c.toString())
+                .map(VplsCommandEnum::toString)
                 .collect(Collectors.toCollection(ArrayList::new));
     }
 
@@ -71,7 +71,7 @@
     public static VplsCommandEnum enumFromString(String command) {
         if (command != null && !command.isEmpty()) {
             for (VplsCommandEnum c : values()) {
-                if (command.toString().equalsIgnoreCase(c.toString())) {
+                if (command.equalsIgnoreCase(c.toString())) {
                     return c;
                 }
             }
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsCommandCompleter.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsCommandCompleter.java
index cfe08b7..2b198a9 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsCommandCompleter.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsCommandCompleter.java
@@ -16,6 +16,7 @@
 package org.onosproject.vpls.cli.completer;
 
 import com.google.common.collect.Lists;
+import org.apache.karaf.shell.console.completer.ArgumentCompleter;
 import org.onosproject.cli.AbstractChoicesCompleter;
 import org.onosproject.vpls.cli.VplsCommandEnum;
 
@@ -29,17 +30,19 @@
 
     @Override
     public List<String> choices() {
-        List<String> argumentList =
-                Lists.newArrayList(getArgumentList().getArguments());
+        ArgumentCompleter.ArgumentList argumentList = getArgumentList();
+        if (argumentList == null) {
+            return Collections.emptyList();
+        }
+        List<String> argList = Lists.newArrayList(argumentList.getArguments());
         String argOne = null;
-        if (argumentList.size() > 1) {
-            argOne = argumentList.get(1);
+        if (argList.size() > 1) {
+            argOne = argList.get(1);
         }
         VplsCommandEnum vplsCommandEnum = VplsCommandEnum.enumFromString(argOne);
         if (vplsCommandEnum != null) {
             switch (vplsCommandEnum) {
                 case CREATE:
-                case CLEAN:
                 case LIST:
                     return Collections.emptyList();
                 default:
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsNameCompleter.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsNameCompleter.java
index ab2479b..6900880 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsNameCompleter.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsNameCompleter.java
@@ -15,11 +15,13 @@
  */
 package org.onosproject.vpls.cli.completer;
 
-import com.google.common.collect.Lists;
 import org.onosproject.cli.AbstractChoicesCompleter;
-import org.onosproject.vpls.config.VplsConfigService;
+import org.onosproject.vpls.api.Vpls;
+import org.onosproject.vpls.api.VplsData;
 
+import java.util.Collection;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import static org.onosproject.cli.AbstractShellCommand.get;
 
@@ -28,9 +30,14 @@
  */
 public class VplsNameCompleter extends AbstractChoicesCompleter {
 
+    protected static Vpls vpls;
+
     @Override
     public List<String> choices() {
-        VplsConfigService vplsConfigService = get(VplsConfigService.class);
-        return Lists.newArrayList(vplsConfigService.vplsNames());
+        if (vpls == null) {
+            vpls = get(Vpls.class);
+        }
+        Collection<VplsData> vplses = vpls.getAllVpls();
+        return vplses.stream().map(VplsData::name).collect(Collectors.toList());
     }
 }
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsOptArgCompleter.java b/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsOptArgCompleter.java
index 5b60352..7058cdc 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsOptArgCompleter.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/cli/completer/VplsOptArgCompleter.java
@@ -16,15 +16,17 @@
 package org.onosproject.vpls.cli.completer;
 
 import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
 import org.apache.karaf.shell.console.completer.ArgumentCompleter;
 import org.onosproject.cli.AbstractChoicesCompleter;
 import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
 import org.onosproject.net.EncapsulationType;
+import org.onosproject.vpls.api.Vpls;
+import org.onosproject.vpls.api.VplsData;
 import org.onosproject.vpls.cli.VplsCommandEnum;
-import org.onosproject.vpls.config.VplsConfigService;
 
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
@@ -36,22 +38,29 @@
  * VPLS optional argument completer.
  */
 public class VplsOptArgCompleter extends AbstractChoicesCompleter {
+    protected static Vpls vpls;
+    protected static InterfaceService interfaceService;
 
     @Override
     public List<String> choices() {
-        VplsConfigService vplsConfigService = get(VplsConfigService.class);
-        List<String> argumentList =
-                Lists.newArrayList(getArgumentList().getArguments());
-        String argOne = argumentList.get(1);
+        if (vpls == null) {
+            vpls = get(Vpls.class);
+        }
+        ArgumentCompleter.ArgumentList argumentList = getArgumentList();
+        if (argumentList == null) {
+            return Collections.emptyList();
+        }
+        List<String> argList = Lists.newArrayList(argumentList.getArguments());
+        String argOne = argList.get(1);
         VplsCommandEnum vplsCommandEnum = VplsCommandEnum.enumFromString(argOne);
         if (vplsCommandEnum != null) {
             switch (vplsCommandEnum) {
                 case ADD_IFACE:
-                    return availableIfaces(vplsConfigService);
+                    return availableIfaces();
                 case SET_ENCAP:
                     return encap();
                 case REMOVE_IFACE:
-                    return vplsIfaces(vplsConfigService);
+                    return vplsIfaces();
                 default:
                     return Collections.emptyList();
             }
@@ -64,21 +73,27 @@
      *
      * @return the list of interfaces not yet assigned to any VPLS
      */
-    private List<String> availableIfaces(VplsConfigService vplsConfigService) {
-        List<String> ifacesAvailable = Lists.newArrayList();
-        Set<Interface> allIfaces = Sets.newHashSet(vplsConfigService.allIfaces());
-        Set<Interface> usedIfaces = Sets.newHashSet(vplsConfigService.ifaces());
+    private List<String> availableIfaces() {
+        if (interfaceService == null) {
+            interfaceService = get(InterfaceService.class);
+        }
 
-        allIfaces.removeAll(usedIfaces);
-        allIfaces.forEach(iface -> ifacesAvailable.add(iface.name()));
+        Set<Interface> allIfaces = interfaceService.getInterfaces();
+        Set<Interface> usedIfaces = vpls.getAllVpls().stream()
+                .map(VplsData::interfaces)
+                .flatMap(Collection::stream)
+                .collect(Collectors.toSet());
 
-        return ifacesAvailable;
+        return allIfaces.stream()
+                .filter(iface -> !usedIfaces.contains(iface))
+                .map(Interface::name)
+                .collect(Collectors.toList());
     }
 
     /**
      * Returns the list of supported encapsulation types.
      *
-     * @return the list of supported encapsualtion types
+     * @return the list of supported encapsulation types
      */
     private List<String> encap() {
         return Arrays.stream(EncapsulationType.values())
@@ -91,15 +106,12 @@
      *
      * @return the list of interfaces associated to a VPLS
      */
-    private List<String> vplsIfaces(VplsConfigService vplsConfigService) {
+    private List<String> vplsIfaces() {
         ArgumentCompleter.ArgumentList list = getArgumentList();
         String vplsName = list.getArguments()[2];
-
-        List<String> vplsIfaces = Lists.newArrayList();
-
-        Set<Interface> connectPoints = vplsConfigService.ifaces(vplsName);
-        connectPoints.forEach(iface -> vplsIfaces.add(iface.name()));
-
-        return vplsIfaces;
+        VplsData vplsData = vpls.getVpls(vplsName);
+        return vplsData.interfaces().stream()
+                .map(Interface::name)
+                .collect(Collectors.toList());
     }
 }
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsAppConfig.java b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsAppConfig.java
index 66f7882..775d56b 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsAppConfig.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsAppConfig.java
@@ -35,6 +35,9 @@
     private static final String INTERFACE = "interfaces";
     private static final String ENCAPSULATION = "encapsulation";
 
+    // Record update time when VPLS distribute store update it
+    private static final String UPDATE_TIME = "lastUpdateTime";
+
     /**
      * Returns a set of configured VPLSs.
      *
@@ -42,9 +45,7 @@
      */
     public Set<VplsConfig> vplss() {
         Set<VplsConfig> vplss = Sets.newHashSet();
-
         JsonNode vplsNode = object.get(VPLS);
-
         if (vplsNode == null) {
             return vplss;
         }
@@ -67,7 +68,6 @@
                                      ifaces,
                                      EncapsulationType.enumFromString(encap)));
         });
-
         return vplss;
     }
 
@@ -215,4 +215,37 @@
     private ArrayNode initVplsConfiguration() {
         return object.putArray(VPLS);
     }
+
+    /**
+     * Sets the last time of update for the VPLS information in the store.
+     *
+     * @param timestamp the update time
+     */
+    public void updateTime(long timestamp) {
+        object.put(UPDATE_TIME, timestamp);
+    }
+
+    /**
+     * Retrieves the last time of update for the VPLS information in the store.
+     *
+     * @return update time, -1 if there is no update time in the config
+     */
+    public long updateTime() {
+        if (object.get(UPDATE_TIME) != null) {
+            return object.get(UPDATE_TIME).asLong();
+        } else {
+            // No update time
+            return -1L;
+        }
+    }
+
+    /**
+     * Clears all VPLS configurations.
+     */
+    public void clearVplsConfig() {
+        if (object.get(VPLS) != null) {
+            object.remove(VPLS);
+        }
+        initVplsConfiguration();
+    }
 }
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfigManager.java b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfigManager.java
new file mode 100644
index 0000000..71b14ad
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfigManager.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vpls.config;
+
+import com.google.common.collect.Sets;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.cluster.NodeId;
+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.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.config.basics.SubjectFactories;
+import org.onosproject.vpls.VplsManager;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.api.Vpls;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import static org.onlab.util.Tools.groupedThreads;
+
+/**
+ * Component for the management of the VPLS configuration.
+ */
+@Component(immediate = true)
+public class VplsConfigManager {
+    private static final Class<VplsAppConfig> CONFIG_CLASS = VplsAppConfig.class;
+    private static final String NET_CONF_EVENT = "Received NetworkConfigEvent {}";
+    private static final String CONFIG_NULL = "VPLS configuration not defined";
+    private static final int INITIAL_RELOAD_CONFIG_DELAY = 0;
+    private static final int INITIAL_RELOAD_CONFIG_PERIOD = 1000;
+    private static final int NUM_THREADS = 1;
+    private static final String VPLS = "vpls";
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private final NetworkConfigListener configListener =
+            new InternalNetworkConfigListener();
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService configService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry registry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected Vpls vpls;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LeadershipService leadershipService;
+
+    private ScheduledExecutorService reloadExecutor =
+            Executors.newScheduledThreadPool(NUM_THREADS,
+                                             groupedThreads("onos/apps/vpls",
+                                                            "config-reloader-%d",
+                                                            log)
+            );
+
+    private ConfigFactory<ApplicationId, VplsAppConfig> vplsConfigFactory =
+            new ConfigFactory<ApplicationId, VplsAppConfig>(
+                    SubjectFactories.APP_SUBJECT_FACTORY, VplsAppConfig.class, VPLS) {
+                @Override
+                public VplsAppConfig createConfig() {
+                    return new VplsAppConfig();
+                }
+            };
+
+    protected ApplicationId appId;
+
+    @Activate
+    void activate() {
+        appId = coreService.registerApplication(VplsManager.VPLS_APP);
+        configService.addListener(configListener);
+
+        // Load config when VPLS service started and there is a leader for VPLS;
+        // otherwise, try again after a period.
+        reloadExecutor.scheduleAtFixedRate(() -> {
+            NodeId vplsLeaderNode = leadershipService.getLeader(appId.name());
+            if (vpls == null || vplsLeaderNode == null) {
+                return;
+            }
+            reloadConfiguration();
+            reloadExecutor.shutdown();
+        }, INITIAL_RELOAD_CONFIG_DELAY, INITIAL_RELOAD_CONFIG_PERIOD, TimeUnit.MILLISECONDS);
+        registry.registerConfigFactory(vplsConfigFactory);
+    }
+
+    @Deactivate
+    void deactivate() {
+        configService.removeListener(configListener);
+        registry.unregisterConfigFactory(vplsConfigFactory);
+    }
+
+    /**
+     * Retrieves the VPLS configuration from network configuration.
+     * Checks difference between new configuration and old configuration.
+     */
+    private synchronized void reloadConfiguration() {
+        VplsAppConfig vplsAppConfig = configService.getConfig(appId, VplsAppConfig.class);
+
+        if (vplsAppConfig == null) {
+            log.warn(CONFIG_NULL);
+
+            // If the config is null, removes all VPLS.
+            vpls.removeAllVpls();
+            return;
+        }
+
+        // If there exists a update time in the configuration; it means the
+        // configuration was pushed by VPLS store; ignore this configuration.
+        long updateTime = vplsAppConfig.updateTime();
+        if (updateTime != -1L) {
+            return;
+        }
+
+        Collection<VplsData> oldVplses = vpls.getAllVpls();
+        Collection<VplsData> newVplses;
+
+        // Generates collection of new VPLSs
+        newVplses = vplsAppConfig.vplss().stream()
+                .map(vplsConfig -> {
+                    Set<Interface> interfaces = vplsConfig.ifaces().stream()
+                            .map(this::getInterfaceByName)
+                            .filter(Objects::nonNull)
+                            .collect(Collectors.toSet());
+                    VplsData vplsData = VplsData.of(vplsConfig.name(), vplsConfig.encap());
+                    vplsData.addInterfaces(interfaces);
+                    return vplsData;
+                }).collect(Collectors.toSet());
+
+        if (newVplses.containsAll(oldVplses) && oldVplses.containsAll(newVplses)) {
+            // no update, ignore
+            return;
+        }
+
+        // To add or update
+        newVplses.forEach(newVplsData -> {
+            boolean vplsExists = false;
+            for (VplsData oldVplsData : oldVplses) {
+                if (oldVplsData.name().equals(newVplsData.name())) {
+                    vplsExists = true;
+
+                    // VPLS exists; but need to be updated.
+                    if (!oldVplsData.equals(newVplsData)) {
+                        // Update VPLS
+                        Set<Interface> newInterfaces = newVplsData.interfaces();
+                        Set<Interface> oldInterfaces = oldVplsData.interfaces();
+
+                        Set<Interface> ifaceToAdd = newInterfaces.stream()
+                                .filter(iface -> !oldInterfaces.contains(iface))
+                                .collect(Collectors.toSet());
+
+                        Set<Interface> ifaceToRem = oldInterfaces.stream()
+                                .filter(iface -> !newInterfaces.contains(iface))
+                                .collect(Collectors.toSet());
+
+                        vpls.addInterfaces(oldVplsData, ifaceToAdd);
+                        vpls.removeInterfaces(oldVplsData, ifaceToRem);
+                        vpls.setEncapsulationType(oldVplsData, newVplsData.encapsulationType());
+                    }
+                }
+            }
+            // VPLS not exist; add new VPLS
+            if (!vplsExists) {
+                vpls.createVpls(newVplsData.name(), newVplsData.encapsulationType());
+                vpls.addInterfaces(newVplsData, newVplsData.interfaces());
+            }
+        });
+
+        // VPLS not exists in old VPLS configuration; remove it.
+        Set<VplsData> vplsToRemove = Sets.newHashSet();
+        oldVplses.forEach(oldVpls -> {
+            Set<String> newVplsNames = newVplses.stream()
+                    .map(VplsData::name)
+                    .collect(Collectors.toSet());
+
+            if (!newVplsNames.contains(oldVpls.name())) {
+                // To avoid ConcurrentModificationException; do remove after this
+                // iteration.
+                vplsToRemove.add(oldVpls);
+            }
+        });
+        vplsToRemove.forEach(vpls::removeVpls);
+    }
+
+    /**
+     * Gets network interface by a given name.
+     *
+     * @param interfaceName the interface name
+     * @return the network interface if there exist with the given name; null
+     * otherwise
+     */
+    private Interface getInterfaceByName(String interfaceName) {
+        return interfaceService.getInterfaces().stream()
+                .filter(iface -> iface.name().equals(interfaceName))
+                .findFirst()
+                .orElse(null);
+    }
+
+    /**
+     * Listener for VPLS configuration events.
+     * Reloads VPLS configuration when configuration added or updated.
+     * Removes all VPLS when configuration removed or unregistered.
+     */
+    private class InternalNetworkConfigListener implements NetworkConfigListener {
+        @Override
+        public void event(NetworkConfigEvent event) {
+            if (event.configClass() == CONFIG_CLASS) {
+                log.debug(NET_CONF_EVENT, event.configClass());
+                switch (event.type()) {
+                    case CONFIG_ADDED:
+                    case CONFIG_UPDATED:
+                        reloadConfiguration();
+                        break;
+                    case CONFIG_REMOVED:
+                    case CONFIG_UNREGISTERED:
+                        vpls.removeAllVpls();
+                    default:
+                        break;
+                }
+            }
+        }
+    }
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfigService.java b/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfigService.java
deleted file mode 100644
index 2d2a576..0000000
--- a/apps/vpls/src/main/java/org/onosproject/vpls/config/VplsConfigService.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.vpls.config;
-
-import com.google.common.collect.SetMultimap;
-import org.onlab.packet.VlanId;
-import org.onosproject.incubator.net.intf.Interface;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.EncapsulationType;
-
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Provides information about the VPLS configuration.
- */
-public interface VplsConfigService {
-    Class<VplsAppConfig> CONFIG_CLASS = VplsAppConfig.class;
-
-    /**
-     * Adds a VPLS to the configuration.
-     *
-     * @param vplsName the name of the VPLS
-     * @param ifaces the interfaces associated with the VPLS
-     * @param encap the encapsulation type
-     */
-    void addVpls(String vplsName, Set<String> ifaces, String encap);
-
-    /**
-     * Removes a VPLS from the configuration.
-     *
-     * @param vplsName the name of the VPLS to be removed
-     */
-    void removeVpls(String vplsName);
-
-    /**
-     * Adds a network interface to a VPLS.
-     *
-     * @param vplsName the name of the VPLS
-     * @param iface the network interface to be added to the VPLS
-     */
-    void addIface(String vplsName, String iface);
-
-    /**
-     * Sets an encapsulation parameter for a VPLS.
-     *
-     * @param vplsName the name of the VPLS
-     * @param encap the encapsulation used (i.e. MPLS or VLAN) or
-     */
-    void setEncap(String vplsName, String encap);
-
-    /**
-     * Returns the encapsulation type in use for a given VPLS.
-     *
-     * @param vplsName the name of the VPLS
-     * @return the encapsulation type in use, if any
-     */
-    EncapsulationType encap(String vplsName);
-
-    /**
-     * Removes a network interface from a VPLS.
-     *
-     * @param iface the network interface to be removed from the VPLS
-     */
-    void removeIface(String iface);
-
-    /**
-     * Cleans up the VPLS configuration. Removes all VPLSs.
-     */
-    void cleanVplsConfig();
-
-    /**
-     * Retrieves the VPLS names modified from CLI.
-     *
-     * @return the VPLS names modified from CLI
-     */
-    Set<String> vplsAffectedByApi();
-    // TODO Remove this function after the intent framework race condition has been fixed
-
-    /**
-     * Retrieves the interfaces without IP configured, so compatible with VPLS,
-     * from the interface service.
-     *
-     * @return the set of interfaces configured, compatible with VPLS
-     */
-    Set<Interface> allIfaces();
-
-    /**
-     * Retrieves the interfaces associated to a VPLS.
-     *
-     * @return the set of interfaces associated to a VPLS
-     */
-    Set<Interface> ifaces();
-
-    /**
-     * Retrieves the interfaces associated to the VPLS specified.
-     *
-     * @param vplsName the name of the VPLS
-     * @return the set of interfaces associated to the VPLS specified
-     */
-    Set<Interface> ifaces(String vplsName);
-
-    /**
-     * Retrieves all VPLS names.
-     *
-     * @return a set of VPLS names
-     */
-    Set<String> vplsNames();
-
-    /**
-     * Retrieves all VPLS names from the old config.
-     *
-     * @return a set of VPLS names
-     */
-    Set<String> vplsNamesOld();
-    // TODO Removes this function after the race condition gets fixed in IF
-
-    /**
-     * Returns the VPLS names and associated interfaces from the configuration.
-     *
-     * @return a map of VPLS names and associated interfaces
-     */
-    SetMultimap<String, Interface> ifacesByVplsName();
-
-    /**
-     * Returns the list of interfaces grouped by VPLS name, given a VLAN Id and
-     * a connect point.
-     *
-     * @param vlan the VLAN Id
-     * @param connectPoint the connect point
-     * @return a map of VPLS names and associated interfaces; null otherwise
-     */
-    SetMultimap<String, Interface> ifacesByVplsName(VlanId vlan,
-                                                    ConnectPoint connectPoint);
-
-    /**
-     * Returns the VPLS names and associated encapsulation type.
-     *
-     * @return a map of VPLS names and associated encapsulation type
-     */
-    Map<String, EncapsulationType> encapByVplsName();
-}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/VplsConfigImpl.java b/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/VplsConfigImpl.java
deleted file mode 100644
index 36da63c..0000000
--- a/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/VplsConfigImpl.java
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.vpls.config.impl;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.SetMultimap;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.Service;
-import org.onlab.packet.VlanId;
-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.EncapsulationType;
-import org.onosproject.net.config.ConfigFactory;
-import org.onosproject.net.config.NetworkConfigEvent;
-import org.onosproject.net.config.NetworkConfigListener;
-import org.onosproject.net.config.NetworkConfigRegistry;
-import org.onosproject.net.config.NetworkConfigService;
-import org.onosproject.net.config.basics.SubjectFactories;
-import org.onosproject.vpls.config.VplsAppConfig;
-import org.onosproject.vpls.config.VplsConfig;
-import org.onosproject.vpls.config.VplsConfigService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Implementation of VPLSConfigurationService which reads VPLS configuration
- * from the network configuration service.
- */
-@Component(immediate = true)
-@Service
-public class VplsConfigImpl implements VplsConfigService {
-    private static final String VPLS_APP = "org.onosproject.vpls";
-    private static final String VPLS = "vpls";
-    private static final String EMPTY = "";
-    private static final String CONFIG_NULL = "VPLS configuration not defined";
-    private static final String APP_ID_NULL = "VPLS application ID is null";
-    private static final String CONFIG_CHANGED = "VPLS configuration changed: {}";
-    private static final String CHECK_CONFIG =
-            "Checking the interface configuration";
-    private static final String NET_CONF_EVENT =
-            "Received NetworkConfigEvent {}";
-
-    private final Logger log = LoggerFactory.getLogger(getClass());
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected NetworkConfigRegistry registry;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected CoreService coreService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected InterfaceService interfaceService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected NetworkConfigService configService;
-
-    private final Set<String> vplsAffectedByApi = new HashSet<>();
-
-    private VplsAppConfig vplsAppConfig = null;
-
-    private SetMultimap<String, String> ifacesOfVpls = HashMultimap.create();
-    private SetMultimap<String, String> oldIfacesOfVpls = HashMultimap.create();
-    private SetMultimap<String, Interface> vplsIfaces = HashMultimap.create();
-
-    private Map<String, EncapsulationType> vplsEncaps = Maps.newHashMap();
-
-    private final InternalNetworkConfigListener configListener =
-            new InternalNetworkConfigListener();
-
-    private ConfigFactory<ApplicationId, VplsAppConfig> vplsConfigFactory =
-            new ConfigFactory<ApplicationId, VplsAppConfig>(
-                    SubjectFactories.APP_SUBJECT_FACTORY, VplsAppConfig.class, VPLS) {
-                @Override
-                public VplsAppConfig createConfig() {
-                    return new VplsAppConfig();
-                }
-            };
-
-    private ApplicationId vplsAppId;
-
-    @Activate
-    protected void active() {
-        configService.addListener(configListener);
-        registry.registerConfigFactory(vplsConfigFactory);
-        loadConfiguration();
-        log.info("Started");
-    }
-
-    @Deactivate
-    protected  void deactive() {
-        registry.unregisterConfigFactory(vplsConfigFactory);
-        configService.removeListener(configListener);
-        log.info("Stopped");
-    }
-
-    @Override
-    public void addVpls(String vplsName, Set<String> ifaces, String encap) {
-        EncapsulationType encapType = EncapsulationType.enumFromString(encap);
-
-        if (ifacesOfVpls.containsKey(vplsName)) {
-            if (ifaces.isEmpty()) {
-                return;
-            }
-            ifaces.forEach(iface -> vplsAppConfig.addIface(vplsName, iface));
-            vplsAppConfig.setEncap(vplsName, encapType);
-        } else {
-            vplsAppConfig.addVpls(new VplsConfig(vplsName, ifaces, encapType));
-        }
-
-        vplsAffectedByApi.add(vplsName);
-        applyConfig(vplsAppConfig);
-    }
-
-    @Override
-    public void removeVpls(String vplsName) {
-        if (ifacesOfVpls.containsKey(vplsName)) {
-            vplsAppConfig.removeVpls(vplsName);
-            vplsAffectedByApi.add(vplsName);
-            applyConfig(vplsAppConfig);
-        }
-    }
-
-    @Override
-    public void addIface(String vplsName, String iface) {
-        if (ifacesOfVpls.containsKey(vplsName)) {
-            vplsAppConfig.addIface(vplsName, iface);
-            vplsAffectedByApi.add(vplsName);
-            applyConfig(vplsAppConfig);
-        }
-    }
-
-    @Override
-    public void setEncap(String vplsName, String encap) {
-        EncapsulationType encapType = EncapsulationType.enumFromString(encap);
-
-        if (ifacesOfVpls.containsKey(vplsName)) {
-            vplsAppConfig.setEncap(vplsName, encapType);
-            vplsAffectedByApi.add(vplsName);
-            applyConfig(vplsAppConfig);
-        }
-    }
-
-    @Override
-    public void removeIface(String iface) {
-        if (ifacesOfVpls.containsValue(iface)) {
-            VplsConfig vpls = vplsAppConfig.vplsFromIface(iface);
-            vplsAppConfig.removeIface(vpls, iface);
-            vplsAffectedByApi.add(vpls.name());
-            applyConfig(vplsAppConfig);
-        }
-    }
-
-    @Override
-    public void cleanVplsConfig() {
-        ifacesOfVpls.entries().forEach(e -> {
-            vplsAppConfig.removeVpls(e.getKey());
-            vplsAffectedByApi.add(e.getKey());
-        });
-        applyConfig(vplsAppConfig);
-    }
-
-    @Override
-    public EncapsulationType encap(String vplsName) {
-        EncapsulationType encap = null;
-        if (vplsEncaps.containsKey(vplsName)) {
-            encap = vplsEncaps.get(vplsName);
-        }
-
-        return encap;
-    }
-
-    @Override
-    public Set<String> vplsAffectedByApi() {
-        Set<String> vplsNames = ImmutableSet.copyOf(vplsAffectedByApi);
-        vplsAffectedByApi.clear();
-        return vplsNames;
-    }
-
-    @Override
-    public Set<Interface> allIfaces() {
-        Set<Interface> interfaces = new HashSet<>();
-        interfaceService.getInterfaces().stream()
-                .filter(iface -> iface.ipAddressesList() == null ||
-                        iface.ipAddressesList().isEmpty())
-                .forEach(interfaces::add);
-        return interfaces;
-    }
-
-    @Override
-    public Set<Interface> ifaces() {
-        Set<Interface> interfaces = new HashSet<>();
-        vplsIfaces.values().forEach(interfaces::add);
-        return interfaces;
-    }
-
-    @Override
-    public Set<Interface> ifaces(String vplsName) {
-        Set<Interface> vplsInterfaces = new HashSet<>();
-        vplsIfaces.get(vplsName).forEach(vplsInterfaces::add);
-        return vplsInterfaces;
-    }
-
-    @Override
-    public Set<String> vplsNames() {
-        return ifacesOfVpls.keySet();
-    }
-
-    @Override
-    public Set<String> vplsNamesOld() {
-        return oldIfacesOfVpls.keySet();
-    }
-
-    @Override
-    public SetMultimap<String, Interface> ifacesByVplsName() {
-        return ImmutableSetMultimap.copyOf(vplsIfaces);
-    }
-
-    @Override
-    public SetMultimap<String, Interface> ifacesByVplsName(VlanId vlan,
-                                                           ConnectPoint connectPoint) {
-        String vplsName =
-                vplsIfaces.entries().stream()
-                        .filter(e -> e.getValue().connectPoint().equals(connectPoint))
-                        .filter(e -> e.getValue().vlan().equals(vlan))
-                        .map(Map.Entry::getKey)
-                        .findFirst()
-                        .orElse(null);
-        SetMultimap<String, Interface> result = HashMultimap.create();
-        if (vplsName != null && vplsIfaces.containsKey(vplsName)) {
-            vplsIfaces.get(vplsName)
-                    .forEach(intf -> result.put(vplsName, intf));
-            return result;
-        }
-        return null;
-    }
-
-    @Override
-    public Map<String, EncapsulationType> encapByVplsName() {
-        return ImmutableMap.copyOf(vplsEncaps);
-    }
-
-    /**
-     * Retrieves the VPLS configuration from network configuration.
-     */
-    private void loadConfiguration() {
-        loadAppId();
-
-        vplsAppConfig = configService.getConfig(vplsAppId, VplsAppConfig.class);
-
-        if (vplsAppConfig == null) {
-            log.warn(CONFIG_NULL);
-            vplsAppConfig = configService.addConfig(vplsAppId, VplsAppConfig.class);
-        }
-
-        oldIfacesOfVpls = ifacesOfVpls;
-        ifacesOfVpls = getConfigInterfaces();
-        vplsIfaces = getConfigCPointsFromIfaces();
-        vplsEncaps = getConfigEncap();
-
-        log.debug(CONFIG_CHANGED, ifacesOfVpls);
-    }
-
-    /**
-     * Retrieves the application identifier from core service.
-     */
-    private void loadAppId() {
-        vplsAppId = coreService.getAppId(VPLS_APP);
-        if (vplsAppId == null) {
-            log.warn(APP_ID_NULL);
-        }
-    }
-
-    /**
-     * Applies a given configuration to the VPLS application.
-     */
-    private void applyConfig(VplsAppConfig vplsAppConfig) {
-        loadAppId();
-        configService.applyConfig(vplsAppId, VplsAppConfig.class, vplsAppConfig.node());
-    }
-
-    /**
-     * Retrieves the VPLS names and related encapsulation types from the
-     * configuration.
-     *
-     * @return a map of VPLS names and associated encapsulation types
-     */
-    private Map<String, EncapsulationType> getConfigEncap() {
-        Map<String, EncapsulationType> configEncap = new HashMap<>();
-
-        vplsAppConfig.vplss().forEach(vpls -> {
-            configEncap.put(vpls.name(), vpls.encap());
-        });
-
-        return configEncap;
-    }
-
-    /**
-     * Retrieves the VPLS names and related interfaces names from the configuration.
-     *
-     * @return a map of VPLS names and related interface names
-     */
-    private SetMultimap<String, String> getConfigInterfaces() {
-        SetMultimap<String, String> confIntfByVpls =
-                HashMultimap.create();
-
-        vplsAppConfig.vplss().forEach(vpls -> {
-            if (vpls.ifaces().isEmpty()) {
-                confIntfByVpls.put(vpls.name(), EMPTY);
-            } else {
-                vpls.ifaces().forEach(iface -> confIntfByVpls.put(vpls.name(), iface));
-            }
-        });
-
-        return confIntfByVpls;
-    }
-
-    /**
-     * Retrieves the VPLS names and related interfaces from the configuration.
-     *
-     * @return a map of VPLS names and related interfaces
-     */
-    private SetMultimap<String, Interface> getConfigCPointsFromIfaces() {
-        log.debug(CHECK_CONFIG);
-
-        SetMultimap<String, Interface> confCPointsByIntf =
-                HashMultimap.create();
-
-        ifacesOfVpls.entries().forEach(vpls -> {
-            interfaceService.getInterfaces()
-                    .stream()
-                    .filter(intf -> intf.ipAddressesList().isEmpty())
-                    .filter(intf -> intf.name().equals(vpls.getValue()))
-                    .forEach(intf -> confCPointsByIntf.put(vpls.getKey(), intf));
-        });
-
-        return confCPointsByIntf;
-    }
-
-    /**
-     * Listener for VPLS configuration events.
-     */
-    private class InternalNetworkConfigListener implements NetworkConfigListener {
-        @Override
-        public void event(NetworkConfigEvent event) {
-            if (event.configClass() == VplsConfigService.CONFIG_CLASS) {
-                log.debug(NET_CONF_EVENT, event.configClass());
-                switch (event.type()) {
-                    case CONFIG_ADDED:
-                    case CONFIG_UPDATED:
-                    case CONFIG_REMOVED:
-                        loadConfiguration();
-                        break;
-                    default:
-                        break;
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/intent/VplsIntentUtility.java b/apps/vpls/src/main/java/org/onosproject/vpls/intent/VplsIntentUtility.java
new file mode 100644
index 0000000..a81a72f
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/intent/VplsIntentUtility.java
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vpls.intent;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+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.net.ConnectPoint;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.Host;
+import org.onosproject.net.ResourceGroup;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.intent.ConnectivityIntent;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.net.intent.SinglePointToMultiPointIntent;
+import org.onosproject.net.intent.constraint.EncapsulationConstraint;
+import org.onosproject.net.intent.constraint.PartialFailureConstraint;
+import org.onosproject.vpls.api.VplsData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.util.Objects.*;
+import static org.onosproject.net.EncapsulationType.*;
+
+/**
+ * Intent utilities for VPLS.
+ */
+public final class VplsIntentUtility {
+    private static final String SP2MP =
+            "Building sp2mp intent from {}";
+    private static final String MP2SP =
+            "Building mp2sp intent to {}";
+
+    private static final Logger log = LoggerFactory.getLogger(
+            VplsIntentUtility.class);
+
+    private static final int PRIORITY_OFFSET = 1000;
+    private static final int PRIORITY_UNI = 200;
+    private static final int PRIORITY_BRC = 100;
+
+    public static final String PREFIX_BROADCAST = "brc";
+    public static final String PREFIX_UNICAST = "uni";
+    private static final String SEPARATOR = "-";
+
+    public static final ImmutableList<Constraint> PARTIAL_FAILURE_CONSTRAINT =
+            ImmutableList.of(new PartialFailureConstraint());
+
+    private VplsIntentUtility() {
+        // Utility classes should not have a public or default constructor.
+    }
+
+    /**
+     * Builds broadcast Intents for a VPLS.
+     *
+     * @param vplsData the VPLS
+     * @param appId the application id for Intents
+     * @return broadcast Intents for the VPLS
+     */
+    public static Set<Intent> buildBrcIntents(VplsData vplsData, ApplicationId appId) {
+        Set<Interface> interfaces = vplsData.interfaces();
+
+        // At least two or more network interfaces to build broadcast Intents
+        if (interfaces.size() < 2) {
+            return ImmutableSet.of();
+        }
+        Set<Intent> brcIntents = Sets.newHashSet();
+        ResourceGroup resourceGroup = ResourceGroup.of(vplsData.name());
+
+        // Generates broadcast Intents from any network interface to other
+        // network interface from the VPLS.
+        interfaces.forEach(src -> {
+            FilteredConnectPoint srcFcp = VplsIntentUtility.buildFilteredConnectedPoint(src);
+            Set<FilteredConnectPoint> dstFcps =
+                    interfaces.stream()
+                            .filter(iface -> !iface.equals(src))
+                            .map(VplsIntentUtility::buildFilteredConnectedPoint)
+                            .collect(Collectors.toSet());
+            Key key = VplsIntentUtility.buildKey(PREFIX_BROADCAST,
+                                                 srcFcp.connectPoint(),
+                                                 vplsData.name(),
+                                                 MacAddress.BROADCAST,
+                                                 appId);
+            Intent brcIntent = buildBrcIntent(key,
+                                              appId,
+                                              srcFcp,
+                                              dstFcps,
+                                              vplsData.encapsulationType(),
+                                              resourceGroup);
+
+            brcIntents.add(brcIntent);
+        });
+        return brcIntents;
+    }
+
+    /**
+     * Builds a broadcast intent.
+     *
+     * @param key key to identify the intent
+     * @param appId application ID for this Intent
+     * @param src the source connect point
+     * @param dsts the destination connect points
+     * @param encap the encapsulation type
+     * @param resourceGroup resource group for this Intent
+     * @return the generated single-point to multi-point intent
+     */
+    protected static SinglePointToMultiPointIntent buildBrcIntent(Key key,
+                                                                  ApplicationId appId,
+                                                                  FilteredConnectPoint src,
+                                                                  Set<FilteredConnectPoint> dsts,
+                                                                  EncapsulationType encap,
+                                                                  ResourceGroup resourceGroup) {
+        log.debug("Building broadcast intent {} for source {}", SP2MP, src);
+
+        SinglePointToMultiPointIntent.Builder intentBuilder;
+
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthDst(MacAddress.BROADCAST)
+                .build();
+
+        intentBuilder = SinglePointToMultiPointIntent.builder()
+                .appId(appId)
+                .key(key)
+                .selector(selector)
+                .filteredIngressPoint(src)
+                .filteredEgressPoints(dsts)
+                .constraints(PARTIAL_FAILURE_CONSTRAINT)
+                .priority(PRIORITY_OFFSET + PRIORITY_BRC)
+                .resourceGroup(resourceGroup);
+
+        setEncap(intentBuilder, PARTIAL_FAILURE_CONSTRAINT, encap);
+
+        return intentBuilder.build();
+    }
+
+    /**
+     * Builds unicast Intents for a VPLS.
+     *
+     * @param vplsData the VPLS
+     * @param hosts the hosts of the VPLS
+     * @param appId application ID for Intents
+     * @return unicast Intents for the VPLS
+     */
+    public static Set<Intent> buildUniIntents(VplsData vplsData, Set<Host> hosts, ApplicationId appId) {
+        Set<Interface> interfaces = vplsData.interfaces();
+        if (interfaces.size() < 2) {
+            return ImmutableSet.of();
+        }
+        Set<Intent> uniIntents = Sets.newHashSet();
+        ResourceGroup resourceGroup = ResourceGroup.of(vplsData.name());
+        hosts.forEach(host -> {
+            FilteredConnectPoint hostFcp = buildFilteredConnectedPoint(host);
+            Set<FilteredConnectPoint> srcFcps =
+                    interfaces.stream()
+                            .map(VplsIntentUtility::buildFilteredConnectedPoint)
+                            .filter(fcp -> !fcp.equals(hostFcp))
+                            .collect(Collectors.toSet());
+            Key key = buildKey(PREFIX_UNICAST,
+                               hostFcp.connectPoint(),
+                               vplsData.name(),
+                               host.mac(),
+                               appId);
+            Intent uniIntent = buildUniIntent(key,
+                                              appId,
+                                              srcFcps,
+                                              hostFcp,
+                                              host,
+                                              vplsData.encapsulationType(),
+                                              resourceGroup);
+            uniIntents.add(uniIntent);
+        });
+
+        return uniIntents;
+    }
+
+    /**
+     * Builds a unicast intent.
+     *
+     * @param key key to identify the intent
+     * @param appId application ID for this Intent
+     * @param srcs the source Connect Points
+     * @param dst the destination Connect Point
+     * @param host destination Host
+     * @param encap the encapsulation type
+     * @param resourceGroup resource group for this Intent
+     * @return the generated multi-point to single-point intent
+     */
+    protected static MultiPointToSinglePointIntent buildUniIntent(Key key,
+                                                                  ApplicationId appId,
+                                                                  Set<FilteredConnectPoint> srcs,
+                                                                  FilteredConnectPoint dst,
+                                                                  Host host,
+                                                                  EncapsulationType encap,
+                                                                  ResourceGroup resourceGroup) {
+        log.debug("Building unicast intent {} for destination {}", MP2SP, dst);
+
+        MultiPointToSinglePointIntent.Builder intentBuilder;
+
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthDst(host.mac())
+                .build();
+
+        intentBuilder = MultiPointToSinglePointIntent.builder()
+                .appId(appId)
+                .key(key)
+                .selector(selector)
+                .filteredIngressPoints(srcs)
+                .filteredEgressPoint(dst)
+                .constraints(PARTIAL_FAILURE_CONSTRAINT)
+                .priority(PRIORITY_OFFSET + PRIORITY_UNI)
+                .resourceGroup(resourceGroup);
+
+        setEncap(intentBuilder, PARTIAL_FAILURE_CONSTRAINT, encap);
+
+        return intentBuilder.build();
+    }
+
+    /**
+     * Builds an intent key either for single-point to multi-point or
+     * multi-point to single-point intents, based on a prefix that defines
+     * the type of intent, the single connect point representing the single
+     * source or destination for that intent, the name of the VPLS the intent
+     * belongs to, and the destination host MAC address the intent reaches.
+     *
+     * @param prefix the key prefix
+     * @param cPoint the connect point identifying the source/destination
+     * @param vplsName the name of the VPLS
+     * @param hostMac the source/destination MAC address
+     * @param appId application ID for the key
+     * @return the key to identify the intent
+     */
+    protected static Key buildKey(String prefix,
+                                  ConnectPoint cPoint,
+                                  String vplsName,
+                                  MacAddress hostMac,
+                                  ApplicationId appId) {
+        String keyString = vplsName +
+                SEPARATOR +
+                prefix +
+                SEPARATOR +
+                cPoint.deviceId() +
+                SEPARATOR +
+                cPoint.port() +
+                SEPARATOR +
+                hostMac;
+
+        return Key.of(keyString, appId);
+    }
+
+
+    /**
+     * Sets one or more encapsulation constraints on the intent builder given.
+     *
+     * @param builder the intent builder
+     * @param constraints the existing intent constraints
+     * @param encap the encapsulation type to be set
+     */
+    public static void setEncap(ConnectivityIntent.Builder builder,
+                                List<Constraint> constraints,
+                                EncapsulationType encap) {
+        // Constraints might be an immutable list, so a new modifiable list
+        // is created
+        List<Constraint> newConstraints = new ArrayList<>(constraints);
+
+        // Remove any encapsulation constraint if already in the list
+        constraints.stream()
+                .filter(c -> c instanceof EncapsulationConstraint)
+                .forEach(newConstraints::remove);
+
+        // if the new encapsulation is different from NONE, a new encapsulation
+        // constraint should be added to the list
+        if (!encap.equals(NONE)) {
+            newConstraints.add(new EncapsulationConstraint(encap));
+        }
+
+        // Submit new constraint list as immutable list
+        builder.constraints(ImmutableList.copyOf(newConstraints));
+    }
+
+    /**
+     * Builds filtered connected point by a given network interface.
+     *
+     * @param iface the network interface
+     * @return the filtered connected point of a given network interface
+     */
+    protected static FilteredConnectPoint buildFilteredConnectedPoint(Interface iface) {
+        Objects.requireNonNull(iface);
+        TrafficSelector.Builder trafficSelector = DefaultTrafficSelector.builder();
+
+        if (iface.vlan() != null && !iface.vlan().equals(VlanId.NONE)) {
+            trafficSelector.matchVlanId(iface.vlan());
+        }
+
+        return new FilteredConnectPoint(iface.connectPoint(), trafficSelector.build());
+    }
+
+    /**
+     * Builds filtered connected point by a given host.
+     *
+     * @param host the host
+     * @return the filtered connected point of the given host
+     */
+    protected static FilteredConnectPoint buildFilteredConnectedPoint(Host host) {
+        requireNonNull(host);
+        TrafficSelector.Builder trafficSelector = DefaultTrafficSelector.builder();
+
+        if (host.vlan() != null && !host.vlan().equals(VlanId.NONE)) {
+            trafficSelector.matchVlanId(host.vlan());
+        }
+        return new FilteredConnectPoint(host.location(), trafficSelector.build());
+    }
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java b/apps/vpls/src/main/java/org/onosproject/vpls/intent/package-info.java
similarity index 79%
copy from apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java
copy to apps/vpls/src/main/java/org/onosproject/vpls/intent/package-info.java
index b5d6ec9..197ea02 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/intent/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Laboratory
+ * Copyright 2017-present Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,6 +15,6 @@
  */
 
 /**
- * Configuration service implementation for VPLS.
+ * Utility for generate Intent for VPLS.
  */
-package org.onosproject.vpls.config.impl;
+package org.onosproject.vpls.intent;
\ No newline at end of file
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/store/DistributedVplsStore.java b/apps/vpls/src/main/java/org/onosproject/vpls/store/DistributedVplsStore.java
new file mode 100644
index 0000000..1743491
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/store/DistributedVplsStore.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vpls.store;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.store.AbstractStore;
+import org.onosproject.store.StoreDelegate;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.EventuallyConsistentMapEvent;
+import org.onosproject.store.service.EventuallyConsistentMapListener;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.onosproject.vpls.VplsManager;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.api.VplsOperation;
+import org.onosproject.vpls.config.VplsAppConfig;
+import org.onosproject.vpls.api.VplsStore;
+import org.onosproject.vpls.config.VplsConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+import static java.util.Objects.*;
+
+/**
+ * Implementation of VPLSConfigurationService which reads VPLS configuration
+ * from the network configuration service.
+ */
+@Component(immediate = true)
+@Service
+public class DistributedVplsStore
+        extends AbstractStore<VplsStoreEvent, StoreDelegate<VplsStoreEvent>>
+        implements VplsStore {
+
+    private static final KryoNamespace APP_KRYO = KryoNamespace.newBuilder()
+            .register(KryoNamespaces.API)
+            .register(VplsData.class)
+            .register(VplsOperation.class)
+            .build();
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService networkConfigService;
+
+    private EventuallyConsistentMap<String, VplsData> vplsDataStore;
+    private EventuallyConsistentMapListener<String, VplsData> vplsDataListener;
+    private ApplicationId appId;
+
+    @Activate
+    protected void active() {
+        appId = coreService.registerApplication(VplsManager.VPLS_APP);
+
+        vplsDataStore = storageService.<String, VplsData>eventuallyConsistentMapBuilder()
+                .withName("VPLS-Data")
+                .withTimestampProvider((name, vpls) -> new WallClockTimestamp())
+                .withSerializer(APP_KRYO)
+                .build();
+        vplsDataListener = new InternalVplsDataListener();
+        vplsDataStore.addListener(vplsDataListener);
+        log.info("Started");
+    }
+
+    @Deactivate
+    protected  void deactive() {
+        vplsDataStore.removeListener(vplsDataListener);
+        log.info("Stopped");
+    }
+
+    @Override
+    public void addVpls(VplsData vplsData) {
+        requireNonNull(vplsData);
+        if (vplsData.name().isEmpty()) {
+            throw new IllegalArgumentException("VPLS name is empty.");
+        }
+        vplsData.state(VplsData.VplsState.ADDING);
+        this.vplsDataStore.put(vplsData.name(), vplsData);
+    }
+
+    @Override
+    public void removeVpls(VplsData vplsData) {
+        requireNonNull(vplsData);
+        if (vplsData.name().isEmpty()) {
+            throw new IllegalArgumentException("VPLS name is empty.");
+        }
+        vplsData.state(VplsData.VplsState.REMOVING);
+        if (!this.vplsDataStore.containsKey(vplsData.name())) {
+            // notify the delegate asynchronously if VPLS does not exists
+            CompletableFuture.runAsync(() -> {
+                VplsStoreEvent event = new VplsStoreEvent(VplsStoreEvent.Type.REMOVE,
+                                                          vplsData);
+                notifyDelegate(event);
+            });
+            return;
+        }
+        this.vplsDataStore.remove(vplsData.name());
+    }
+
+    @Override
+    public void updateVpls(VplsData vplsData) {
+        switch (vplsData.state()) {
+            case ADDED:
+            case REMOVED:
+            case FAILED:
+                // state update only
+                this.vplsDataStore.put(vplsData.name(), vplsData);
+                break;
+            default:
+                vplsData.state(VplsData.VplsState.UPDATING);
+                this.vplsDataStore.put(vplsData.name(), vplsData);
+                break;
+        }
+    }
+
+    @Override
+    public VplsData getVpls(String vplsName) {
+        return vplsDataStore.get(vplsName);
+    }
+
+    @Override
+    public Collection<VplsData> getAllVpls() {
+        return vplsDataStore.values();
+    }
+
+    /**
+     * Writes all VPLS data to the network configuration store.
+     *
+     * @param vplsDataCollection the VPLSs data
+     */
+    public void writeVplsToNetConfig(Collection<VplsData> vplsDataCollection) {
+        VplsAppConfig config = networkConfigService.addConfig(appId, VplsAppConfig.class);
+        config.clearVplsConfig();
+
+        // Setup update time for this VPLS application configuration
+        WallClockTimestamp ts = new WallClockTimestamp();
+        config.updateTime(ts.unixTimestamp());
+
+        vplsDataCollection.forEach(vplsData -> {
+            Set<String> interfaceNames = vplsData.interfaces()
+                    .stream()
+                    .map(Interface::name)
+                    .collect(Collectors.toSet());
+            VplsConfig vplsConfig = new VplsConfig(vplsData.name(), interfaceNames,
+                                                   vplsData.encapsulationType());
+            config.addVpls(vplsConfig);
+        });
+
+        networkConfigService.applyConfig(appId, VplsAppConfig.class, config.node());
+    }
+
+    /**
+     * Listener for VPLS data store.
+     */
+    private class InternalVplsDataListener implements EventuallyConsistentMapListener<String, VplsData> {
+        private static final String STATE_UPDATE = "VPLS state updated, new VPLS: {}";
+
+        @Override
+        public void event(EventuallyConsistentMapEvent<String, VplsData> event) {
+            VplsData vplsData = event.value();
+            // Update network config
+            writeVplsToNetConfig(getAllVpls());
+            switch (event.type()) {
+                case PUT:
+                    // Add or Update
+                    if (vplsData.state() == VplsData.VplsState.ADDING) {
+                        VplsStoreEvent vplsStoreEvent =
+                                new VplsStoreEvent(VplsStoreEvent.Type.ADD, vplsData);
+                        notifyDelegate(vplsStoreEvent);
+                    } else if (vplsData.state() == VplsData.VplsState.UPDATING) {
+                        VplsStoreEvent vplsStoreEvent =
+                                new VplsStoreEvent(VplsStoreEvent.Type.UPDATE, vplsData);
+                        notifyDelegate(vplsStoreEvent);
+                    } else {
+                        // Do nothing here, just update state from operation service
+                        log.debug(STATE_UPDATE, vplsData);
+                    }
+                    break;
+                case REMOVE:
+                    VplsStoreEvent vplsStoreEvent =
+                            new VplsStoreEvent(VplsStoreEvent.Type.REMOVE, vplsData);
+                    notifyDelegate(vplsStoreEvent);
+                    break;
+                default:
+                    break;
+            }
+
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/store/VplsStoreEvent.java b/apps/vpls/src/main/java/org/onosproject/vpls/store/VplsStoreEvent.java
new file mode 100644
index 0000000..210470c
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/store/VplsStoreEvent.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vpls.store;
+
+import org.onosproject.event.AbstractEvent;
+import org.onosproject.vpls.api.VplsData;
+
+/**
+ * A class to represent a VPLS store related event.
+ */
+public class VplsStoreEvent extends AbstractEvent<VplsStoreEvent.Type, VplsData> {
+
+    /**
+     * VPLS store event type.
+     */
+    public enum Type {
+        ADD,
+        REMOVE,
+        UPDATE
+    }
+
+    /**
+     * Constructs a store event with given event type and VPLS information.
+     *
+     * @param type the event type
+     * @param subject the VPLS
+     */
+    public VplsStoreEvent(Type type, VplsData subject) {
+        super(type, subject);
+    }
+
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java b/apps/vpls/src/main/java/org/onosproject/vpls/store/package-info.java
similarity index 78%
copy from apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java
copy to apps/vpls/src/main/java/org/onosproject/vpls/store/package-info.java
index b5d6ec9..0f1a807 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/config/impl/package-info.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/store/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Laboratory
+ * Copyright 2017-present Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,4 @@
  * limitations under the License.
  */
 
-/**
- * Configuration service implementation for VPLS.
- */
-package org.onosproject.vpls.config.impl;
+package org.onosproject.vpls.store;
\ No newline at end of file
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsConfigServiceAdapter.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsConfigServiceAdapter.java
deleted file mode 100644
index e5844fb..0000000
--- a/apps/vpls/src/test/java/org/onosproject/vpls/VplsConfigServiceAdapter.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.vpls;
-
-import com.google.common.collect.SetMultimap;
-import org.onlab.packet.VlanId;
-import org.onosproject.incubator.net.intf.Interface;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.EncapsulationType;
-import org.onosproject.vpls.config.VplsConfigService;
-
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Test adapter for VPLS configuration service.
- */
-public class VplsConfigServiceAdapter implements VplsConfigService {
-    @Override
-    public void addVpls(String vplsName, Set<String> ifaces, String encap) {}
-
-    @Override
-    public void removeVpls(String vplsName) {}
-
-    @Override
-    public void addIface(String vplsName, String iface) {}
-
-    @Override
-    public void setEncap(String vplsName, String encap) {}
-
-    @Override
-    public EncapsulationType encap(String vplsName) {
-        return null;
-    }
-
-    @Override
-    public void removeIface(String iface) {}
-
-    @Override
-    public void cleanVplsConfig() {}
-
-    @Override
-    public Set<String> vplsAffectedByApi() {
-        return null;
-    }
-
-    @Override
-    public Set<Interface> allIfaces() {
-        return null;
-    }
-
-    @Override
-    public Set<Interface> ifaces() {
-        return null;
-    }
-
-    @Override
-    public Set<Interface> ifaces(String vplsName) {
-        return null;
-    }
-
-    @Override
-    public Set<String> vplsNames() {
-        return null;
-    }
-
-    @Override
-    public Set<String> vplsNamesOld() {
-        return null;
-    }
-
-    @Override
-    public SetMultimap<String, Interface> ifacesByVplsName() {
-        return null;
-    }
-
-    @Override
-    public SetMultimap<String, Interface> ifacesByVplsName(VlanId vlan, ConnectPoint connectPoint) {
-        return null;
-    }
-
-    @Override
-    public Map<String, EncapsulationType> encapByVplsName() {
-        return null;
-    }
-}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsIntentTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsIntentTest.java
new file mode 100644
index 0000000..7ee9292
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/VplsIntentTest.java
@@ -0,0 +1,537 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vpls;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceListener;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.Host;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.IntentServiceAdapter;
+import org.onosproject.net.intent.IntentUtils;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.net.intent.SinglePointToMultiPointIntent;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.intent.VplsIntentUtility;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.lang.String.format;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.EncapsulationType.NONE;
+import static org.onosproject.net.EncapsulationType.VLAN;
+
+/**
+ * Tests for {@link VplsIntentUtility}.
+ */
+public class VplsIntentTest extends VplsTest {
+
+    private Set<Host> hostsAvailable;
+    private IntentService intentService;
+    private InterfaceService interfaceService;
+
+    @Before
+    public void setUp() throws Exception {
+        idGenerator = new TestIdGenerator();
+        Intent.unbindIdGenerator(idGenerator);
+        Intent.bindIdGenerator(idGenerator);
+        hostsAvailable = Sets.newHashSet();
+        intentService = new TestIntentService();
+        interfaceService = createMock(InterfaceService.class);
+        interfaceService.addListener(anyObject(InterfaceListener.class));
+        expectLastCall().anyTimes();
+        addIfaceConfig();
+    }
+
+    @After
+    public void tearDown() {
+        Intent.unbindIdGenerator(idGenerator);
+    }
+
+    /**
+     * Creates the interface configuration:
+     *  On devices 1 and 2 is configured an interface on port 1 with vlan 100.
+     *  On device 3 is configured an interface on port 3 with no vlan.
+     *  On devices 3 and 4 is configured an interface on port 1 with vlan 200.
+     *  On device 4 is an interface configured on port 2 with vlan 400.
+     *  On device 5 are configured two interfaces on port 1 and 2 with no vlan.
+     *  On device 5 and 6 is configured an interface on port 1 with vlan 300.
+     */
+    private void addIfaceConfig() {
+        Set<Interface> interfaces = ImmutableSet.copyOf(AVAILABLE_INTERFACES);
+        Set<Interface> vlanOneSet = ImmutableSet.of(V100H1, V100H2);
+        Set<Interface> vlanTwoSet = ImmutableSet.of(V200H1, V200H2);
+        Set<Interface> vlanThreeSet = ImmutableSet.of(VNONEH1, VNONEH2);
+        Set<Interface> vlanFourSet = ImmutableSet.of(V400H1, VNONEH3);
+
+        AVAILABLE_INTERFACES.forEach(intf -> {
+            expect(interfaceService.getInterfacesByPort(intf.connectPoint()))
+                    .andReturn(Sets.newHashSet(intf)).anyTimes();
+        });
+        expect(interfaceService.getInterfacesByVlan(VLAN100))
+                .andReturn(vlanOneSet).anyTimes();
+        expect(interfaceService.getInterfacesByVlan(VLAN200))
+                .andReturn(vlanTwoSet).anyTimes();
+        expect(interfaceService.getInterfacesByVlan(VLAN300))
+                .andReturn(vlanThreeSet).anyTimes();
+        expect(interfaceService.getInterfacesByVlan(VLAN400))
+                .andReturn(vlanFourSet).anyTimes();
+        expect(interfaceService.getInterfacesByVlan(VlanId.NONE))
+                .andReturn(vlanFourSet).anyTimes();
+        expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
+
+        replay(interfaceService);
+    }
+
+    /**
+     * Seven ports are configured with VLANs, while three ports are not. No hosts are
+     * registered by the HostService.
+     *
+     * The first three ports have an interface configured on VPLS 1,
+     * the other three on VPLS 2. Two ports are defined for VPLS 3, while
+     * the two remaining ports are configured on VPLS 4.
+     *
+     * The number of intents expected is 10: three for VPLS 1, three for VPLS 2,
+     * two for VPLS 3, two for VPLS 4. Eight MP2SP intents.
+     * Checks if the number of intents submitted to the intent framework is
+     * equal to the number of intents expected and if all intents are equivalent.
+     */
+    @Test
+    public void activateNoHosts() {
+        List<Intent> expectedIntents = Lists.newArrayList();
+        Set<FilteredConnectPoint> fcPoints;
+        Set<Interface> interfaces;
+
+        interfaces = ImmutableSet.of(V100H1, V200H1, V300H1);
+        VplsData vplsData = createVplsData(VPLS1, VLAN, interfaces);
+        Set<Intent> brcIntents = VplsIntentUtility.buildBrcIntents(vplsData, APPID);
+        brcIntents.forEach(intentService::submit);
+        fcPoints = buildFCPoints(interfaces);
+        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS1, VLAN));
+
+        checkIntents(expectedIntents);
+
+        interfaces = ImmutableSet.of(V100H2, V200H2, V300H2);
+        vplsData = createVplsData(VPLS2, NONE, interfaces);
+        brcIntents = VplsIntentUtility.buildBrcIntents(vplsData, APPID);
+        brcIntents.forEach(intentService::submit);
+        fcPoints = buildFCPoints(interfaces);
+        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS2, NONE));
+
+        checkIntents(expectedIntents);
+
+        interfaces = ImmutableSet.of(VNONEH1, VNONEH2);
+        vplsData = createVplsData(VPLS3, NONE, interfaces);
+        brcIntents = VplsIntentUtility.buildBrcIntents(vplsData, APPID);
+        brcIntents.forEach(intentService::submit);
+        fcPoints = buildFCPoints(interfaces);
+        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS3, NONE));
+
+        checkIntents(expectedIntents);
+
+        interfaces = ImmutableSet.of(V400H1, VNONEH3);
+        vplsData = createVplsData(VPLS4, NONE, interfaces);
+        brcIntents = VplsIntentUtility.buildBrcIntents(vplsData, APPID);
+        brcIntents.forEach(intentService::submit);
+        fcPoints = buildFCPoints(interfaces);
+        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS4, NONE));
+
+        checkIntents(expectedIntents);
+    }
+
+
+
+    /**
+     * Ten ports are configured with VLANs and ten hosts are registered by the
+     * HostService.
+     *
+     * The first three ports have an interface configured on VPLS 1,
+     * the other three on VPLS 2, two on VPLS3 and two on VPLS4.
+     *
+     * The number of intents expected is twenty: six
+     * for VPLS 1, six for VPLS 2. four for VPLS 3, four for VPLS 4.
+     * That is ten sp2mp intents, ten mp2sp intents. For VPLS 1
+     * IPs are added to demonstrate this doesn't influence the number of intents
+     * created. Checks if the number of intents submitted to the intent
+     * framework is equal to the number of intents expected and if all intents
+     * are equivalent.
+     */
+    @Test
+    public void tenInterfacesConfiguredHostsPresent() {
+        hostsAvailable.addAll(AVAILABLE_HOSTS);
+
+        List<Intent> expectedIntents = Lists.newArrayList();
+        Set<FilteredConnectPoint> fcPoints;
+        Set<Host> hosts;
+        Set<Interface> interfaces;
+        VplsData vplsData;
+        Set<Intent> brcIntents;
+        Set<Intent> uniIntents;
+
+        interfaces = ImmutableSet.of(V100H1, V200H1, V300H1);
+        fcPoints = buildFCPoints(interfaces);
+        hosts = ImmutableSet.of(V100HOST1, V200HOST1, V300HOST1);
+        vplsData = createVplsData(VPLS1, VLAN, interfaces);
+        brcIntents = VplsIntentUtility.buildBrcIntents(vplsData, APPID);
+        uniIntents = VplsIntentUtility.buildUniIntents(vplsData, hosts, APPID);
+        brcIntents.forEach(intentService::submit);
+        uniIntents.forEach(intentService::submit);
+        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS1, VLAN));
+        expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS1, VLAN));
+
+        interfaces = ImmutableSet.of(V100H2, V200H2, V300H2);
+        fcPoints = buildFCPoints(interfaces);
+        hosts = ImmutableSet.of(V100HOST2, V200HOST2, V300HOST2);
+        vplsData = createVplsData(VPLS2, NONE, interfaces);
+        brcIntents = VplsIntentUtility.buildBrcIntents(vplsData, APPID);
+        uniIntents = VplsIntentUtility.buildUniIntents(vplsData, hosts, APPID);
+        brcIntents.forEach(intentService::submit);
+        uniIntents.forEach(intentService::submit);
+        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS2, NONE));
+        expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS2, NONE));
+
+        interfaces = ImmutableSet.of(VNONEH1, VNONEH2);
+        fcPoints = buildFCPoints(interfaces);
+        hosts = ImmutableSet.of(VNONEHOST1, VNONEHOST2);
+        vplsData = createVplsData(VPLS3, NONE, interfaces);
+        brcIntents = VplsIntentUtility.buildBrcIntents(vplsData, APPID);
+        uniIntents = VplsIntentUtility.buildUniIntents(vplsData, hosts, APPID);
+        brcIntents.forEach(intentService::submit);
+        uniIntents.forEach(intentService::submit);
+        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS3, NONE));
+        expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS3, NONE));
+
+        interfaces = ImmutableSet.of(V400H1, VNONEH3);
+        fcPoints = buildFCPoints(interfaces);
+        hosts = ImmutableSet.of(V400HOST1, VNONEHOST3);
+        vplsData = createVplsData(VPLS4, NONE, interfaces);
+        brcIntents = VplsIntentUtility.buildBrcIntents(vplsData, APPID);
+        uniIntents = VplsIntentUtility.buildUniIntents(vplsData, hosts, APPID);
+        brcIntents.forEach(intentService::submit);
+        uniIntents.forEach(intentService::submit);
+        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS4, NONE));
+        expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS4, NONE));
+
+        checkIntents(expectedIntents);
+    }
+
+    /**
+     * Generates a list of the expected sp2mp intents for a VPLS.
+     *
+     * @param fcPoints the filtered connect point
+     * @param name the name of the VPLS
+     * @param encap the encapsulation type
+     * @return the list of expected sp2mp intents for the given VPLS
+     */
+    private List<SinglePointToMultiPointIntent>
+    generateVplsBrc(Set<FilteredConnectPoint> fcPoints, String name, EncapsulationType encap) {
+        List<SinglePointToMultiPointIntent> intents = Lists.newArrayList();
+
+        fcPoints.forEach(point -> {
+            Set<FilteredConnectPoint> otherPoints =
+                    fcPoints.stream()
+                            .filter(fcp -> !fcp.equals(point))
+                            .collect(Collectors.toSet());
+
+            Key brckey = buildKey(VplsIntentUtility.PREFIX_BROADCAST,
+                                  point.connectPoint(),
+                                  name,
+                                  MacAddress.BROADCAST);
+
+            intents.add(buildBrcIntent(brckey, point, otherPoints, encap));
+        });
+
+        return intents;
+    }
+
+    /**
+     * Generates a list of expected mp2sp intents for a given VPLS.
+     *
+     * @param fcPoints the filtered connect point
+     * @param hosts the hosts
+     * @param name the name of the VPLS
+     * @param encap the encapsulation type
+     * @return the list of expected mp2sp intents for the given VPLS
+     */
+    private List<MultiPointToSinglePointIntent>
+    generateVplsUni(Set<FilteredConnectPoint> fcPoints, Set<Host> hosts,
+                    String name, EncapsulationType encap) {
+        List<MultiPointToSinglePointIntent> intents = Lists.newArrayList();
+
+        hosts.forEach(host -> {
+            FilteredConnectPoint hostPoint = getHostPoint(host, fcPoints);
+
+            Set<FilteredConnectPoint> otherPoints =
+                    fcPoints.stream()
+                            .filter(fcp -> !fcp.equals(hostPoint))
+                            .collect(Collectors.toSet());
+
+            Key uniKey = buildKey(VplsIntentUtility.PREFIX_UNICAST,
+                                  host.location(), name, host.mac());
+
+            intents.add(buildUniIntent(uniKey, otherPoints, hostPoint, host, encap));
+        });
+
+        return intents;
+    }
+
+    /**
+     * Checks if the number of intents submitted to the intent framework is equal
+     * to the number of intents expected and if all intents are equivalent.
+     *
+     * @param intents the list of intents expected
+     */
+    private void checkIntents(List<Intent> intents) {
+        assertEquals("The number of intents submitted differs from the number" +
+                             " of intents expected. ",
+                     intents.size(), intentService.getIntentCount());
+        for (Intent intentOne : intents) {
+            boolean found = false;
+            for (Intent intentTwo : intentService.getIntents()) {
+                if (intentOne.key().equals(intentTwo.key())) {
+                    found = true;
+                    assertTrue(format("The intent submitted is different from" +
+                                              " the intent expected. %s %s",
+                                      intentOne, intentTwo),
+                               IntentUtils.intentsAreEqual(intentOne, intentTwo));
+                    break;
+                }
+            }
+            assertTrue("The intent submitted is not equal to any of the expected" +
+                               " intents. ", found);
+        }
+    }
+
+    /**
+     * Builds a broadcast intent.
+     *
+     * @param key the key to identify the intent
+     * @param src the ingress connect point
+     * @param dsts the egress connect points
+     * @return the generated single-point to multi-point intent
+     */
+    private SinglePointToMultiPointIntent buildBrcIntent(Key key,
+                                                         FilteredConnectPoint src,
+                                                         Set<FilteredConnectPoint> dsts,
+                                                         EncapsulationType encap) {
+        SinglePointToMultiPointIntent.Builder intentBuilder;
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthDst(MacAddress.BROADCAST)
+                .build();
+        intentBuilder = SinglePointToMultiPointIntent.builder()
+                .appId(APPID)
+                .key(key)
+                .selector(selector)
+                .filteredIngressPoint(src)
+                .filteredEgressPoints(dsts)
+                .constraints(VplsIntentUtility.PARTIAL_FAILURE_CONSTRAINT)
+                .priority(PRIORITY_OFFSET);
+        VplsIntentUtility.setEncap(intentBuilder,
+                                   VplsIntentUtility.PARTIAL_FAILURE_CONSTRAINT,
+                                   encap);
+
+        return intentBuilder.build();
+    }
+
+    /**
+     * Builds a unicast intent.
+     *
+     * @param key the key to identify the intent
+     * @param srcs the ingress connect points
+     * @param dst the egress connect point
+     * @param host the destination Host
+     * @return the generated multi-point to single-point intent
+     */
+    private MultiPointToSinglePointIntent buildUniIntent(Key key,
+                                                         Set<FilteredConnectPoint> srcs,
+                                                         FilteredConnectPoint dst,
+                                                         Host host,
+                                                         EncapsulationType encap) {
+        MultiPointToSinglePointIntent.Builder intentBuilder;
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthDst(host.mac())
+                .build();
+        intentBuilder = MultiPointToSinglePointIntent.builder()
+                .appId(APPID)
+                .key(key)
+                .selector(selector)
+                .filteredIngressPoints(srcs)
+                .filteredEgressPoint(dst)
+                .constraints(VplsIntentUtility.PARTIAL_FAILURE_CONSTRAINT)
+                .priority(PRIORITY_OFFSET);
+        VplsIntentUtility.setEncap(intentBuilder,
+                                   VplsIntentUtility.PARTIAL_FAILURE_CONSTRAINT,
+                                   encap);
+
+        return intentBuilder.build();
+    }
+
+    /**
+     * Returns the filtered connect point associated to a given host.
+     *
+     * @param host the target host
+     * @param fcps the filtered connected points
+     * @return the filtered connect point associated to the given host; null
+     * otherwise
+     */
+    private FilteredConnectPoint getHostPoint(Host host,
+                                              Set<FilteredConnectPoint> fcps) {
+        return fcps.stream()
+                .filter(fcp -> fcp.connectPoint().equals(host.location()))
+                .filter(fcp -> {
+                    VlanIdCriterion vlanCriterion =
+                            (VlanIdCriterion) fcp.trafficSelector().
+                                    getCriterion(Criterion.Type.VLAN_VID);
+                    return vlanCriterion == null ||
+                            vlanCriterion.vlanId().equals(host.vlan());
+                })
+                .findFirst()
+                .orElse(null);
+    }
+
+    /**
+     * Computes a set of filtered connect points from a list of given interfaces.
+     *
+     * @param interfaces the interfaces to compute
+     * @return the set of filtered connect points
+     */
+    private Set<FilteredConnectPoint> buildFCPoints(Collection<Interface> interfaces) {
+        // Build all filtered connected points in the VPLS
+        return interfaces
+                .stream()
+                .map(intf -> {
+                    TrafficSelector.Builder selectorBuilder =
+                            DefaultTrafficSelector.builder();
+                    if (!intf.vlan().equals(VlanId.NONE)) {
+                        selectorBuilder.matchVlanId(intf.vlan());
+                    }
+                    return new FilteredConnectPoint(intf.connectPoint(),
+                                                    selectorBuilder.build());
+                })
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * Builds an intent Key either for a single-point to multi-point or
+     * multi-point to single-point intent, based on a prefix that defines
+     * the intent type, the connection point representing the source or the
+     * destination and the VLAN Id representing the VPLS.
+     *
+     * @param prefix the key prefix
+     * @param cPoint the ingress/egress connect point
+     * @param vplsName the VPLS name
+     * @param hostMac the ingress/egress MAC address
+     * @return the key to identify the intent
+     */
+    private Key buildKey(String prefix,
+                         ConnectPoint cPoint,
+                         String vplsName,
+                         MacAddress hostMac) {
+        String keyString = vplsName +
+                DASH +
+                prefix +
+                DASH +
+                cPoint.deviceId() +
+                DASH +
+                cPoint.port() +
+                DASH +
+                hostMac;
+
+        return Key.of(keyString, APPID);
+    }
+
+    /**
+     * Creates VPLS data by given name, encapsulation type and network
+     * interfaces.
+     *
+     * @param name the VPLS name
+     * @param encap the encapsulation type
+     * @param interfaces the network interfaces
+     * @return the VPLS data
+     */
+    private VplsData createVplsData(String name, EncapsulationType encap,
+                                    Set<Interface> interfaces) {
+        VplsData vplsData = VplsData.of(name, encap);
+        vplsData.addInterfaces(interfaces);
+        return vplsData;
+    }
+
+    /**
+     * Represents a fake IntentService class that allows to store and retrieve
+     * intents without implementing the IntentService logic.
+     */
+    private class TestIntentService extends IntentServiceAdapter {
+        private Map<Key, Intent> intents;
+
+        public TestIntentService() {
+            intents = Maps.newHashMap();
+        }
+
+        @Override
+        public void submit(Intent intent) {
+            intents.put(intent.key(), intent);
+        }
+
+        @Override
+        public long getIntentCount() {
+            return intents.size();
+        }
+
+        @Override
+        public Iterable<Intent> getIntents() {
+            return intents.values();
+        }
+
+        @Override
+        public Intent getIntent(Key intentKey) {
+            for (Intent intent : intents.values()) {
+                if (intent.key().equals(intentKey)) {
+                    return intent;
+                }
+            }
+            return null;
+        }
+    }
+
+}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsManagerTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsManagerTest.java
new file mode 100644
index 0000000..67128db
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/VplsManagerTest.java
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vpls;
+
+import com.google.common.collect.ImmutableSet;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.api.VplsOperation;
+import org.onosproject.vpls.api.VplsOperationService;
+import org.onosproject.vpls.store.VplsStoreEvent;
+
+import java.util.Collection;
+
+import static org.junit.Assert.*;
+import static org.onosproject.net.EncapsulationType.*;
+import static org.onosproject.vpls.api.VplsData.VplsState.*;
+
+/**
+ * Test for {@link VplsManager}
+ */
+public class VplsManagerTest extends VplsTest {
+    private VplsManager vplsManager;
+    private TestVplsStore vplsStore = new TestVplsStore();
+    private TestHostService hostService = new TestHostService();
+    private TestInterfaceService interfaceService = new TestInterfaceService();
+    private TestVplsOperationService vplsOperationService = new TestVplsOperationService();
+
+    @Before
+    public void setup() {
+        vplsManager = new VplsManager();
+        vplsManager.hostService = hostService;
+        vplsManager.vplsStore = vplsStore;
+        vplsManager.operationService = vplsOperationService;
+        vplsManager.interfaceService = interfaceService;
+        vplsStore.clear();
+        vplsOperationService.clear();
+        vplsManager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        vplsManager.deactivate();
+    }
+
+    /**
+     * Creates VPLS by given name and encapsulation type.
+     */
+    @Test
+    public void testCreateVpls() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        assertEquals(VPLS1, vplsData.name());
+        assertEquals(NONE, vplsData.encapsulationType());
+
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertEquals(vplsData.state(), ADDING);
+    }
+
+    /**
+     * Gets VPLS by VPLS name.
+     */
+    @Test
+    public void testGetVpls() {
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.state(ADDED);
+        vplsStore.addVpls(vplsData);
+
+        VplsData result = vplsManager.getVpls(VPLS1);
+        assertEquals(vplsData, result);
+
+        result = vplsManager.getVpls(VPLS2);
+        assertNull(result);
+    }
+
+    /**
+     * Removes a VPLS.
+     */
+    @Test
+    public void testRemoveVpls() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        vplsManager.removeVpls(vplsData);
+        assertEquals(vplsData.state(), REMOVING);
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertNull(vplsData);
+        Collection<VplsData> allVpls = vplsStore.getAllVpls();
+        assertEquals(0, allVpls.size());
+    }
+
+    /**
+     * Removes all VPLS.
+     */
+    @Test
+    public void testRemoveAllVpls() {
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.state(ADDED);
+        vplsStore.addVpls(vplsData);
+
+        vplsData = VplsData.of(VPLS2, VLAN);
+        vplsData.state(ADDED);
+        vplsStore.addVpls(vplsData);
+
+        vplsManager.removeAllVpls();
+        assertEquals(0, vplsStore.getAllVpls().size());
+    }
+
+    /**
+     * Adds network interfaces one by one to a VPLS.
+     */
+    @Test
+    public void testAddInterface() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        vplsManager.addInterface(vplsData, V100H1);
+        vplsManager.addInterface(vplsData, V100H2);
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertNotNull(vplsData);
+        assertEquals(vplsData.state(), UPDATING);
+        assertEquals(2, vplsData.interfaces().size());
+        assertTrue(vplsData.interfaces().contains(V100H1));
+        assertTrue(vplsData.interfaces().contains(V100H2));
+    }
+
+    /**
+     * Adds network interfaces to a VPLS.
+     */
+    @Test
+    public void testAddInterfaces() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        vplsManager.addInterfaces(vplsData, ImmutableSet.of(V100H1, V100H2));
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertNotNull(vplsData);
+        assertEquals(vplsData.state(), UPDATING);
+        assertEquals(2, vplsData.interfaces().size());
+        assertTrue(vplsData.interfaces().contains(V100H1));
+        assertTrue(vplsData.interfaces().contains(V100H2));
+    }
+
+    /**
+     * Removes network interfaces one by one from a VPLS.
+     */
+    @Test
+    public void testRemoveInterface() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        vplsManager.addInterface(vplsData, V100H1);
+        vplsManager.addInterface(vplsData, V100H2);
+        vplsManager.removeInterface(vplsData, V100H1);
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertNotNull(vplsData);
+        assertEquals(vplsData.state(), UPDATING);
+        assertEquals(1, vplsData.interfaces().size());
+        assertTrue(vplsData.interfaces().contains(V100H2));
+    }
+
+    /**
+     * Removes network interfaces from a VPLS.
+     */
+    @Test
+    public void testRemoveInterfaces() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        vplsManager.addInterface(vplsData, V100H1);
+        vplsManager.addInterface(vplsData, V100H2);
+        vplsManager.removeInterfaces(vplsData, ImmutableSet.of(V100H1, V100H2));
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertNotNull(vplsData);
+        assertEquals(vplsData.state(), UPDATING);
+        assertEquals(0, vplsData.interfaces().size());
+    }
+
+    /**
+     * Sets encapsulation type for a VPLS.
+     */
+    @Test
+    public void testSetEncapsulationType() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        vplsManager.setEncapsulationType(vplsData, EncapsulationType.VLAN);
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertNotNull(vplsData);
+        assertEquals(vplsData.state(), UPDATING);
+        assertEquals(vplsData.encapsulationType(), EncapsulationType.VLAN);
+    }
+
+    /**
+     * Adds hosts to a VPLS.
+     */
+    @Test
+    public void testAddHost() {
+        VplsData vplsData  = VplsData.of(VPLS1, NONE);
+        vplsData.addInterface(V100H1);
+        vplsData.state(ADDED);
+        vplsStore.addVpls(vplsData);
+
+        HostEvent hostEvent = new HostEvent(HostEvent.Type.HOST_ADDED, V100HOST1);
+        hostService.postHostEvent(hostEvent);
+
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertNotNull(vplsData);
+
+        assertEquals(vplsData.state(), UPDATING);
+    }
+
+    /**
+     * Removes hosts from a VPLS.
+     */
+    @Test
+    public void testRemoveHost() {
+        VplsData vplsData  = VplsData.of(VPLS1, NONE);
+        vplsData.addInterface(V100H1);
+        vplsData.state(ADDED);
+        vplsStore.addVpls(vplsData);
+
+        HostEvent hostEvent = new HostEvent(HostEvent.Type.HOST_REMOVED, V100HOST1);
+        hostService.postHostEvent(hostEvent);
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertNotNull(vplsData);
+
+        assertEquals(vplsData.state(), UPDATING);
+    }
+
+    /**
+     * Pass different VPLS store event to store delegate.
+     * Include these cases:
+     * <ul>
+     *     <li>VPLS added</li>
+     *     <li>VPLS updated</li>
+     *     <li>VPLS state updated</li>
+     *     <li>VPLS removed</li>
+     * </ul>
+     */
+    @Test
+    public void testStoreDelegate() {
+        // Add
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        VplsStoreEvent event = new VplsStoreEvent(VplsStoreEvent.Type.ADD, vplsData);
+        vplsStore.delegate().notify(event);
+
+        VplsOperation vplsOperation = vplsOperationService.operation();
+        assertEquals(vplsOperation.op(), VplsOperation.Operation.ADD);
+        assertEquals(vplsOperation.vpls(), vplsData);
+        vplsOperationService.clear();
+
+        // Update info
+        vplsData.encapsulationType(EncapsulationType.VLAN);
+        vplsData.state(UPDATING);
+        event = new VplsStoreEvent(VplsStoreEvent.Type.UPDATE, vplsData);
+        vplsStore.delegate().notify(event);
+        vplsOperation = vplsOperationService.operation();
+        assertEquals(vplsOperation.op(), VplsOperation.Operation.UPDATE);
+        assertEquals(vplsOperation.vpls(), vplsData);
+        vplsOperationService.clear();
+
+        // Update state (no operation)
+        vplsData.state(VplsData.VplsState.ADDED);
+        event = new VplsStoreEvent(VplsStoreEvent.Type.UPDATE, vplsData);
+        vplsStore.delegate().notify(event);
+        vplsOperation = vplsOperationService.operation();
+        assertNull(vplsOperation);
+        vplsOperationService.clear();
+
+        // Remove
+        event = new VplsStoreEvent(VplsStoreEvent.Type.REMOVE, vplsData);
+        vplsStore.delegate().notify(event);
+        vplsOperation = vplsOperationService.operation();
+        assertEquals(vplsOperation.op(), VplsOperation.Operation.REMOVE);
+        assertEquals(vplsOperation.vpls(), vplsData);
+        vplsOperationService.clear();
+    }
+
+    /**
+     * Trigger host event listener by HOST_ADDED event.
+     */
+    @Test
+    public void hostAddEventTest() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        vplsManager.addInterface(vplsData, V100H1);
+        HostEvent hostEvent = new HostEvent(HostEvent.Type.HOST_ADDED, V100HOST1);
+        hostService.postHostEvent(hostEvent);
+
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertEquals(UPDATING, vplsData.state());
+    }
+
+    /**
+     * Trigger host event listener by HOST_REMOVED event.
+     */
+    @Test
+    public void hostRemoveEventTest() {
+        VplsData vplsData = vplsManager.createVpls(VPLS1, NONE);
+        vplsManager.addInterface(vplsData, V100H1);
+        HostEvent hostEvent = new HostEvent(HostEvent.Type.HOST_REMOVED, V100HOST1);
+        hostService.postHostEvent(hostEvent);
+
+        vplsData = vplsStore.getVpls(VPLS1);
+        assertEquals(UPDATING, vplsData.state());
+    }
+
+    /**
+     * Test VPLS operation service.
+     * Stores last operation submitted by VPLS manager.
+     */
+    class TestVplsOperationService implements VplsOperationService {
+        VplsOperation operation;
+
+        @Override
+        public void submit(VplsOperation vplsOperation) {
+            this.operation = vplsOperation;
+        }
+
+        /**
+         * Clears the VPLS operation.
+         */
+        public void clear() {
+            operation = null;
+        }
+
+        /**
+         * Gets the latest VPLS operation.
+         * @return the latest VPLS operation.
+         */
+        public VplsOperation operation() {
+            return operation;
+        }
+    }
+
+}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsNeighbourHandlerTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsNeighbourHandlerTest.java
index 412e937..2acc871 100644
--- a/apps/vpls/src/test/java/org/onosproject/vpls/VplsNeighbourHandlerTest.java
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/VplsNeighbourHandlerTest.java
@@ -17,8 +17,6 @@
 
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.Maps;
 import com.google.common.collect.SetMultimap;
 import com.google.common.collect.Sets;
 import org.junit.After;
@@ -30,8 +28,6 @@
 import org.onlab.packet.VlanId;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.incubator.net.intf.Interface;
-import org.onosproject.incubator.net.intf.InterfaceListener;
-import org.onosproject.incubator.net.intf.InterfaceService;
 import org.onosproject.incubator.net.neighbour.NeighbourHandlerRegistration;
 import org.onosproject.incubator.net.neighbour.NeighbourMessageContext;
 import org.onosproject.incubator.net.neighbour.NeighbourMessageHandler;
@@ -39,122 +35,26 @@
 import org.onosproject.incubator.net.neighbour.NeighbourProtocol;
 import org.onosproject.incubator.net.neighbour.NeighbourResolutionService;
 import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultHost;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.EncapsulationType;
 import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.HostLocation;
-import org.onosproject.net.PortNumber;
 import org.onosproject.net.host.HostService;
-import org.onosproject.net.host.HostServiceAdapter;
-import org.onosproject.net.provider.ProviderId;
+import org.onosproject.vpls.api.VplsData;
 
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertTrue;
 
 /**
- * Tests the the {@link VplsNeighbourHandler} class.
+ * Tests the the {@link VplsNeighbourHandler}.
  */
-public class VplsNeighbourHandlerTest {
+public class VplsNeighbourHandlerTest extends VplsTest {
 
     private static final String IFACES_NOT_EXPECTED =
             "The interfaces reached by the packet are not equal to the " +
                     "interfaces expected.";
-
-    private static final DeviceId DID1 = getDeviceId(1);
-    private static final DeviceId DID2 = getDeviceId(2);
-    private static final DeviceId DID3 = getDeviceId(3);
-    private static final DeviceId DID4 = getDeviceId(4);
-    private static final DeviceId DID5 = getDeviceId(5);
-
-    private static final PortNumber P1 = PortNumber.portNumber(1);
-    private static final PortNumber P2 = PortNumber.portNumber(2);
-    private static final PortNumber P3 = PortNumber.portNumber(3);
-
-    private static final ConnectPoint OF1P1 = new ConnectPoint(DID1, P1);
-    private static final ConnectPoint OF2P1 = new ConnectPoint(DID2, P1);
-    private static final ConnectPoint OF3P1 = new ConnectPoint(DID3, P1);
-    private static final ConnectPoint OF4P1 = new ConnectPoint(DID4, P1);
-    private static final ConnectPoint OF4P2 = new ConnectPoint(DID4, P2);
-    private static final ConnectPoint OF4P3 = new ConnectPoint(DID4, P3);
-    private static final ConnectPoint OF5P1 = new ConnectPoint(DID5, P1);
-    private static final ConnectPoint OF5P2 = new ConnectPoint(DID5, P2);
-    private static final ConnectPoint OF5P3 = new ConnectPoint(DID5, P3);
-
-    private static final String VPLS1 = "vpls1";
-    private static final String VPLS2 = "vpls2";
-    private static final String VPLS3 = "vpls3";
-    private static final String VPLS4 = "vpls4";
-
-    private static final VlanId VLAN100 = VlanId.vlanId("100");
-    private static final VlanId VLAN200 = VlanId.vlanId("200");
-    private static final VlanId VLAN300 = VlanId.vlanId("300");
-    private static final VlanId VLAN400 = VlanId.vlanId("400");
-    private static final VlanId VLAN_NONE = VlanId.NONE;
-
-    private static final Interface V100H1 =
-            new Interface("v100h1", OF1P1, null, null, VLAN100);
-    private static final Interface V100H2 =
-            new Interface("v100h2", OF4P1, null, null, VLAN100);
-    private static final Interface V200H1 =
-            new Interface("v200h1", OF4P2, null, null, VLAN200);
-    private static final Interface V200H2 =
-            new Interface("v200h2", OF2P1, null, null, VLAN200);
-    private static final Interface V300H1 =
-            new Interface("v300h1", OF3P1, null, null, VLAN300);
-    private static final Interface V400H1 =
-            new Interface("v400h1", OF5P1, null, null, VLAN400);
-    private static final Interface VNONEH1 =
-            new Interface("vNoneh1", OF5P2, null, null, VLAN_NONE);
-    private static final Interface VNONEH2 =
-            new Interface("vNoneh2", OF5P3, null, null, VLAN_NONE);
-    private static final Interface VNONEH3 =
-            new Interface("vNoneh3", OF4P3, null, null, VLAN_NONE);
-
-    private static final MacAddress MAC1 = MacAddress.valueOf("00:00:00:00:00:01");
-    private static final MacAddress MAC2 = MacAddress.valueOf("00:00:00:00:00:02");
-    private static final MacAddress MAC3 = MacAddress.valueOf("00:00:00:00:00:03");
-    private static final MacAddress MAC4 = MacAddress.valueOf("00:00:00:00:00:04");
-    private static final MacAddress MAC5 = MacAddress.valueOf("00:00:00:00:00:05");
-    private static final MacAddress MAC6 = MacAddress.valueOf("00:00:00:00:00:06");
-    private static final MacAddress MAC7 = MacAddress.valueOf("00:00:00:00:00:07");
-    private static final MacAddress MAC8 = MacAddress.valueOf("00:00:00:00:00:08");
-    private static final MacAddress MAC9 = MacAddress.valueOf("00:00:00:00:00:09");
-
-    private static final ProviderId PID = new ProviderId("of", "foo");
-
-    private final Host v100Host1 = makeHost(MAC1, VLAN100, OF1P1);
-    private final Host v100Host2 = makeHost(MAC2, VLAN100, OF4P1);
-    private final Host v200Host1 = makeHost(MAC3, VLAN200, OF4P2);
-    private final Host v200Host2 = makeHost(MAC5, VLAN200, OF2P1);
-    private final Host v300Host1 = makeHost(MAC4, VLAN300, OF3P1);
-    private final Host v400Host1 = makeHost(MAC6, VLAN400, OF5P1);
-    private final Host vNoneHost1 = makeHost(MAC7, VLAN_NONE, OF5P2);
-    private final Host vNoneHost2 = makeHost(MAC8, VLAN_NONE, OF5P3);
-    private final Host vNoneHost3 = makeHost(MAC9, VLAN_NONE, OF4P3);
-
-    private final Set<Host> availableHosts = ImmutableSet.of(v100Host1,
-                                                             v100Host2,
-                                                             v200Host1,
-                                                             v300Host1,
-                                                             v200Host2,
-                                                             v400Host1,
-                                                             vNoneHost1,
-                                                             vNoneHost2,
-                                                             vNoneHost3);
-
-    private final Set<Interface> availableInterfaces =
-            ImmutableSet.of(V100H1, V100H2, V200H1, V200H2, V300H1,
-                            V400H1, VNONEH1, VNONEH2, VNONEH3);
-
     private VplsNeighbourHandler vplsNeighbourHandler;
-
     private HostService hostService;
 
     /**
@@ -167,29 +67,46 @@
     @Before
     public void setUp() {
         vplsNeighbourHandler = new VplsNeighbourHandler();
-        SetMultimap<String, Interface> ifacesByVpls =
-                HashMultimap.create();
-        ifacesByVpls.put(VPLS1, V100H1);
-        ifacesByVpls.put(VPLS1, V200H1);
-        ifacesByVpls.put(VPLS1, V300H1);
-        ifacesByVpls.put(VPLS2, V100H2);
-        ifacesByVpls.put(VPLS2, V200H2);
-        ifacesByVpls.put(VPLS3, VNONEH1);
-        ifacesByVpls.put(VPLS3, VNONEH2);
-        ifacesByVpls.put(VPLS4, V400H1);
-        ifacesByVpls.put(VPLS4, VNONEH3);
-        HashMap<String, EncapsulationType> encap = Maps.newHashMap();
-        vplsNeighbourHandler.vplsConfigService =
-                new TestVplsConfigService(ifacesByVpls, encap);
-        vplsNeighbourHandler.interfaceService =
-                new TestInterfaceService();
-        vplsNeighbourHandler.neighbourService =
-                new TestNeighbourService();
         hostService = new TestHostService();
+        vplsNeighbourHandler.vplsStore = new TestVplsStore();
+        vplsNeighbourHandler.interfaceService = new TestInterfaceService();
+        vplsNeighbourHandler.neighbourService = new TestNeighbourService();
+        vplsNeighbourHandler.coreService = new TestCoreService();
+        vplsNeighbourHandler.configService = new TestConfigService();
+
+        // Init VPLS store
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1, V200H1, V300H1));
+        vplsNeighbourHandler.vplsStore.addVpls(vplsData);
+
+        vplsData = VplsData.of(VPLS2);
+        vplsData.addInterfaces(ImmutableSet.of(V100H2, V200H2));
+        vplsNeighbourHandler.vplsStore.addVpls(vplsData);
+
+        vplsData = VplsData.of(VPLS3);
+        vplsData.addInterfaces(ImmutableSet.of(VNONEH1, VNONEH2));
+        vplsNeighbourHandler.vplsStore.addVpls(vplsData);
+
+        vplsData = VplsData.of(VPLS4);
+        vplsData.addInterfaces(ImmutableSet.of(V400H1, VNONEH3));
+        vplsNeighbourHandler.vplsStore.addVpls(vplsData);
+
+        vplsNeighbourHandler.activate();
+
     }
 
     @After
     public void tearDown() {
+        vplsNeighbourHandler.deactivate();
+    }
+
+    /**
+     * Registers neighbour handler to all available interfaces.
+     */
+    @Test
+    public void testConfigNeighbourHandler() {
+        vplsNeighbourHandler.configNeighbourHandler();
+        assertEquals(9, vplsNeighbourHandler.neighbourService.getHandlerRegistrations().size());
     }
 
     /**
@@ -200,21 +117,21 @@
     public void vpls1RequestMessage() {
         // Request messages from v100h1 (VPLS 1) should be received by v200h1 and v300h1
         TestMessageContext requestMessage =
-                makeBroadcastRequestContext(v100Host1);
+                makeBroadcastRequestContext(V100HOST1);
         Set<Interface> expectInterfaces = ImmutableSet.of(V200H1, V300H1);
-        vplsNeighbourHandler.handleRequest(requestMessage);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
 
         // Request messages from v200h1 (VPLS 1) should be received by v100h1 and v300h1
-        requestMessage = makeBroadcastRequestContext(v200Host1);
+        requestMessage = makeBroadcastRequestContext(V200HOST1);
         expectInterfaces = ImmutableSet.of(V100H1, V300H1);
-        vplsNeighbourHandler.handleRequest(requestMessage);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
 
         // Request from v300h1 (VPLS 1) should be received by v100h1 and v200h1
-        requestMessage = makeBroadcastRequestContext(v300Host1);
+        requestMessage = makeBroadcastRequestContext(V300HOST1);
         expectInterfaces = ImmutableSet.of(V100H1, V200H1);
-        vplsNeighbourHandler.handleRequest(requestMessage);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
     }
 
@@ -226,15 +143,15 @@
     public void vpls2RequestMessage() {
         // Request messages from v100h2 (VPLS 2) should be received by v200h2
         TestMessageContext requestMessage =
-                makeBroadcastRequestContext(v100Host2);
+                makeBroadcastRequestContext(V100HOST2);
         Set<Interface> expectInterfaces = ImmutableSet.of(V200H2);
-        vplsNeighbourHandler.handleRequest(requestMessage);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
 
         // Request messages from v200h2 (VPLS 2) should be received by v100h2
-        requestMessage = makeBroadcastRequestContext(v200Host2);
+        requestMessage = makeBroadcastRequestContext(V200HOST2);
         expectInterfaces = ImmutableSet.of(V100H2);
-        vplsNeighbourHandler.handleRequest(requestMessage);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
     }
 
@@ -246,17 +163,17 @@
      */
     @Test
     public void vpls3RequestMessage() {
-        // Request messages from vNoneHost1 (VPLS 3) should be received by vNoneHost2
+        // Request messages from VNONEHOST1 (VPLS 3) should be received by VNONEHOST2
         TestMessageContext requestMessage =
-                makeBroadcastRequestContext(vNoneHost1);
+                makeBroadcastRequestContext(VNONEHOST1);
         Set<Interface> expectInterfaces = ImmutableSet.of(VNONEH2);
-        vplsNeighbourHandler.handleRequest(requestMessage);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
 
         // Request messages from vNoneh2 (VPLS 3) should be received by vNoneh1
-        requestMessage = makeBroadcastRequestContext(vNoneHost2);
+        requestMessage = makeBroadcastRequestContext(VNONEHOST2);
         expectInterfaces = ImmutableSet.of(VNONEH1);
-        vplsNeighbourHandler.handleRequest(requestMessage);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
     }
 
@@ -268,17 +185,17 @@
      */
     @Test
     public void vpls4RequestMessage() {
-        // Request messages from v400Host1 (VPLS 4) should be received by vNoneHost3
+        // Request messages from V400HOST1 (VPLS 4) should be received by VNONEHOST3
         TestMessageContext requestMessage =
-                makeBroadcastRequestContext(v400Host1);
+                makeBroadcastRequestContext(V400HOST1);
         Set<Interface> expectInterfaces = ImmutableSet.of(VNONEH3);
-        vplsNeighbourHandler.handleRequest(requestMessage);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
 
-        // Request messages from vNoneHost3 (VPLS 4) should be received by v400Host1
-        requestMessage = makeBroadcastRequestContext(vNoneHost3);
+        // Request messages from VNONEHOST3 (VPLS 4) should be received by V400HOST1
+        requestMessage = makeBroadcastRequestContext(VNONEHOST3);
         expectInterfaces = ImmutableSet.of(V400H1);
-        vplsNeighbourHandler.handleRequest(requestMessage);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
     }
 
@@ -291,21 +208,21 @@
     public void vpls1ReplyMessage() {
         // Reply messages from v100h1 (VPLS 1) should be received by v200h1
         TestMessageContext replyMessage =
-                makeReplyContext(v100Host1, v200Host1);
+                makeReplyContext(V100HOST1, V200HOST1);
         Set<Interface> expectInterfaces = ImmutableSet.of(V200H1);
-        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
 
         // Reply messages from v200h1 (VPLS 1) should be received by v300h1
-        replyMessage = makeReplyContext(v200Host1, v300Host1);
+        replyMessage = makeReplyContext(V200HOST1, V300HOST1);
         expectInterfaces = ImmutableSet.of(V300H1);
-        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
 
         // Reply messages from v300h1 (VPLS 1) should be received by v100h1
-        replyMessage = makeReplyContext(v300Host1, v100Host1);
+        replyMessage = makeReplyContext(V300HOST1, V100HOST1);
         expectInterfaces = ImmutableSet.of(V100H1);
-        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
     }
 
@@ -318,15 +235,15 @@
     public void vpls2ReplyMessage() {
         // Reply messages from v100h2 (VPLS 2) should be received by v200h2
         TestMessageContext replyMessage =
-                makeReplyContext(v100Host2, v200Host2);
+                makeReplyContext(V100HOST2, V200HOST2);
         Set<Interface> expectInterfaces = ImmutableSet.of(V200H2);
-        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
 
         // Reply messages from v200h2 (VPLS 2) should be received by v100h2
-        replyMessage = makeReplyContext(v200Host2, v100Host2);
+        replyMessage = makeReplyContext(V200HOST2, V100HOST2);
         expectInterfaces = ImmutableSet.of(V100H2);
-        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
     }
 
@@ -339,15 +256,15 @@
     public void vpls3ReplyMessage() {
         // Reply messages from vNoneh1 (VPLS 3) should be received by vNoneh2
         TestMessageContext replyMessage =
-                makeReplyContext(vNoneHost1, vNoneHost2);
+                makeReplyContext(VNONEHOST1, VNONEHOST2);
         Set<Interface> expectInterfaces = ImmutableSet.of(VNONEH2);
-        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
 
         // Reply messages from vNoneh2 (VPLS 3) should be received by vNoneh1
-        replyMessage = makeReplyContext(vNoneHost2, vNoneHost1);
+        replyMessage = makeReplyContext(VNONEHOST2, VNONEHOST1);
         expectInterfaces = ImmutableSet.of(VNONEH1);
-        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
     }
 
@@ -360,15 +277,15 @@
     public void vpls4ReplyMessage() {
         // Reply messages from v400h1 (VPLS 4) should be received by vNoneh3
         TestMessageContext replyMessage =
-                makeReplyContext(v400Host1, vNoneHost3);
+                makeReplyContext(V400HOST1, VNONEHOST3);
         Set<Interface> expectInterfaces = ImmutableSet.of(VNONEH3);
-        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
 
         // Reply messages from vNoneh3 (VPLS 4) should be received by v400h1
-        replyMessage = makeReplyContext(vNoneHost3, v400Host1);
+        replyMessage = makeReplyContext(VNONEHOST3, V400HOST1);
         expectInterfaces = ImmutableSet.of(V400H1);
-        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
     }
 
@@ -381,52 +298,56 @@
     public void wrongReplyMessage() {
         // Reply message from v100h1 (VPLS 1) to v100h2 (VPLS 2).
         // Forward results should be empty
-        TestMessageContext replyMessage = makeReplyContext(v100Host1, v100Host2);
+        TestMessageContext replyMessage = makeReplyContext(V100HOST1, V100HOST2);
         Set<Interface> expectInterfaces = ImmutableSet.of();
-        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
 
         // Reply message from v200h2 (VPLS 2) to v300h1 (VPLS 1).
         // Forward results should be empty
-        replyMessage = makeReplyContext(v200Host2, v300Host1);
+        replyMessage = makeReplyContext(V200HOST2, V300HOST1);
         expectInterfaces = ImmutableSet.of();
-        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
 
         // Reply message from vNoneh1 (VPLS 3) to v400h1 (VPLS 4).
         // Forward results should be empty
-        replyMessage = makeReplyContext(vNoneHost1, v400Host1);
+        replyMessage = makeReplyContext(VNONEHOST1, V400HOST1);
         expectInterfaces = ImmutableSet.of();
-        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
 
         // Reply message from vNoneh3 (VPLS 4) to vNoneH2 (VPLS 3).
         // Forward results should be empty
-        replyMessage = makeReplyContext(vNoneHost3, vNoneHost2);
+        replyMessage = makeReplyContext(VNONEHOST3, VNONEHOST2);
         expectInterfaces = ImmutableSet.of();
-        vplsNeighbourHandler.handleReply(replyMessage, hostService);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
         assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
     }
 
     /**
-     * Returns the device Id of the ith device.
-     *
-     * @param i the device to get the Id of
-     * @return the device Id
+     * Sends reply and request message from a host which not related to any VPLS.
      */
-    private static DeviceId getDeviceId(int i) {
-        return DeviceId.deviceId("" + i);
+    @Test
+    public void testVplsNotfound() {
+        TestMessageContext replyMessage = makeReplyContext(V300HOST2, V100HOST1);
+        Set<Interface> expectInterfaces = ImmutableSet.of();
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(replyMessage);
+        assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
+        assertTrue(replyMessage.dropped());
+
+        TestMessageContext requestMessage = makeBroadcastRequestContext(V300HOST2);
+        ((TestNeighbourService) vplsNeighbourHandler.neighbourService).sendNeighourMessage(requestMessage);
+        assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
+        assertTrue(requestMessage.dropped());
     }
 
-    private Host makeHost(MacAddress mac, VlanId vlan, ConnectPoint cp) {
-        return new DefaultHost(PID,
-                               HostId.hostId(mac, vlan),
-                               mac,
-                               vlan,
-                               new HostLocation(cp, 0),
-                               Sets.newHashSet());
-    }
-
+    /**
+     * Generates broadcast request message context by given source host.
+     *
+     * @param host the source host
+     * @return the request message context
+     */
     private TestMessageContext makeBroadcastRequestContext(Host host) {
         return new TestMessageContext(host.location(),
                                       host.mac(),
@@ -435,6 +356,13 @@
                                       NeighbourMessageType.REQUEST);
     }
 
+    /**
+     * Generates reply message context by given source and destination host.
+     *
+     * @param src the source host
+     * @param dst the destination host
+     * @return the reply message context
+     */
     private TestMessageContext makeReplyContext(Host src, Host dst) {
         return new TestMessageContext(src.location(),
                                       src.mac(),
@@ -443,15 +371,16 @@
                                       NeighbourMessageType.REPLY);
     }
 
+    /**
+     * Test message context.
+     */
     private class TestMessageContext implements NeighbourMessageContext {
-
-
         private final NeighbourMessageType type;
         private final MacAddress srcMac;
         private final MacAddress dstMac;
         private final ConnectPoint inPort;
         private final VlanId vlanId;
-
+        private boolean dropped = false;
         public Set<Interface> forwardResults;
 
         /**
@@ -475,8 +404,8 @@
             this.dstMac = dstMac;
             this.vlanId = vlanId;
             this.type = type;
-
             this.forwardResults = Sets.newHashSet();
+            this.dropped = false;
         }
 
         @Override
@@ -518,6 +447,10 @@
         public void forward(ConnectPoint outPort) {
         }
 
+        /**
+         * Records all forward network interface information.
+         * @param outIntf output interface
+         */
         @Override
         public void forward(Interface outIntf) {
             forwardResults.add(outIntf);
@@ -533,6 +466,7 @@
 
         @Override
         public void drop() {
+            this.dropped = true;
         }
 
         @Override
@@ -544,141 +478,16 @@
         public NeighbourProtocol protocol() {
             return null;
         }
-    }
 
-    private class TestVplsConfigService extends VplsConfigServiceAdapter {
-
-        private final SetMultimap<String, Interface> ifacesByVplsName;
-
-        public TestVplsConfigService(SetMultimap<String, Interface> ifacesByVplsName,
-                                     HashMap<String, EncapsulationType> encapByVplsName) {
-            this.ifacesByVplsName = ifacesByVplsName;
-        }
-
-        @Override
-        public void addVpls(String vplsName, Set<String> ifaceNames, String encap) {
-            if (!ifacesByVplsName.containsKey(vplsName)) {
-                ifaceNames.forEach(ifaceName -> {
-                    availableInterfaces.forEach(iface -> {
-                        if (iface.name().equals(ifaceName)) {
-                            ifacesByVplsName.put(vplsName, iface);
-                        }
-                    });
-                });
-            }
-        }
-
-        @Override
-        public void removeVpls(String vplsName) {
-            if (ifacesByVplsName.containsKey(vplsName)) {
-                ifacesByVplsName.removeAll(vplsName);
-            }
-        }
-
-        @Override
-        public void addIface(String vplsName, String ifaceName) {
-            availableInterfaces.forEach(intf -> {
-                if (intf.name().equals(ifaceName)) {
-                    ifacesByVplsName.put(vplsName, intf);
-                }
-            });
-        }
-
-        @Override
-        public void removeIface(String ifaceName) {
-            SetMultimap<String, Interface> toBeRemoved = HashMultimap.create();
-            ifacesByVplsName.entries().forEach(e -> {
-                if (e.getValue().name().equals(ifaceName)) {
-                    toBeRemoved.put(e.getKey(), e.getValue());
-                }
-            });
-            toBeRemoved.entries()
-                    .forEach(e -> ifacesByVplsName.remove(e.getKey(),
-                                                          e.getValue()));
-        }
-
-        @Override
-        public void cleanVplsConfig() {
-            ifacesByVplsName.clear();
-        }
-
-        @Override
-        public Set<Interface> allIfaces() {
-            return ImmutableSet.copyOf(ifacesByVplsName.values());
-        }
-
-        @Override
-        public Set<Interface> ifaces(String name) {
-            return ifacesByVplsName.get(name)
-                    .stream()
-                    .collect(Collectors.toSet());
-        }
-
-        @Override
-        public Set<String> vplsNames() {
-            return ifacesByVplsName.keySet();
-        }
-
-        @Override
-        public SetMultimap<String, Interface> ifacesByVplsName() {
-            return ImmutableSetMultimap.copyOf(ifacesByVplsName);
-        }
-
-        @Override
-        public SetMultimap<String, Interface> ifacesByVplsName(VlanId vlan,
-                                                               ConnectPoint connectPoint) {
-            String vplsName =
-                    ifacesByVplsName.entries().stream()
-                            .filter(e -> e.getValue().connectPoint().equals(connectPoint))
-                            .filter(e -> e.getValue().vlan().equals(vlan))
-                            .map(Map.Entry::getKey)
-                            .findFirst()
-                            .orElse(null);
-            SetMultimap<String, Interface> result = HashMultimap.create();
-            if (vplsName != null &&
-                    ifacesByVplsName.containsKey(vplsName)) {
-                ifacesByVplsName.get(vplsName)
-                        .forEach(intf -> result.put(vplsName, intf));
-                return result;
-            }
-            return null;
+        public boolean dropped() {
+            return dropped;
         }
     }
 
-    class TestHostService extends HostServiceAdapter {
-        @Override
-        public Set<Host> getHostsByMac(MacAddress mac) {
-            return availableHosts.stream()
-                    .filter(host -> host.mac().equals(mac))
-                    .collect(Collectors.toSet());
-        }
-
-        @Override
-        public Iterable<Host> getHosts() {
-            return availableHosts;
-        }
-
-        @Override
-        public Set<Host> getHostsByVlan(VlanId vlanId) {
-            return availableHosts.stream()
-                    .filter(host -> host.vlan().equals(vlanId))
-                    .collect(Collectors.toSet());
-        }
-
-        @Override
-        public int getHostCount() {
-            return availableHosts.size();
-        }
-
-        @Override
-        public Host getHost(HostId hostId) {
-            return availableHosts.stream()
-                    .filter(host -> host.id().equals(hostId))
-                    .findFirst()
-                    .orElse(null);
-        }
-    }
-
+    /**
+     * Test neighbour service; records all registrations between neighbour
+     * message handler and interfaces.
+     */
     private class TestNeighbourService implements NeighbourResolutionService {
         private SetMultimap<ConnectPoint, NeighbourHandlerRegistration> handlerRegs;
 
@@ -732,6 +541,26 @@
             return handlerRegs.asMap();
         }
 
+        /**
+         * Sends neighbour message context to all handler which related to the
+         * context.
+         *
+         * @param context the neighbour message context
+         */
+        public void sendNeighourMessage(NeighbourMessageContext context) {
+            ConnectPoint connectPoint = context.inPort();
+            VlanId vlanId = context.vlan();
+            Collection<NeighbourHandlerRegistration> registrations = handlerRegs.get(connectPoint);
+            registrations.forEach(reg -> {
+                if (reg.intf().vlan().equals(vlanId)) {
+                    reg.handler().handleMessage(context, hostService);
+                }
+            });
+        }
+
+        /**
+         * Test handler registration.
+         */
         private class HandlerRegistration implements NeighbourHandlerRegistration {
             private final Interface intf;
             private final NeighbourMessageHandler handler;
@@ -767,65 +596,4 @@
             }
         }
     }
-
-    class TestInterfaceService implements InterfaceService {
-
-        @Override
-        public void addListener(InterfaceListener listener) {
-        }
-
-        @Override
-        public void removeListener(InterfaceListener listener) {
-        }
-
-        @Override
-        public Set<Interface> getInterfaces() {
-            return availableInterfaces;
-        }
-
-        @Override
-        public Interface getInterfaceByName(ConnectPoint connectPoint,
-                                            String name) {
-            return availableInterfaces.stream()
-                    .filter(intf -> intf.name().equals(name))
-                    .findFirst()
-                    .orElse(null);
-        }
-
-        @Override
-        public Set<Interface> getInterfacesByPort(ConnectPoint port) {
-            return availableInterfaces.stream()
-                    .filter(intf -> intf.connectPoint().equals(port))
-                    .collect(Collectors.toSet());
-        }
-
-        @Override
-        public Set<Interface> getInterfacesByIp(IpAddress ip) {
-            return availableInterfaces.stream()
-                    .filter(intf -> intf.ipAddressesList().contains(ip))
-                    .collect(Collectors.toSet());
-        }
-
-        @Override
-        public Set<Interface> getInterfacesByVlan(VlanId vlan) {
-            return availableInterfaces.stream()
-                    .filter(intf -> intf.vlan().equals(vlan))
-                    .collect(Collectors.toSet());
-        }
-
-        @Override
-        public Interface getMatchingInterface(IpAddress ip) {
-            return availableInterfaces.stream()
-                    .filter(intf -> intf.ipAddressesList().contains(ip))
-                    .findFirst()
-                    .orElse(null);
-        }
-
-        @Override
-        public Set<Interface> getMatchingInterfaces(IpAddress ip) {
-            return availableInterfaces.stream()
-                    .filter(intf -> intf.ipAddressesList().contains(ip))
-                    .collect(Collectors.toSet());
-        }
-    }
 }
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsOperationManagerTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsOperationManagerTest.java
new file mode 100644
index 0000000..36ffda9
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/VplsOperationManagerTest.java
@@ -0,0 +1,543 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vpls;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.cluster.ClusterServiceAdapter;
+import org.onosproject.cluster.Leader;
+import org.onosproject.cluster.Leadership;
+import org.onosproject.cluster.LeadershipEvent;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.Host;
+import org.onosproject.net.host.HostServiceAdapter;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentEvent;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.api.VplsOperation;
+
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.Set;
+
+import static org.junit.Assert.*;
+import static org.onlab.junit.TestTools.assertAfter;
+import static org.onlab.junit.TestTools.delay;
+
+/**
+ * Tests for {@link VplsOperationManager}.
+ */
+public class VplsOperationManagerTest extends VplsTest {
+
+    VplsOperationManager vplsOperationManager;
+    private static final int OPERATION_DELAY = 1000;
+    private static final int OPERATION_DURATION = 1500;
+
+    @Before
+    public void setup() {
+        if (idGenerator == null) {
+            idGenerator = new TestIdGenerator();
+        }
+        Intent.unbindIdGenerator(idGenerator);
+        Intent.bindIdGenerator(idGenerator);
+        vplsOperationManager = new VplsOperationManager();
+        vplsOperationManager.coreService = new TestCoreService();
+        vplsOperationManager.intentService = new TestIntentService();
+        vplsOperationManager.leadershipService = new TestLeadershipService();
+        vplsOperationManager.clusterService = new ClusterServiceAdapter();
+        vplsOperationManager.hostService = new TestHostService();
+        vplsOperationManager.vplsStore = new TestVplsStore();
+        vplsOperationManager.isLeader = true;
+        vplsOperationManager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        vplsOperationManager.deactivate();
+    }
+
+    /**
+     * Sends leadership event to the manager and checks if the manager is
+     * leader or not.
+     */
+    @Test
+    public void testLeadershipEvent() {
+        vplsOperationManager.isLeader = false;
+        vplsOperationManager.localNodeId = NODE_ID_1;
+
+        // leader changed to self
+        Leader leader = new Leader(NODE_ID_1, 0, 0);
+        Leadership leadership = new Leadership(APP_NAME, leader, ImmutableList.of());
+        LeadershipEvent event = new LeadershipEvent(LeadershipEvent.Type.LEADER_CHANGED, leadership);
+        ((TestLeadershipService) vplsOperationManager.leadershipService).sendEvent(event);
+        assertTrue(vplsOperationManager.isLeader);
+
+        // leader changed to other
+        leader = new Leader(NODE_ID_2, 0, 0);
+        leadership = new Leadership(APP_NAME, leader, ImmutableList.of());
+        event = new LeadershipEvent(LeadershipEvent.Type.LEADER_CHANGED, leadership);
+        ((TestLeadershipService) vplsOperationManager.leadershipService).sendEvent(event);
+        assertFalse(vplsOperationManager.isLeader);
+    }
+
+    /**
+     * Submits an ADD operation to the operation manager; check if the VPLS
+     * store changed after a period.
+     */
+    @Test
+    public void testSubmitAddOperation() {
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+
+        VplsOperation vplsOperation = VplsOperation.of(vplsData,
+                                                       VplsOperation.Operation.ADD);
+
+        vplsOperationManager.submit(vplsOperation);
+        assertAfter(OPERATION_DELAY, OPERATION_DURATION, () -> {
+            Collection<VplsData> vplss = vplsOperationManager.vplsStore.getAllVpls();
+            assertEquals(1, vplss.size());
+            VplsData result = vplss.iterator().next();
+
+            assertEquals(vplsData, result);
+            assertEquals(VplsData.VplsState.ADDED, result.state());
+
+            Set<Intent> intentsInstalled =
+                    Sets.newHashSet(vplsOperationManager.intentService.getIntents());
+            assertEquals(4, intentsInstalled.size());
+        });
+    }
+
+    /**
+     * Submits an ADD operation to the operation manager; check the VPLS state
+     * from store if Intent install failed.
+     */
+    @Test
+    public void testSubmitAddOperationFail() {
+        vplsOperationManager.intentService = new AlwaysFailureIntentService();
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+
+        VplsOperation vplsOperation = VplsOperation.of(vplsData,
+                                                       VplsOperation.Operation.ADD);
+        vplsOperationManager.submit(vplsOperation);
+        assertAfter(OPERATION_DELAY, OPERATION_DURATION, () -> {
+            Collection<VplsData> vplss = vplsOperationManager.vplsStore.getAllVpls();
+            assertEquals(1, vplss.size());
+            VplsData result = vplss.iterator().next();
+
+            assertEquals(vplsData, result);
+            assertEquals(VplsData.VplsState.FAILED, result.state());
+        });
+    }
+
+    /**
+     * Submits an REMOVE operation to the operation manager; check if the VPLS
+     * store changed after a period.
+     */
+    @Test
+    public void testSubmitRemoveOperation() {
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+        vplsData.state(VplsData.VplsState.REMOVING);
+
+        VplsOperation vplsOperation = VplsOperation.of(vplsData,
+                                                       VplsOperation.Operation.REMOVE);
+
+        vplsOperationManager.submit(vplsOperation);
+
+        assertAfter(OPERATION_DELAY, OPERATION_DURATION, () -> {
+            Collection<VplsData> vplss = vplsOperationManager.vplsStore.getAllVpls();
+            assertEquals(0, vplss.size());
+        });
+    }
+
+    /**
+     * Submits an UPDATE operation with VPLS interface update to the operation manager; check if the VPLS
+     * store changed after a period.
+     */
+    @Test
+    public void testSubmitUpdateOperation() {
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1));
+        vplsData.state(VplsData.VplsState.ADDED);
+        vplsOperationManager.vplsStore.addVpls(vplsData);
+
+        vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+        vplsData.state(VplsData.VplsState.UPDATING);
+
+        VplsOperation vplsOperation = VplsOperation.of(vplsData,
+                                                       VplsOperation.Operation.UPDATE);
+
+        vplsOperationManager.submit(vplsOperation);
+
+        assertAfter(OPERATION_DELAY, OPERATION_DURATION, () -> {
+            Collection<VplsData> vplss = vplsOperationManager.vplsStore.getAllVpls();
+            VplsData result = vplss.iterator().next();
+            VplsData expected = VplsData.of(VPLS1, EncapsulationType.VLAN);
+            expected.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+            expected.state(VplsData.VplsState.ADDED);
+
+            assertEquals(1, vplss.size());
+            assertEquals(expected, result);
+
+            Set<Intent> intentsInstalled =
+                    Sets.newHashSet(vplsOperationManager.intentService.getIntents());
+            assertEquals(4, intentsInstalled.size());
+        });
+    }
+
+    /**
+     * Submits an UPDATE operation with VPLS host update to the operation manager; check if the VPLS
+     * store changed after a period.
+     */
+    @Test
+    public void testSubmitUpdateHostOperation() {
+        vplsOperationManager.hostService = new EmptyHostService();
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+
+        VplsOperation vplsOperation = VplsOperation.of(vplsData,
+                                                       VplsOperation.Operation.ADD);
+        vplsOperationManager.submit(vplsOperation);
+        delay(1000);
+        vplsOperationManager.hostService = new TestHostService();
+
+        vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+        vplsData.state(VplsData.VplsState.UPDATING);
+
+        vplsOperation = VplsOperation.of(vplsData,
+                                                       VplsOperation.Operation.UPDATE);
+
+        vplsOperationManager.submit(vplsOperation);
+
+        assertAfter(OPERATION_DELAY, OPERATION_DURATION, () -> {
+            Collection<VplsData> vplss = vplsOperationManager.vplsStore.getAllVpls();
+            VplsData result = vplss.iterator().next();
+            VplsData expected = VplsData.of(VPLS1);
+            expected.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+            expected.state(VplsData.VplsState.ADDED);
+            assertEquals(1, vplss.size());
+            assertEquals(expected, result);
+
+            assertEquals(4, vplsOperationManager.intentService.getIntentCount());
+        });
+    }
+
+    /**
+     * Submits same operation twice to the manager; the manager should ignore
+     * duplicated operation.
+     */
+    @Test
+    public void testDuplicateOperationInQueue() {
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+
+        VplsOperation vplsOperation = VplsOperation.of(vplsData,
+                                                       VplsOperation.Operation.ADD);
+
+        vplsOperationManager.submit(vplsOperation);
+        vplsOperationManager.submit(vplsOperation);
+        Deque<VplsOperation> opQueue = vplsOperationManager.pendingVplsOperations.get(VPLS1);
+        assertEquals(1, opQueue.size());
+
+        // Clear operation queue before scheduler process it
+        opQueue.clear();
+    }
+
+    /**
+     * Submits REMOVE operation after submits ADD operation; there should be no
+     * pending or running operation in the manager.
+     */
+    @Test
+    public void testDoNothingOperation() {
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+
+        VplsOperation vplsOperation = VplsOperation.of(vplsData,
+                                                       VplsOperation.Operation.ADD);
+        vplsOperationManager.submit(vplsOperation);
+        vplsOperation = VplsOperation.of(vplsData,
+                                         VplsOperation.Operation.REMOVE);
+        vplsOperationManager.submit(vplsOperation);
+        assertAfter(OPERATION_DELAY, OPERATION_DURATION, () -> {
+            assertEquals(0, vplsOperationManager.pendingVplsOperations.size());
+
+            // Should not have any running operation
+            assertEquals(0, vplsOperationManager.runningOperations.size());
+        });
+    }
+
+    /**
+     * Optimize operations which don't need to be optimized.
+     */
+    @Test
+    public void testOptimizeOperationsNoOptimize() {
+        // empty queue
+        Deque<VplsOperation> operations = new ArrayDeque<>();
+        VplsOperation vplsOperation =
+                VplsOperationManager.getOptimizedVplsOperation(operations);
+        assertNull(vplsOperation);
+
+        // one operation
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsOperation = VplsOperation.of(vplsData, VplsOperation.Operation.ADD);
+        operations.add(vplsOperation);
+        VplsOperation result =
+                VplsOperationManager.getOptimizedVplsOperation(operations);
+        assertEquals(vplsOperation, result);
+
+    }
+
+    /**
+     * Optimize operations with first is ADD operation and last is also ADD
+     * operation.
+     */
+    @Test
+    public void testOptimizeOperationsAToA() {
+        Deque<VplsOperation> operations = new ArrayDeque<>();
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1));
+        VplsOperation vplsOperation = VplsOperation.of(vplsData,
+                                                       VplsOperation.Operation.ADD);
+        operations.add(vplsOperation);
+        vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+        vplsOperation = VplsOperation.of(vplsData,
+                                         VplsOperation.Operation.ADD);
+        operations.add(vplsOperation);
+        vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+        assertEquals(VplsOperation.of(vplsData, VplsOperation.Operation.ADD), vplsOperation);
+    }
+
+    /**
+     * Optimize operations with first is ADD operation and last is REMOVE
+     * operation.
+     */
+    @Test
+    public void testOptimizeOperationsAToR() {
+        Deque<VplsOperation> operations = new ArrayDeque<>();
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1));
+        VplsOperation vplsOperation = VplsOperation.of(vplsData,
+                                                       VplsOperation.Operation.ADD);
+        operations.add(vplsOperation);
+        vplsOperation = VplsOperation.of(vplsData,
+                                         VplsOperation.Operation.REMOVE);
+        operations.add(vplsOperation);
+        vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+        assertNull(vplsOperation);
+    }
+
+    /**
+     * Optimize operations with first is ADD operation and last is UPDATE
+     * operation.
+     */
+    @Test
+    public void testOptimizeOperationsAToU() {
+        Deque<VplsOperation> operations = new ArrayDeque<>();
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1));
+        VplsOperation vplsOperation = VplsOperation.of(vplsData,
+                                                       VplsOperation.Operation.ADD);
+        operations.add(vplsOperation);
+        vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+        vplsOperation = VplsOperation.of(vplsData,
+                                         VplsOperation.Operation.UPDATE);
+        operations.add(vplsOperation);
+        vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+        assertEquals(VplsOperation.of(vplsData, VplsOperation.Operation.ADD), vplsOperation);
+    }
+
+    /**
+     * Optimize operations with first is REMOVE operation and last is ADD
+     * operation.
+     */
+    @Test
+    public void testOptimizeOperationsRToA() {
+        Deque<VplsOperation> operations = new ArrayDeque<>();
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1));
+        VplsOperation vplsOperation = VplsOperation.of(vplsData,
+                                                       VplsOperation.Operation.REMOVE);
+        operations.add(vplsOperation);
+        vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+        vplsOperation = VplsOperation.of(vplsData,
+                                         VplsOperation.Operation.ADD);
+        operations.add(vplsOperation);
+        vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+        assertEquals(VplsOperation.of(vplsData, VplsOperation.Operation.UPDATE), vplsOperation);
+    }
+
+    /**
+     * Optimize operations with first is REMOVE operation and last is also
+     * REMOVE operation.
+     */
+    @Test
+    public void testOptimizeOperationsRToR() {
+        Deque<VplsOperation> operations = new ArrayDeque<>();
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1));
+        VplsOperation vplsOperation = VplsOperation.of(vplsData,
+                                                       VplsOperation.Operation.REMOVE);
+        operations.add(vplsOperation);
+        vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+        vplsOperation = VplsOperation.of(vplsData,
+                                         VplsOperation.Operation.REMOVE);
+        operations.add(vplsOperation);
+        vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+        vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1));
+        assertEquals(VplsOperation.of(vplsData, VplsOperation.Operation.REMOVE), vplsOperation);
+    }
+
+    /**
+     * Optimize operations with first is REMOVE operation and last is UPDATE
+     * operation.
+     */
+    @Test
+    public void testOptimizeOperationsRToU() {
+        Deque<VplsOperation> operations = new ArrayDeque<>();
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1));
+        VplsOperation vplsOperation = VplsOperation.of(vplsData,
+                                                       VplsOperation.Operation.REMOVE);
+        operations.add(vplsOperation);
+        vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+        vplsOperation = VplsOperation.of(vplsData,
+                                         VplsOperation.Operation.UPDATE);
+        operations.add(vplsOperation);
+        vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+        assertEquals(VplsOperation.of(vplsData, VplsOperation.Operation.UPDATE), vplsOperation);
+    }
+
+    /**
+     * Optimize operations with first is UPDATE operation and last is ADD
+     * operation.
+     */
+    @Test
+    public void testOptimizeOperationsUToA() {
+        Deque<VplsOperation> operations = new ArrayDeque<>();
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1));
+        VplsOperation vplsOperation = VplsOperation.of(vplsData,
+                                                       VplsOperation.Operation.UPDATE);
+        operations.add(vplsOperation);
+        vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+        vplsOperation = VplsOperation.of(vplsData,
+                                         VplsOperation.Operation.ADD);
+        operations.add(vplsOperation);
+        vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+        assertEquals(VplsOperation.of(vplsData, VplsOperation.Operation.UPDATE), vplsOperation);
+    }
+
+    /**
+     * Optimize operations with first is UPDATE operation and last is REMOVE
+     * operation.
+     */
+    @Test
+    public void testOptimizeOperationsUToR() {
+        Deque<VplsOperation> operations = new ArrayDeque<>();
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1));
+        VplsOperation vplsOperation = VplsOperation.of(vplsData,
+                                                       VplsOperation.Operation.UPDATE);
+        operations.add(vplsOperation);
+        vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+        vplsOperation = VplsOperation.of(vplsData,
+                                         VplsOperation.Operation.REMOVE);
+        operations.add(vplsOperation);
+        vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+        assertEquals(VplsOperation.of(vplsData, VplsOperation.Operation.REMOVE), vplsOperation);
+    }
+
+    /**
+     * Optimize operations with first is UPDATE operation and last is also
+     * UPDATE operation.
+     */
+    @Test
+    public void testOptimizeOperationsUToU() {
+        Deque<VplsOperation> operations = new ArrayDeque<>();
+        VplsData vplsData = VplsData.of(VPLS1);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1));
+        VplsOperation vplsOperation = VplsOperation.of(vplsData,
+                                                       VplsOperation.Operation.UPDATE);
+        operations.add(vplsOperation);
+        vplsData = VplsData.of(VPLS1, EncapsulationType.VLAN);
+        vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+        vplsOperation = VplsOperation.of(vplsData,
+                                         VplsOperation.Operation.UPDATE);
+        operations.add(vplsOperation);
+        vplsOperation = VplsOperationManager.getOptimizedVplsOperation(operations);
+        assertEquals(VplsOperation.of(vplsData, VplsOperation.Operation.UPDATE), vplsOperation);
+    }
+
+    /**
+     * Test Intent service which always fail when submit or withdraw Intents.
+     */
+    class AlwaysFailureIntentService extends TestIntentService {
+        @Override
+        public void submit(Intent intent) {
+            intents.add(new IntentData(intent, IntentState.FAILED, new WallClockTimestamp()));
+            if (listener != null) {
+                IntentEvent event = IntentEvent.getEvent(IntentState.FAILED, intent).get();
+                listener.event(event);
+            }
+        }
+
+        @Override
+        public void withdraw(Intent intent) {
+            intents.forEach(intentData -> {
+                if (intentData.intent().key().equals(intent.key())) {
+                    intentData.setState(IntentState.FAILED);
+
+                    if (listener != null) {
+                        IntentEvent event = IntentEvent.getEvent(IntentState.FAILED, intent).get();
+                        listener.event(event);
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * Test host service without any hosts.
+     */
+    class EmptyHostService extends HostServiceAdapter {
+        @Override
+        public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
+            return ImmutableSet.of();
+        }
+    }
+
+}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java
index 6dfcea5..716b331 100644
--- a/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Laboratory
+ * Copyright 2017-present Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,704 +13,213 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.onosproject.vpls;
 
-import com.google.common.collect.HashMultimap;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import com.google.common.collect.SetMultimap;
 import com.google.common.collect.Sets;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
 import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 import org.onosproject.TestApplicationId;
-import org.onosproject.app.ApplicationService;
+import org.onosproject.cluster.LeadershipEvent;
+import org.onosproject.cluster.LeadershipEventListener;
+import org.onosproject.cluster.LeadershipServiceAdapter;
+import org.onosproject.cluster.NodeId;
 import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
+import org.onosproject.core.CoreServiceAdapter;
 import org.onosproject.core.IdGenerator;
 import org.onosproject.incubator.net.intf.Interface;
 import org.onosproject.incubator.net.intf.InterfaceListener;
 import org.onosproject.incubator.net.intf.InterfaceService;
-import org.onosproject.intentsync.IntentSynchronizationService;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultHost;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.EncapsulationType;
-import org.onosproject.net.FilteredConnectPoint;
 import org.onosproject.net.Host;
 import org.onosproject.net.HostId;
 import org.onosproject.net.HostLocation;
 import org.onosproject.net.PortNumber;
-import org.onosproject.net.config.NetworkConfigService;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.criteria.Criterion;
-import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.ConfigApplyDelegate;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigServiceAdapter;
 import org.onosproject.net.host.HostEvent;
 import org.onosproject.net.host.HostListener;
-import org.onosproject.net.host.HostService;
 import org.onosproject.net.host.HostServiceAdapter;
 import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentEvent;
+import org.onosproject.net.intent.IntentListener;
 import org.onosproject.net.intent.IntentServiceAdapter;
-import org.onosproject.net.intent.IntentUtils;
-import org.onosproject.net.intent.Key;
-import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.net.intent.SinglePointToMultiPointIntent;
+import org.onosproject.net.intent.IntentState;
 import org.onosproject.net.provider.ProviderId;
-import org.onosproject.vpls.config.VplsConfigService;
+import org.onosproject.store.StoreDelegate;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.onosproject.vpls.api.Vpls;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.config.VplsAppConfig;
+import org.onosproject.vpls.config.VplsAppConfigTest;
+import org.onosproject.vpls.config.VplsConfig;
+import org.onosproject.vpls.store.VplsStoreAdapter;
+import org.onosproject.vpls.store.VplsStoreEvent;
 
+import java.io.IOException;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.stream.Collectors;
 
-import static java.lang.String.format;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.replay;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.onosproject.net.EncapsulationType.NONE;
-import static org.onosproject.net.EncapsulationType.VLAN;
-import static org.onosproject.net.EncapsulationType.valueOf;
-import static org.onosproject.vpls.IntentInstaller.PARTIAL_FAILURE_CONSTRAINT;
-import static org.onosproject.vpls.IntentInstaller.PREFIX_BROADCAST;
-import static org.onosproject.vpls.IntentInstaller.PREFIX_UNICAST;
-import static org.onosproject.vpls.IntentInstaller.setEncap;
-
 /**
- * Tests for the {@link Vpls} class.
+ * Class provides data for VPLS testing.
  */
-public class VplsTest {
-    private static final String APP_NAME = "org.onosproject.vpls";
-    private static final ApplicationId APPID = TestApplicationId.create(APP_NAME);
-    private static final String DASH = "-";
-    private static final int PRIORITY_OFFSET = 1000;
-    private static final String VPLS1 = "vpls1";
-    private static final String VPLS2 = "vpls2";
-    private static final String VPLS3 = "vpls3";
-    private static final String VPLS4 = "vpls4";
+public abstract class VplsTest {
+    protected static final String APP_NAME = "org.onosproject.vpls";
+    protected static final ApplicationId APPID = TestApplicationId.create(APP_NAME);
+    protected static final String DASH = "-";
+    protected static final int PRIORITY_OFFSET = 1000;
+    protected static final String VPLS1 = "vpls1";
+    protected static final String VPLS2 = "vpls2";
+    protected static final String VPLS3 = "vpls3";
+    protected static final String VPLS4 = "vpls4";
 
-    private static final PortNumber P1 = PortNumber.portNumber(1);
-    private static final PortNumber P2 = PortNumber.portNumber(2);
+    protected static final PortNumber P1 = PortNumber.portNumber(1);
+    protected static final PortNumber P2 = PortNumber.portNumber(2);
 
-    private static final DeviceId DID1 = getDeviceId(1);
-    private static final DeviceId DID2 = getDeviceId(2);
-    private static final DeviceId DID3 = getDeviceId(3);
-    private static final DeviceId DID4 = getDeviceId(4);
-    private static final DeviceId DID5 = getDeviceId(5);
-    private static final DeviceId DID6 = getDeviceId(6);
+    protected static final DeviceId DID1 = getDeviceId(1);
+    protected static final DeviceId DID2 = getDeviceId(2);
+    protected static final DeviceId DID3 = getDeviceId(3);
+    protected static final DeviceId DID4 = getDeviceId(4);
+    protected static final DeviceId DID5 = getDeviceId(5);
+    protected static final DeviceId DID6 = getDeviceId(6);
 
-    private static final ConnectPoint CP1 = new ConnectPoint(DID1, P1);
-    private static final ConnectPoint CP2 = new ConnectPoint(DID2, P1);
-    private static final ConnectPoint CP3 = new ConnectPoint(DID3, P1);
-    private static final ConnectPoint CP4 = new ConnectPoint(DID4, P1);
-    private static final ConnectPoint CP5 = new ConnectPoint(DID5, P1);
-    private static final ConnectPoint CP6 = new ConnectPoint(DID6, P1);
-    private static final ConnectPoint CP7 = new ConnectPoint(DID4, P2);
-    private static final ConnectPoint CP8 = new ConnectPoint(DID3, P2);
-    private static final ConnectPoint CP9 = new ConnectPoint(DID5, P1);
-    private static final ConnectPoint CP10 = new ConnectPoint(DID5, P2);
+    protected static final ConnectPoint CP1 = new ConnectPoint(DID1, P1);
+    protected static final ConnectPoint CP2 = new ConnectPoint(DID2, P1);
+    protected static final ConnectPoint CP3 = new ConnectPoint(DID3, P1);
+    protected static final ConnectPoint CP4 = new ConnectPoint(DID4, P1);
+    protected static final ConnectPoint CP5 = new ConnectPoint(DID5, P1);
+    protected static final ConnectPoint CP6 = new ConnectPoint(DID6, P1);
+    protected static final ConnectPoint CP7 = new ConnectPoint(DID4, P2);
+    protected static final ConnectPoint CP8 = new ConnectPoint(DID3, P2);
+    protected static final ConnectPoint CP9 = new ConnectPoint(DID5, P1);
+    protected static final ConnectPoint CP10 = new ConnectPoint(DID5, P2);
 
-    private static final VlanId VLAN100 = VlanId.vlanId((short) 100);
-    private static final VlanId VLAN200 = VlanId.vlanId((short) 200);
-    private static final VlanId VLAN300 = VlanId.vlanId((short) 300);
-    private static final VlanId VLAN400 = VlanId.vlanId((short) 400);
-    private static final VlanId VLAN_NONE = VlanId.NONE;
+    protected static final VlanId VLAN100 = VlanId.vlanId((short) 100);
+    protected static final VlanId VLAN200 = VlanId.vlanId((short) 200);
+    protected static final VlanId VLAN300 = VlanId.vlanId((short) 300);
+    protected static final VlanId VLAN400 = VlanId.vlanId((short) 400);
+    protected static final VlanId VLAN_NONE = VlanId.NONE;
 
-    private static final MacAddress MAC1 = getMac(1);
-    private static final MacAddress MAC2 = getMac(2);
-    private static final MacAddress MAC3 = getMac(3);
-    private static final MacAddress MAC4 = getMac(4);
-    private static final MacAddress MAC5 = getMac(5);
-    private static final MacAddress MAC6 = getMac(6);
-    private static final MacAddress MAC7 = getMac(7);
-    private static final MacAddress MAC8 = getMac(8);
-    private static final MacAddress MAC9 = getMac(9);
-    private static final MacAddress MAC10 = getMac(10);
-    private static final MacAddress MAC11 = getMac(11);
+    protected static final MacAddress MAC1 = getMac(1);
+    protected static final MacAddress MAC2 = getMac(2);
+    protected static final MacAddress MAC3 = getMac(3);
+    protected static final MacAddress MAC4 = getMac(4);
+    protected static final MacAddress MAC5 = getMac(5);
+    protected static final MacAddress MAC6 = getMac(6);
+    protected static final MacAddress MAC7 = getMac(7);
+    protected static final MacAddress MAC8 = getMac(8);
+    protected static final MacAddress MAC9 = getMac(9);
+    protected static final MacAddress MAC10 = getMac(10);
+    protected static final MacAddress MAC11 = getMac(11);
 
-    private static final Ip4Address IP1 = Ip4Address.valueOf("192.168.1.1");
-    private static final Ip4Address IP2 = Ip4Address.valueOf("192.168.1.2");
+    protected static final Ip4Address IP1 = Ip4Address.valueOf("192.168.1.1");
+    protected static final Ip4Address IP2 = Ip4Address.valueOf("192.168.1.2");
 
-    private static final HostId HID1 = HostId.hostId(MAC1, VLAN100);
-    private static final HostId HID2 = HostId.hostId(MAC2, VLAN100);
-    private static final HostId HID3 = HostId.hostId(MAC3, VLAN200);
-    private static final HostId HID4 = HostId.hostId(MAC4, VLAN200);
-    private static final HostId HID5 = HostId.hostId(MAC5, VLAN300);
-    private static final HostId HID6 = HostId.hostId(MAC6, VLAN300);
-    private static final HostId HID7 = HostId.hostId(MAC7, VLAN300);
-    private static final HostId HID8 = HostId.hostId(MAC8, VLAN400);
-    private static final HostId HID9 = HostId.hostId(MAC9);
-    private static final HostId HID10 = HostId.hostId(MAC10);
-    private static final HostId HID11 = HostId.hostId(MAC11);
+    protected static final HostId HID1 = HostId.hostId(MAC1, VLAN100);
+    protected static final HostId HID2 = HostId.hostId(MAC2, VLAN100);
+    protected static final HostId HID3 = HostId.hostId(MAC3, VLAN200);
+    protected static final HostId HID4 = HostId.hostId(MAC4, VLAN200);
+    protected static final HostId HID5 = HostId.hostId(MAC5, VLAN300);
+    protected static final HostId HID6 = HostId.hostId(MAC6, VLAN300);
+    protected static final HostId HID7 = HostId.hostId(MAC7, VLAN300);
+    protected static final HostId HID8 = HostId.hostId(MAC8, VLAN400);
+    protected static final HostId HID9 = HostId.hostId(MAC9);
+    protected static final HostId HID10 = HostId.hostId(MAC10);
+    protected static final HostId HID11 = HostId.hostId(MAC11);
 
-    private static final ProviderId PID = new ProviderId("of", "foo");
+    protected static final ProviderId PID = new ProviderId("of", "foo");
 
-    private static IdGenerator idGenerator;
+    protected static final NodeId NODE_ID_1 = new NodeId("Node1");
+    protected static final NodeId NODE_ID_2 = new NodeId("Node2");
 
-    private static final Interface V100H1 =
+    protected static IdGenerator idGenerator;
+
+    protected static final Interface V100H1 =
             new Interface("v100h1", CP1, null, null, VLAN100);
-    private static final Interface V100H2 =
+    protected static final Interface V100H2 =
             new Interface("v100h2", CP2, null, null, VLAN100);
-    private static final Interface V200H1 =
+    protected static final Interface V200H1 =
             new Interface("v200h1", CP3, null, null, VLAN200);
-    private static final Interface V200H2 =
+    protected static final Interface V200H2 =
             new Interface("v200h2", CP4, null, null, VLAN200);
-    private static final Interface V300H1 =
+    protected static final Interface V300H1 =
             new Interface("v300h1", CP5, null, null, VLAN300);
-    private static final Interface V300H2 =
+    protected static final Interface V300H2 =
             new Interface("v300h2", CP6, null, null, VLAN300);
-    private static final Interface V400H1 =
+    protected static final Interface V400H1 =
             new Interface("v400h1", CP7, null, null, VLAN400);
 
-    private static final Interface VNONEH1 =
+    protected static final Interface VNONEH1 =
             new Interface("vNoneh1", CP8, null, null, VLAN_NONE);
-    private static final Interface VNONEH2 =
+    protected static final Interface VNONEH2 =
             new Interface("vNoneh2", CP9, null, null, VLAN_NONE);
-    private static final Interface VNONEH3 =
+    protected static final Interface VNONEH3 =
             new Interface("vNoneh3", CP10, null, null, VLAN_NONE);
 
-    private static final Host V100HOST1 =
+    protected static final Host V100HOST1 =
             new DefaultHost(PID, HID1, MAC1, VLAN100,
                             getLocation(1), Collections.singleton(IP1));
-    private static final Host V100HOST2 =
+    protected static final Host V100HOST2 =
             new DefaultHost(PID, HID2, MAC2, VLAN100,
                             getLocation(2), Sets.newHashSet());
-    private static final Host V200HOST1 =
+    protected static final Host V200HOST1 =
             new DefaultHost(PID, HID3, MAC3, VLAN200,
                             getLocation(3), Collections.singleton(IP2));
-    private static final Host V200HOST2 =
+    protected static final Host V200HOST2 =
             new DefaultHost(PID, HID4, MAC4, VLAN200,
                             getLocation(4), Sets.newHashSet());
-    private static final Host V300HOST1 =
+    protected static final Host V300HOST1 =
             new DefaultHost(PID, HID5, MAC5, VLAN300,
                             getLocation(5), Sets.newHashSet());
-    private static final Host V300HOST2 =
+    protected static final Host V300HOST2 =
             new DefaultHost(PID, HID6, MAC6, VLAN300,
                             getLocation(6), Sets.newHashSet());
-    private static final Host V300HOST3 =
+    protected static final Host V300HOST3 =
             new DefaultHost(PID, HID7, MAC7, VLAN300,
                             getLocation(7), Sets.newHashSet());
-    private static final Host V400HOST1 =
+    protected static final Host V400HOST1 =
             new DefaultHost(PID, HID8, MAC8, VLAN400,
                             getLocation(4, 2), Sets.newHashSet());
 
-    private static final Host VNONEHOST1 =
+    protected static final Host VNONEHOST1 =
             new DefaultHost(PID, HID9, MAC9, VlanId.NONE,
                             getLocation(3, 2), Sets.newHashSet());
-    private static final Host VNONEHOST2 =
+    protected static final Host VNONEHOST2 =
             new DefaultHost(PID, HID10, MAC10, VlanId.NONE,
                             getLocation(5, 1), Sets.newHashSet());
-    private static final Host VNONEHOST3 =
+    protected static final Host VNONEHOST3 =
             new DefaultHost(PID, HID11, MAC11, VlanId.NONE,
                             getLocation(5, 2), Sets.newHashSet());
 
-    private static final Set<Interface> AVAILABLE_INTERFACES =
+    protected static final Set<Interface> AVAILABLE_INTERFACES =
             ImmutableSet.of(V100H1, V100H2, V200H1, V200H2, V300H1, V300H2,
-                            V400H1, VNONEH1, VNONEH2);
+                            V400H1, VNONEH1, VNONEH2, VNONEH3);
 
-    private static final Set<Host> AVAILABLE_HOSTS =
+    protected static final Set<Host> AVAILABLE_HOSTS =
             ImmutableSet.of(V100HOST1, V100HOST2, V200HOST1,
                             V200HOST2, V300HOST1, V300HOST2, V300HOST3,
                             VNONEHOST1, VNONEHOST2,
                             V400HOST1, VNONEHOST3);
 
-    private SetMultimap<String, Interface> interfacesByVpls = HashMultimap.create();
-
-    private ApplicationService applicationService;
-    private CoreService coreService;
-    private HostListener hostListener;
-    private NetworkConfigService configService;
-    private Set<Host> hostsAvailable;
-    private HostService hostService;
-    private IntentService intentService;
-    private InterfaceService interfaceService;
-    private VplsConfigService vplsConfigService;
-    private Vpls vpls;
-
-    @Before
-    public void setUp() throws Exception {
-        idGenerator = new TestIdGenerator();
-        Intent.unbindIdGenerator(idGenerator);
-        Intent.bindIdGenerator(idGenerator);
-
-        applicationService = createMock(ApplicationService.class);
-
-        configService = createMock(NetworkConfigService.class);
-
-        coreService = createMock(CoreService.class);
-        expect(coreService.registerApplication(APP_NAME))
-                .andReturn(APPID);
-        replay(coreService);
-
-        hostsAvailable = Sets.newHashSet();
-        hostService = new TestHostService(hostsAvailable);
-
-        intentService = new TestIntentService();
-
-        TestIntentSynchronizer intentSynchronizer =
-                new TestIntentSynchronizer(intentService);
-
-        interfaceService = createMock(InterfaceService.class);
-        interfaceService.addListener(anyObject(InterfaceListener.class));
-        expectLastCall().anyTimes();
-        addIfaceConfig();
-
-        interfacesByVpls.put(VPLS1, V100H1);
-        interfacesByVpls.put(VPLS1, V200H1);
-        interfacesByVpls.put(VPLS1, V300H1);
-        interfacesByVpls.put(VPLS2, V100H2);
-        interfacesByVpls.put(VPLS2, V200H2);
-        interfacesByVpls.put(VPLS2, V300H2);
-        interfacesByVpls.put(VPLS3, VNONEH1);
-        interfacesByVpls.put(VPLS3, VNONEH2);
-        interfacesByVpls.put(VPLS4, V400H1);
-        interfacesByVpls.put(VPLS4, VNONEH3);
-
-        Map<String, EncapsulationType> encapByVpls = new HashMap<>();
-        encapByVpls.put(VPLS1, VLAN);
-        encapByVpls.put(VPLS2, NONE);
-        encapByVpls.put(VPLS3, NONE);
-        encapByVpls.put(VPLS4, NONE);
-
-        vplsConfigService = new TestVplsConfigService(interfacesByVpls, encapByVpls);
-
-        vpls = new Vpls();
-        vpls.applicationService = applicationService;
-        vpls.coreService = coreService;
-        vpls.hostService = hostService;
-        vpls.vplsConfigService = vplsConfigService;
-        vpls.intentService = intentService;
-        vpls.interfaceService = interfaceService;
-        vpls.configService = configService;
-        vpls.intentSynchronizer = intentSynchronizer;
-
-    }
-
-    @After
-    public void tearDown() {
-        Intent.unbindIdGenerator(idGenerator);
-    }
-
-    /**
-     * Creates the interface configuration:
-     *  On devices 1 and 2 is configured an interface on port 1 with vlan 100.
-     *  On device 3 is configured an interface on port 3 with no vlan.
-     *  On devices 3 and 4 is configured an interface on port 1 with vlan 200.
-     *  On device 4 is an interface configured on port 2 with vlan 400.
-     *  On device 5 are configured two interfaces on port 1 and 2 with no vlan.
-     *  On device 5 and 6 is configured an interface on port 1 with vlan 300.
-     */
-    private void addIfaceConfig() {
-        Set<Interface> interfaces = ImmutableSet.copyOf(AVAILABLE_INTERFACES);
-        Set<Interface> vlanOneSet = ImmutableSet.of(V100H1, V100H2);
-        Set<Interface> vlanTwoSet = ImmutableSet.of(V200H1, V200H2);
-        Set<Interface> vlanThreeSet = ImmutableSet.of(VNONEH1, VNONEH2);
-        Set<Interface> vlanFourSet = ImmutableSet.of(V400H1, VNONEH3);
-
-        AVAILABLE_INTERFACES.forEach(intf -> {
-            expect(interfaceService.getInterfacesByPort(intf.connectPoint()))
-                    .andReturn(Sets.newHashSet(intf)).anyTimes();
-        });
-        expect(interfaceService.getInterfacesByVlan(VLAN100))
-                .andReturn(vlanOneSet).anyTimes();
-        expect(interfaceService.getInterfacesByVlan(VLAN200))
-                .andReturn(vlanTwoSet).anyTimes();
-        expect(interfaceService.getInterfacesByVlan(VLAN300))
-                .andReturn(vlanThreeSet).anyTimes();
-        expect(interfaceService.getInterfacesByVlan(VLAN400))
-                .andReturn(vlanFourSet).anyTimes();
-        expect(interfaceService.getInterfacesByVlan(VlanId.NONE))
-                .andReturn(vlanFourSet).anyTimes();
-        expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
-
-        replay(interfaceService);
-    }
-
-    /**
-     * Seven ports are configured with VLANs, while three ports are not. No hosts are
-     * registered by the HostService.
-     *
-     * The first three ports have an interface configured on VPLS 1,
-     * the other three on VPLS 2. Two ports are defined for VPLS 3, while
-     * the two remaining ports are configured on VPLS 4.
-     *
-     * The number of intents expected is 10: three for VPLS 1, three for VPLS 2,
-     * two for VPLS 3, two for VPLS 4. Eight MP2SP intents.
-     * Checks if the number of intents submitted to the intent framework is
-     * equal to the number of intents expected and if all intents are equivalent.
-     */
-    @Test
-    public void activateNoHosts() {
-        vpls.activate();
-
-        List<Intent> expectedIntents = Lists.newArrayList();
-        Set<FilteredConnectPoint> fcPoints;
-
-        fcPoints = buildFCPoints(ImmutableSet.of(V100H1, V200H1, V300H1));
-        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS1, VLAN));
-
-        fcPoints = buildFCPoints(ImmutableSet.of(V100H2, V200H2, V300H2));
-        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS2, NONE));
-
-        fcPoints = buildFCPoints(ImmutableSet.of(VNONEH1, VNONEH2));
-        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS3, NONE));
-
-        fcPoints = buildFCPoints(ImmutableSet.of(V400H1, VNONEH3));
-        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS4, NONE));
-
-        checkIntents(expectedIntents);
-    }
-
-    /**
-     * Ten ports are configured with VLANs and ten hosts are registered by the
-     * HostService.
-     *
-     * The first three ports have an interface configured on VPLS 1,
-     * the other three on VPLS 2, two on VPLS3 and two on VPLS4.
-     *
-     * The number of intents expected is twenty: six
-     * for VPLS 1, six for VPLS 2. four for VPLS 3, four for VPLS 4.
-     * That is ten sp2mp intents, ten mp2sp intents. For VPLS 1
-     * IPs are added to demonstrate this doesn't influence the number of intents
-     * created. Checks if the number of intents submitted to the intent
-     * framework is equal to the number of intents expected and if all intents
-     * are equivalent.
-     */
-    @Test
-    public void tenInterfacesConfiguredHostsPresent() {
-        hostsAvailable.addAll(AVAILABLE_HOSTS);
-
-        vpls.activate();
-
-        List<Intent> expectedIntents = Lists.newArrayList();
-        Set<FilteredConnectPoint> fcPoints;
-        Set<Host> hosts;
-
-        fcPoints = buildFCPoints(ImmutableSet.of(V100H1, V200H1, V300H1));
-        hosts = ImmutableSet.of(V100HOST1, V200HOST1, V300HOST1);
-        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS1, VLAN));
-        expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS1, VLAN));
-
-        fcPoints = buildFCPoints(ImmutableSet.of(V100H2, V200H2, V300H2));
-        hosts = ImmutableSet.of(V100HOST2, V200HOST2, V300HOST2);
-        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS2, NONE));
-        expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS2, NONE));
-
-        fcPoints = buildFCPoints(ImmutableSet.of(VNONEH1, VNONEH2));
-        hosts = ImmutableSet.of(VNONEHOST1, VNONEHOST2);
-        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS3, NONE));
-        expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS3, NONE));
-
-        fcPoints = buildFCPoints(ImmutableSet.of(V400H1, VNONEH3));
-        hosts = ImmutableSet.of(V400HOST1, VNONEHOST3);
-        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS4, NONE));
-        expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS4, NONE));
-
-        checkIntents(expectedIntents);
-    }
-
-    /**
-     * Ten ports are configured; seven have VLANs and three do not.
-     * Initially, no hosts are registered by the HostService.
-     *
-     * The first three ports have an interface configured on
-     * VPLS 1, three have an interface configured on VPLS 2, two have an
-     * interface configured on VPLS 3 and two have an interface configured
-     * on VPLS 4, three have an interface configure. When the
-     * module starts up, three hosts attached to device one, two and three -
-     * port 1, are registered by the HostService and events are sent to the
-     * application. sp2mp intents are created for all interfaces configured and
-     * mp2sp intents are created only for the hosts attached.
-     *
-     * The number of intents expected is seventeen: six for VPLS 1,
-     * three for VPLS 2, four for VPLS3 and four for VPLS4.
-     * Ten sp2mp intents, seven mp2sp intents. IPs are added on the first two
-     * hosts only to demonstrate this doesn't influence the number of intents
-     * created.
-     * An additional host is added on device seven - port 1, to demonstrate that
-     * the application does not generate intents, even if the interface uses the
-     * same VLAN Id of the other interfaces configured for the specifc VPLS.
-     * Checks if the number of intents submitted to the intent framework is equal
-     * to the number of intents expected and if all intents are equivalent.
-     */
-    @Test
-    public void tenInterfacesThreeHostEventsSameVpls() {
-        vpls.activate();
-
-        List<Intent> expectedIntents = Lists.newArrayList();
-        Set<FilteredConnectPoint> fcPoints;
-        Set<Host> hosts;
-
-        hostsAvailable.addAll(Sets.newHashSet(V100HOST1, V200HOST1,
-                                              V300HOST1, V300HOST3,
-                                              VNONEHOST1, VNONEHOST2,
-                                              V400HOST1, VNONEHOST3));
-        hostsAvailable.forEach(host ->
-                                       hostListener.event(new HostEvent(HostEvent.Type.HOST_ADDED, host)));
-
-        fcPoints = buildFCPoints(ImmutableSet.of(V100H1, V200H1, V300H1));
-        hosts = ImmutableSet.of(V100HOST1, V200HOST1, V300HOST1);
-        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS1, VLAN));
-        expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS1, VLAN));
-
-        fcPoints = buildFCPoints(ImmutableSet.of(V100H2, V200H2, V300H2));
-        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS2, NONE));
-
-        fcPoints = buildFCPoints(ImmutableSet.of(VNONEH1, VNONEH2));
-        hosts = ImmutableSet.of(VNONEHOST1, VNONEHOST2);
-        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS3, NONE));
-        expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS3, NONE));
-
-        fcPoints = buildFCPoints(ImmutableSet.of(V400H1, VNONEH3));
-        hosts = ImmutableSet.of(V400HOST1, VNONEHOST3);
-        expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS4, NONE));
-        expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS4, NONE));
-
-        checkIntents(expectedIntents);
-    }
-
-    /**
-     * Generates a list of the expected sp2mp intents for a VPLS.
-     *
-     * @param fcPoints the filtered connect point
-     * @param name the name of the VPLS
-     * @param encap the encapsulation type
-     * @return the list of expected sp2mp intents for the given VPLS
-     */
-    private List<SinglePointToMultiPointIntent>
-    generateVplsBrc(Set<FilteredConnectPoint> fcPoints, String name, EncapsulationType encap) {
-        List<SinglePointToMultiPointIntent> intents = Lists.newArrayList();
-
-        fcPoints.forEach(point -> {
-            Set<FilteredConnectPoint> otherPoints =
-                    fcPoints.stream()
-                            .filter(fcp -> !fcp.equals(point))
-                            .collect(Collectors.toSet());
-
-            Key brckey = buildKey(PREFIX_BROADCAST,
-                                  point.connectPoint(),
-                                  name,
-                                  MacAddress.BROADCAST);
-
-            intents.add(buildBrcIntent(brckey, point, otherPoints, encap));
-        });
-
-        return intents;
-    }
-
-    /**
-     * Generates a list of expected mp2sp intents for a given VPLS.
-     *
-     * @param fcPoints the filtered connect point
-     * @param hosts the hosts
-     * @param name the name of the VPLS
-     * @param encap the encapsulation type
-     * @return the list of expected mp2sp intents for the given VPLS
-     */
-    private List<MultiPointToSinglePointIntent>
-    generateVplsUni(Set<FilteredConnectPoint> fcPoints, Set<Host> hosts,
-                    String name, EncapsulationType encap) {
-        List<MultiPointToSinglePointIntent> intents = Lists.newArrayList();
-
-        hosts.forEach(host -> {
-            FilteredConnectPoint hostPoint = getHostPoint(host, fcPoints);
-
-            Set<FilteredConnectPoint> otherPoints =
-                    fcPoints.stream()
-                            .filter(fcp -> !fcp.equals(hostPoint))
-                            .collect(Collectors.toSet());
-
-            Key uniKey = buildKey(PREFIX_UNICAST,
-                                  host.location(), name, host.mac());
-
-            intents.add(buildUniIntent(uniKey, otherPoints, hostPoint, host, encap));
-        });
-
-        return intents;
-    }
-
-    /**
-     * Checks if the number of intents submitted to the intent framework is equal
-     * to the number of intents expected and if all intents are equivalent.
-     *
-     * @param intents the list of intents expected
-     */
-    private void checkIntents(List<Intent> intents) {
-        assertEquals("The number of intents submitted differs from the number" +
-                             " of intents expected. ",
-                     intents.size(), intentService.getIntentCount());
-
-        for (Intent intentOne : intents) {
-            boolean found = false;
-            for (Intent intentTwo : intentService.getIntents()) {
-                if (intentOne.key().equals(intentTwo.key())) {
-                    found = true;
-                    assertTrue(format("The intent submitted is different from" +
-                                              " the intent expected. %s %s",
-                                      intentOne, intentTwo),
-                               IntentUtils.intentsAreEqual(intentOne, intentTwo));
-                    break;
-                }
-            }
-            assertTrue("The intent submitted is not equal to any of the expected" +
-                               " intents. ", found);
-        }
-    }
-
-    /**
-     * Builds a broadcast intent.
-     *
-     * @param key the key to identify the intent
-     * @param src the ingress connect point
-     * @param dsts the egress connect points
-     * @return the generated single-point to multi-point intent
-     */
-    private SinglePointToMultiPointIntent buildBrcIntent(Key key,
-                                                         FilteredConnectPoint src,
-                                                         Set<FilteredConnectPoint> dsts,
-                                                         EncapsulationType encap) {
-        SinglePointToMultiPointIntent.Builder intentBuilder;
-
-        TrafficSelector selector = DefaultTrafficSelector.builder()
-                .matchEthDst(MacAddress.BROADCAST)
-                .build();
-
-        intentBuilder = SinglePointToMultiPointIntent.builder()
-                .appId(APPID)
-                .key(key)
-                .selector(selector)
-                .filteredIngressPoint(src)
-                .filteredEgressPoints(dsts)
-                .constraints(PARTIAL_FAILURE_CONSTRAINT)
-                .priority(PRIORITY_OFFSET);
-
-        setEncap(intentBuilder, PARTIAL_FAILURE_CONSTRAINT, encap);
-
-        return intentBuilder.build();
-    }
-
-    /**
-     * Builds a unicast intent.
-     *
-     * @param key the key to identify the intent
-     * @param srcs the ingress connect points
-     * @param dst the egress connect point
-     * @param host the destination Host
-     * @return the generated multi-point to single-point intent
-     */
-    private MultiPointToSinglePointIntent buildUniIntent(Key key,
-                                                         Set<FilteredConnectPoint> srcs,
-                                                         FilteredConnectPoint dst,
-                                                         Host host,
-                                                         EncapsulationType encap) {
-        MultiPointToSinglePointIntent.Builder intentBuilder;
-
-        TrafficSelector selector = DefaultTrafficSelector.builder()
-                .matchEthDst(host.mac())
-                .build();
-
-        intentBuilder = MultiPointToSinglePointIntent.builder()
-                .appId(APPID)
-                .key(key)
-                .selector(selector)
-                .filteredIngressPoints(srcs)
-                .filteredEgressPoint(dst)
-                .constraints(PARTIAL_FAILURE_CONSTRAINT)
-                .priority(PRIORITY_OFFSET);
-
-        setEncap(intentBuilder, PARTIAL_FAILURE_CONSTRAINT, encap);
-
-        return intentBuilder.build();
-    }
-
-    /**
-     * Returns the filtered connect point associated to a given host.
-     *
-     * @param host the target host
-     * @param fcps the filtered connected points
-     * @return the filtered connect point associated to the given host; null
-     * otherwise
-     */
-    private FilteredConnectPoint getHostPoint(Host host,
-                                              Set<FilteredConnectPoint> fcps) {
-        return fcps.stream()
-                .filter(fcp -> fcp.connectPoint().equals(host.location()))
-                .filter(fcp -> {
-                    VlanIdCriterion vlanCriterion =
-                            (VlanIdCriterion) fcp.trafficSelector().
-                                    getCriterion(Criterion.Type.VLAN_VID);
-                    return vlanCriterion == null ||
-                            vlanCriterion.vlanId().equals(host.vlan());
-                })
-                .findFirst()
-                .orElse(null);
-    }
-
-    /**
-     * Computes a set of filtered connect points from a list of given interfaces.
-     *
-     * @param interfaces the interfaces to compute
-     * @return the set of filtered connect points
-     */
-    private Set<FilteredConnectPoint> buildFCPoints(Collection<Interface> interfaces) {
-        // Build all filtered connected points in the VPLS
-        return interfaces
-                .stream()
-                .map(intf -> {
-                    TrafficSelector.Builder selectorBuilder =
-                            DefaultTrafficSelector.builder();
-                    if (!intf.vlan().equals(VlanId.NONE)) {
-                        selectorBuilder.matchVlanId(intf.vlan());
-                    }
-                    return new FilteredConnectPoint(intf.connectPoint(),
-                                                    selectorBuilder.build());
-                })
-                .collect(Collectors.toSet());
-    }
-
-    /**
-     * Builds an intent Key either for a single-point to multi-point or
-     * multi-point to single-point intent, based on a prefix that defines
-     * the intent type, the connection point representing the source or the
-     * destination and the VLAN Id representing the VPLS.
-     *
-     * @param prefix the key prefix
-     * @param cPoint the ingress/egress connect point
-     * @param vplsName the VPLS name
-     * @param hostMac the ingress/egress MAC address
-     * @return the key to identify the intent
-     */
-    private Key buildKey(String prefix,
-                         ConnectPoint cPoint,
-                         String vplsName,
-                         MacAddress hostMac) {
-        String keyString = vplsName +
-                DASH +
-                prefix +
-                DASH +
-                cPoint.deviceId() +
-                DASH +
-                cPoint.port() +
-                DASH +
-                hostMac;
-
-        return Key.of(keyString, APPID);
-    }
 
     /**
      * Returns the device Id of the ith device.
@@ -718,38 +227,91 @@
      * @param i the device to get the Id of
      * @return the device Id
      */
-    private static DeviceId getDeviceId(int i) {
+    protected static DeviceId getDeviceId(int i) {
         return DeviceId.deviceId("" + i);
     }
 
-    private static MacAddress getMac(int n) {
+    /**
+     * Generates a mac address by given number.
+     *
+     * @param n the number to generate mac address
+     * @return the mac address
+     */
+    protected static MacAddress getMac(int n) {
         return MacAddress.valueOf(String.format("00:00:00:00:00:%s", n));
     }
 
-    private static HostLocation getLocation(int i) {
+    /**
+     * Generates a host location by given device number.
+     *
+     * @param i the given number
+     * @return the host location
+     */
+    protected static HostLocation getLocation(int i) {
         return new HostLocation(new ConnectPoint(getDeviceId(i), P1), 123L);
     }
 
-    private static HostLocation getLocation(int d, int p) {
+    /**
+     * Generates host location by given device number and port number.
+     *
+     * @param d the device number
+     * @param p the port number
+     * @return the host location
+     */
+    protected static HostLocation getLocation(int d, int p) {
         return new HostLocation(new ConnectPoint(getDeviceId(d),
                                                  PortNumber.portNumber(p)), 123L);
     }
 
     /**
-     * Represents a fake IntentService class that allows to store and retrieve
-     * intents without implementing the IntentService logic.
+     * Test core service; For generate test application ID.
      */
-    private class TestIntentService extends IntentServiceAdapter {
+    public class TestCoreService extends CoreServiceAdapter {
+        @Override
+        public ApplicationId registerApplication(String name) {
+            return TestApplicationId.create(name);
+        }
+    }
 
-        private Map<Key, Intent> intents;
+    /**
+     * Test intent service.
+     * Always install or withdraw success for any Intents.
+     */
+    public class TestIntentService extends IntentServiceAdapter {
+        IntentListener listener;
+        List<IntentData> intents;
 
         public TestIntentService() {
-            intents = Maps.newHashMap();
+            intents = Lists.newArrayList();
         }
 
         @Override
         public void submit(Intent intent) {
-            intents.put(intent.key(), intent);
+            intents.add(new IntentData(intent, IntentState.INSTALLED, new WallClockTimestamp()));
+            if (listener != null) {
+                IntentEvent.getEvent(IntentState.INSTALLED, intent).ifPresent(listener::event);
+
+            }
+        }
+
+        @Override
+        public void withdraw(Intent intent) {
+            intents.forEach(intentData -> {
+                if (intentData.intent().key().equals(intent.key())) {
+                    intentData.setState(IntentState.WITHDRAWN);
+
+                    if (listener != null) {
+                        IntentEvent.getEvent(IntentState.WITHDRAWN, intent).ifPresent(listener::event);
+                    }
+                }
+            });
+        }
+
+        @Override
+        public Iterable<Intent> getIntents() {
+            return intents.stream()
+                    .map(IntentData::intent)
+                    .collect(Collectors.toList());
         }
 
         @Override
@@ -758,52 +320,227 @@
         }
 
         @Override
-        public Iterable<Intent> getIntents() {
-            return intents.values();
+        public void addListener(IntentListener listener) {
+            this.listener = listener;
         }
 
         @Override
-        public Intent getIntent(Key intentKey) {
-            for (Intent intent : intents.values()) {
-                if (intent.key().equals(intentKey)) {
-                    return intent;
-                }
-            }
-            return null;
+        public void removeListener(IntentListener listener) {
+            this.listener = null;
         }
     }
 
     /**
-     * Represents a fake HostService class which allows to add hosts manually
-     * in each test, when needed.
+     * Test leadership service.
      */
-    private class TestHostService extends HostServiceAdapter {
+    public class TestLeadershipService extends LeadershipServiceAdapter {
+        LeadershipEventListener listener;
 
-        private Set<Host> hosts;
-
-        public TestHostService(Set<Host> hosts) {
-            this.hosts = hosts;
+        @Override
+        public void addListener(LeadershipEventListener listener) {
+            this.listener = listener;
         }
 
         @Override
-        public void addListener(HostListener listener) {
-            VplsTest.this.hostListener = listener;
+        public void removeListener(LeadershipEventListener listener) {
+            this.listener = null;
+        }
+
+        /**
+         * Sends the leadership event to the listener.
+         *
+         * @param event the Intent event
+         */
+        public void sendEvent(LeadershipEvent event) {
+            if (listener != null && listener.isRelevant(event)) {
+                listener.event(event);
+            }
         }
 
         @Override
-        public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
-            return hosts.stream()
-                    .filter(h -> h.location().equals(connectPoint))
+        public NodeId getLeader(String path) {
+            return NODE_ID_1;
+        }
+    }
+
+    /**
+     * Test interface service; contains all interfaces which already generated.
+     */
+    public class TestInterfaceService implements InterfaceService {
+
+        @Override
+        public void addListener(InterfaceListener listener) {
+        }
+
+        @Override
+        public void removeListener(InterfaceListener listener) {
+        }
+
+        @Override
+        public Set<Interface> getInterfaces() {
+            return AVAILABLE_INTERFACES;
+        }
+
+        @Override
+        public Interface getInterfaceByName(ConnectPoint connectPoint,
+                                            String name) {
+            return AVAILABLE_INTERFACES.stream()
+                    .filter(intf -> intf.name().equals(name))
+                    .findFirst()
+                    .orElse(null);
+        }
+
+        @Override
+        public Set<Interface> getInterfacesByPort(ConnectPoint port) {
+            return AVAILABLE_INTERFACES.stream()
+                    .filter(intf -> intf.connectPoint().equals(port))
                     .collect(Collectors.toSet());
         }
 
+        @Override
+        public Set<Interface> getInterfacesByIp(IpAddress ip) {
+            return AVAILABLE_INTERFACES.stream()
+                    .filter(intf -> intf.ipAddressesList().contains(ip))
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public Set<Interface> getInterfacesByVlan(VlanId vlan) {
+            return AVAILABLE_INTERFACES.stream()
+                    .filter(intf -> intf.vlan().equals(vlan))
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public Interface getMatchingInterface(IpAddress ip) {
+            return AVAILABLE_INTERFACES.stream()
+                    .filter(intf -> intf.ipAddressesList().contains(ip))
+                    .findFirst()
+                    .orElse(null);
+        }
+
+        @Override
+        public Set<Interface> getMatchingInterfaces(IpAddress ip) {
+            return AVAILABLE_INTERFACES.stream()
+                    .filter(intf -> intf.ipAddressesList().contains(ip))
+                    .collect(Collectors.toSet());
+        }
+    }
+
+    /**
+     * Test VPLS store.
+     */
+    public class TestVplsStore extends VplsStoreAdapter {
+        /**
+         * Clears the store.
+         */
+        public void clear() {
+            vplsDataMap.clear();
+        }
+
+        /**
+         * Gets the store delegate.
+         *
+         * @return the store delegate
+         */
+        public StoreDelegate<VplsStoreEvent> delegate() {
+            return this.delegate;
+        }
+    }
+
+    /**
+     * Test VPLS.
+     * Provides basic VPLS functionality and stores VPLS information.
+     */
+    public class TestVpls implements Vpls {
+        public Map<String, VplsData> testData;
+
+        public TestVpls() {
+            testData = Maps.newHashMap();
+        }
+
+        public void initSampleData() {
+            testData.clear();
+            VplsData vplsData = VplsData.of(VPLS1);
+            vplsData.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+            vplsData.state(VplsData.VplsState.ADDED);
+            testData.put(VPLS1, vplsData);
+
+            vplsData = VplsData.of(VPLS2);
+            vplsData.addInterfaces(ImmutableSet.of(V200H1, V200H2));
+            vplsData.state(VplsData.VplsState.ADDED);
+            testData.put(VPLS2, vplsData);
+        }
+
+        @Override
+        public VplsData createVpls(String vplsName, EncapsulationType encapsulationType) {
+            VplsData vplsData = VplsData.of(vplsName, encapsulationType);
+            testData.put(vplsName, vplsData);
+            return vplsData;
+        }
+
+        @Override
+        public VplsData removeVpls(VplsData vplsData) {
+            if (!testData.containsKey(vplsData.name())) {
+                return null;
+            }
+
+            testData.remove(vplsData.name());
+            return vplsData;
+        }
+
+        @Override
+        public void addInterfaces(VplsData vplsData, Collection<Interface> interfaces) {
+            vplsData.addInterfaces(interfaces);
+            testData.put(vplsData.name(), vplsData);
+        }
+
+        @Override
+        public void addInterface(VplsData vplsData, Interface iface) {
+            vplsData.addInterface(iface);
+            testData.put(vplsData.name(), vplsData);
+        }
+
+        @Override
+        public void setEncapsulationType(VplsData vplsData, EncapsulationType encapsulationType) {
+            vplsData.encapsulationType(encapsulationType);
+            testData.put(vplsData.name(), vplsData);
+        }
+
+        @Override
+        public VplsData getVpls(String vplsName) {
+            return testData.get(vplsName);
+        }
+
+        @Override
+        public Collection<VplsData> getAllVpls() {
+            return testData.values();
+        }
+
+        @Override
+        public Collection<Interface> removeInterfaces(VplsData vplsData, Collection<Interface> interfaces) {
+            vplsData.removeInterfaces(interfaces);
+            testData.put(vplsData.name(), vplsData);
+            return interfaces;
+        }
+
+        @Override
+        public Interface removeInterface(VplsData vplsData, Interface iface) {
+            vplsData.removeInterface(iface);
+            testData.put(vplsData.name(), vplsData);
+            return iface;
+        }
+
+        @Override
+        public void removeAllVpls() {
+            testData.clear();
+        }
     }
 
     /**
      * Represents a fake IdGenerator class for intents.
      */
-    private static class TestIdGenerator implements IdGenerator {
-
+    protected static class TestIdGenerator implements IdGenerator {
         private final AtomicLong id = new AtomicLong(0);
 
         @Override
@@ -814,170 +551,135 @@
     }
 
     /**
-     * Test IntentSynchronizer that passes all intents straight through to the
-     * intent service.
+     * Test host service; contains all hosts which already generated.
+     *
      */
-    private class TestIntentSynchronizer implements IntentSynchronizationService {
+    public class TestHostService extends HostServiceAdapter {
 
-        private final IntentService intentService;
+        private HostListener listener;
 
-        /**
-         * Creates a new intent test synchronizer.
-         *
-         * @param intentService intent service
-         */
-        public TestIntentSynchronizer(IntentService intentService) {
-            this.intentService = intentService;
+        @Override
+        public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
+            return AVAILABLE_HOSTS.stream()
+                    .filter(host -> host.location().equals(connectPoint))
+                    .collect(Collectors.toSet());
         }
 
         @Override
-        public void submit(Intent intent) {
-            intentService.submit(intent);
+        public Set<Host> getHostsByMac(MacAddress mac) {
+            return AVAILABLE_HOSTS.stream()
+                    .filter(host -> host.mac().equals(mac))
+                    .collect(Collectors.toSet());
         }
 
         @Override
-        public void withdraw(Intent intent) {
-            intentService.withdraw(intent);
+        public Iterable<Host> getHosts() {
+            return AVAILABLE_HOSTS;
         }
 
         @Override
-        public void removeIntentsByAppId(ApplicationId applicationId) {
+        public Set<Host> getHostsByVlan(VlanId vlanId) {
+            return AVAILABLE_HOSTS.stream()
+                    .filter(host -> host.vlan().equals(vlanId))
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public int getHostCount() {
+            return AVAILABLE_HOSTS.size();
+        }
+
+        @Override
+        public Host getHost(HostId hostId) {
+            return AVAILABLE_HOSTS.stream()
+                    .filter(host -> host.id().equals(hostId))
+                    .findFirst()
+                    .orElse(null);
+        }
+
+        @Override
+        public void addListener(HostListener listener) {
+            this.listener = listener;
+        }
+
+        public void postHostEvent(HostEvent hostEvent) {
+            this.listener.event(hostEvent);
         }
     }
 
     /**
-     * Represents a fake VplsConfigService class which is needed for testing.
+     * Test network configuration service.
      */
-    private class TestVplsConfigService extends VplsConfigServiceAdapter {
+    public class TestConfigService extends NetworkConfigServiceAdapter {
+        public static final String EMPTY_JSON_TREE = "{}";
+        NetworkConfigListener listener;
+        VplsAppConfig vplsAppConfig;
 
-        private final SetMultimap<String, Interface> ifacesByVplsName;
-        private final Map<String, EncapsulationType> encapsByVplsName;
-
-        private Set<String> vplsAffectByApi = new HashSet<>();
-
-        TestVplsConfigService(SetMultimap<String, Interface> ifacesByVplsName,
-                              Map<String, EncapsulationType> encapsByVplsName) {
-            this.ifacesByVplsName = ifacesByVplsName;
-            this.encapsByVplsName = encapsByVplsName;
+        @Override
+        public void addListener(NetworkConfigListener listener) {
+            this.listener = listener;
         }
 
         @Override
-        public void addVpls(String vplsName, Set<String> ifaceNames, String encap) {
-            if (!ifacesByVplsName.containsKey(vplsName)) {
-                ifaceNames.forEach(ifaceName -> {
-                    AVAILABLE_INTERFACES.forEach(iface -> {
-                        if (iface.name().equals(ifaceName)) {
-                            ifacesByVplsName.put(vplsName, iface);
-                        }
-                    });
-                });
-            }
-            if (!ifacesByVplsName.containsKey(vplsName)) {
-                encapsByVplsName.put(vplsName, valueOf(encap));
+        public void removeListener(NetworkConfigListener listener) {
+            this.listener = null;
+        }
+
+        /**
+         * Sends network config event to listener.
+         *
+         * @param event the network config event
+         */
+        public void sendEvent(NetworkConfigEvent event) {
+            if (listener != null) {
+                listener.event(event);
             }
         }
 
-        @Override
-        public void removeVpls(String vplsName) {
-            if (ifacesByVplsName.containsKey(vplsName)) {
-                ifacesByVplsName.removeAll(vplsName);
+        /**
+         * Constructs test config service.
+         * Generates an VPLS configuration with sample VPLS configs.
+         */
+        public TestConfigService() {
+            vplsAppConfig = new VplsAppConfig();
+            final ObjectMapper mapper = new ObjectMapper();
+            final ConfigApplyDelegate delegate = new VplsAppConfigTest.MockCfgDelegate();
+            JsonNode tree = null;
+            try {
+                tree = new ObjectMapper().readTree(EMPTY_JSON_TREE);
+            } catch (IOException e) {
+                e.printStackTrace();
             }
+            vplsAppConfig.init(APPID, APP_NAME, tree, mapper, delegate);
+            VplsConfig vplsConfig = new VplsConfig(VPLS1,
+                                                   ImmutableSet.of(V100H1.name(), V100H2.name()),
+                                                   EncapsulationType.NONE);
+            vplsAppConfig.addVpls(vplsConfig);
+            vplsConfig = new VplsConfig(VPLS2,
+                                        ImmutableSet.of(V200H1.name(), V200H2.name()),
+                                        EncapsulationType.VLAN);
+            vplsAppConfig.addVpls(vplsConfig);
+
+        }
+
+        /**
+         * Overrides VPLS config to the config service.
+         *
+         * @param vplsAppConfig the new VPLS config
+         */
+        public void setConfig(VplsAppConfig vplsAppConfig) {
+            this.vplsAppConfig = vplsAppConfig;
         }
 
         @Override
-        public void addIface(String vplsName, String iface) {
-            if (!ifacesByVplsName.containsKey(vplsName)) {
-                AVAILABLE_INTERFACES.forEach(intf -> {
-                    if (intf.name().equals(iface)) {
-                        ifacesByVplsName.put(vplsName, intf);
-                    }
-                });
-            }
+        public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
+            return (C) vplsAppConfig;
         }
 
         @Override
-        public void setEncap(String vplsName, String encap) {
-            encapsByVplsName.put(vplsName, EncapsulationType.enumFromString(encap));
-        }
-
-        @Override
-        public void removeIface(String iface) {
-            SetMultimap<String, Interface> search = HashMultimap.create(ifacesByVplsName);
-            search.entries().forEach(e -> {
-                if (e.getValue().name().equals(iface)) {
-                    ifacesByVplsName.remove(e.getKey(), iface);
-                }
-            });
-        }
-
-        @Override
-        public void cleanVplsConfig() {
-            ifacesByVplsName.clear();
-        }
-
-        @Override
-        public EncapsulationType encap(String vplsName) {
-            EncapsulationType encap = null;
-            if (encapsByVplsName.containsKey(vplsName)) {
-                encap = encapsByVplsName.get(vplsName);
-            }
-            return encap;
-        }
-
-        @Override
-        public Set<String> vplsAffectedByApi() {
-            Set<String> vplsNames = ImmutableSet.copyOf(vplsAffectByApi);
-
-            vplsAffectByApi.clear();
-
-            return vplsNames;
-        }
-
-        @Override
-        public Set<Interface> allIfaces() {
-            return ifacesByVplsName.values()
-                    .stream()
-                    .collect(Collectors.toSet());
-        }
-
-        @Override
-        public Set<Interface> ifaces(String name) {
-            return ifacesByVplsName.get(name)
-                    .stream()
-                    .collect(Collectors.toSet());
-        }
-
-        @Override
-        public Set<String> vplsNames() {
-            return ifacesByVplsName.keySet();
-        }
-
-        @Override
-        public Set<String> vplsNamesOld() {
-            return ifacesByVplsName.keySet();
-        }
-
-        public SetMultimap<String, Interface> ifacesByVplsName() {
-            return ImmutableSetMultimap.copyOf(ifacesByVplsName);
-        }
-
-        @Override
-        public SetMultimap<String, Interface> ifacesByVplsName(VlanId vlan,
-                                                               ConnectPoint connectPoint) {
-            String vplsName =
-                    ifacesByVplsName.entries().stream()
-                            .filter(e -> e.getValue().connectPoint().equals(connectPoint))
-                            .filter(e -> e.getValue().vlan().equals(vlan))
-                            .map(Map.Entry::getKey)
-                            .findFirst()
-                            .orElse(null);
-            SetMultimap<String, Interface> result = HashMultimap.create();
-            if (vplsName != null && ifacesByVplsName.containsKey(vplsName)) {
-                ifacesByVplsName.get(vplsName)
-                        .forEach(intf -> result.put(vplsName, intf));
-                return result;
-            }
-            return null;
+        public <S, C extends Config<S>> C addConfig(S subject, Class<C> configClass) {
+            return (C) vplsAppConfig;
         }
     }
+
 }
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/cli/VplsCommandTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/cli/VplsCommandTest.java
new file mode 100644
index 0000000..eeff5ef
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/cli/VplsCommandTest.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vpls.cli;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.vpls.VplsTest;
+import org.onosproject.vpls.api.VplsData;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.Collection;
+
+import static org.junit.Assert.*;
+
+/**
+ * Test for {@link VplsCommand}.
+ */
+public class VplsCommandTest extends VplsTest {
+    private static final String NEW_LINE = "\n";
+    private static final String SHOW_ALL_RES = "----------------\n" +
+            "VPLS name: \u001B[1mvpls2\u001B[0m\n" +
+            "Associated interfaces: [v200h2, v200h1]\n" +
+            "Encapsulation: NONE\n" +
+            "State: ADDED\n" +
+            "----------------\n" +
+            "VPLS name: \u001B[1mvpls1\u001B[0m\n" +
+            "Associated interfaces: [v100h1, v100h2]\n" +
+            "Encapsulation: NONE\n" +
+            "State: ADDED\n" +
+            "----------------\n";
+    private static final String SHOW_ONE_RES = "VPLS name: \u001B[1mvpls1\u001B[0m\n" +
+            "Associated interfaces: [v100h1, v100h2]\n" +
+            "Encapsulation: NONE\n" +
+            "State: ADDED\n";
+    private static final String IFACE_ALREADY_USED =
+            "\u001B[31mInterface \u001B[1mv200h1\u001B[0m\u001B[31m already associated " +
+            "to VPLS \u001B[1mvpls2\u001B[0m\u001B[31m\u001B[0m\n";
+    private static final String LIST_OUTPUT = VPLS1 + NEW_LINE + VPLS2 + NEW_LINE;
+    VplsCommand vplsCommand;
+
+    @Before
+    public void setup() {
+        vplsCommand = new VplsCommand();
+        vplsCommand.vpls = new TestVpls();
+        vplsCommand.interfaceService = new TestInterfaceService();
+    }
+
+    /**
+     * Creates a new VPLS.
+     */
+    @Test
+    public void testCreate() {
+        vplsCommand.command = VplsCommandEnum.CREATE.toString();
+        vplsCommand.vplsName = VPLS1;
+        vplsCommand.execute();
+        Collection<VplsData> vplss = vplsCommand.vpls.getAllVpls();
+        assertEquals(1, vplss.size());
+        VplsData result = vplss.iterator().next();
+        VplsData expected = VplsData.of(VPLS1, EncapsulationType.NONE);
+        assertEquals(expected, result);
+    }
+
+    /**
+     * Adds new network interface to a VPLS.
+     */
+    @Test
+    public void testAddIf() {
+        vplsCommand.create(VPLS1);
+
+        vplsCommand.command = VplsCommandEnum.ADD_IFACE.toString();
+        vplsCommand.vplsName = VPLS1;
+        vplsCommand.optArg = V100H1.name();
+        vplsCommand.execute();
+
+        vplsCommand.command = VplsCommandEnum.ADD_IFACE.toString();
+        vplsCommand.vplsName = VPLS1;
+        vplsCommand.optArg = V200H1.name();
+        vplsCommand.execute();
+
+        Collection<VplsData> vplss = vplsCommand.vpls.getAllVpls();
+        assertEquals(1, vplss.size());
+        VplsData result = vplss.iterator().next();
+        assertEquals(2, result.interfaces().size());
+        assertTrue(result.interfaces().contains(V100H1));
+        assertTrue(result.interfaces().contains(V200H1));
+    }
+
+    /**
+     * Removes network interface from a VPLS.
+     */
+    @Test
+    public void testRemIf() {
+        vplsCommand.create(VPLS1);
+        vplsCommand.addIface(VPLS1, V100H1.name());
+        vplsCommand.addIface(VPLS1, V200H1.name());
+
+        vplsCommand.command = VplsCommandEnum.REMOVE_IFACE.toString();
+        vplsCommand.vplsName = VPLS1;
+        vplsCommand.optArg = V200H1.name();
+        vplsCommand.execute();
+
+        Collection<VplsData> vplss = vplsCommand.vpls.getAllVpls();
+        assertEquals(1, vplss.size());
+        VplsData result = vplss.iterator().next();
+        assertEquals(1, result.interfaces().size());
+        assertTrue(result.interfaces().contains(V100H1));
+        assertFalse(result.interfaces().contains(V200H1));
+    }
+
+    /**
+     * Lists all VPLS names.
+     */
+    @Test
+    public void testList() {
+        ((TestVpls) vplsCommand.vpls).initSampleData();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        PrintStream ps = new PrintStream(baos);
+        System.setOut(ps);
+        vplsCommand.command = VplsCommandEnum.LIST.toString();
+        vplsCommand.execute();
+        String result = baos.toString();
+
+        assertEquals(LIST_OUTPUT, result);
+    }
+
+    /**
+     * Sets encapsulation to a VPLS.
+     */
+    @Test
+    public void testSetEncap() {
+        ((TestVpls) vplsCommand.vpls).initSampleData();
+
+        // Sets to NONE
+        vplsCommand.command = VplsCommandEnum.SET_ENCAP.toString();
+        vplsCommand.vplsName = VPLS1;
+        vplsCommand.optArg = EncapsulationType.NONE.name();
+        vplsCommand.execute();
+        VplsData result = vplsCommand.vpls.getVpls(VPLS1);
+        assertEquals(result.encapsulationType(), EncapsulationType.NONE);
+
+        // Sets to VLAN
+        vplsCommand.command = VplsCommandEnum.SET_ENCAP.toString();
+        vplsCommand.vplsName = VPLS1;
+        vplsCommand.optArg = EncapsulationType.VLAN.name();
+        vplsCommand.execute();
+        result = vplsCommand.vpls.getVpls(VPLS1);
+        assertEquals(result.encapsulationType(), EncapsulationType.VLAN);
+
+        // Sets to MPLS
+        vplsCommand.command = VplsCommandEnum.SET_ENCAP.toString();
+        vplsCommand.vplsName = VPLS1;
+        vplsCommand.optArg = EncapsulationType.MPLS.name();
+        vplsCommand.execute();
+        result = vplsCommand.vpls.getVpls(VPLS1);
+        assertEquals(result.encapsulationType(), EncapsulationType.MPLS);
+    }
+
+    /**
+     * Deletes a VPLS.
+     */
+    @Test
+    public void testDelete() {
+        ((TestVpls) vplsCommand.vpls).initSampleData();
+        vplsCommand.command = VplsCommandEnum.DELETE.toString();
+        vplsCommand.vplsName = VPLS1;
+        vplsCommand.execute();
+        Collection<VplsData> vplss = vplsCommand.vpls.getAllVpls();
+        assertEquals(1, vplss.size());
+    }
+
+    /**
+     * Shows all VPLS information.
+     */
+    @Test
+    public void testShowAll() {
+        ((TestVpls) vplsCommand.vpls).initSampleData();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        PrintStream ps = new PrintStream(baos);
+        System.setOut(ps);
+        vplsCommand.command = VplsCommandEnum.SHOW.toString();
+        vplsCommand.execute();
+        String result = baos.toString();
+        assertEquals(SHOW_ALL_RES, result);
+    }
+
+    /**
+     * Shows a VPLS information.
+     */
+    @Test
+    public void testShowOne() {
+        ((TestVpls) vplsCommand.vpls).initSampleData();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        PrintStream ps = new PrintStream(baos);
+        System.setOut(ps);
+        vplsCommand.command = VplsCommandEnum.SHOW.toString();
+        vplsCommand.vplsName = VPLS1;
+        vplsCommand.execute();
+        String result = baos.toString();
+        assertEquals(SHOW_ONE_RES, result);
+    }
+
+    /**
+     * Adds a network interface which already related to another VPLS to a VPLS.
+     */
+    @Test
+    public void testIfaceAssociated() {
+        ((TestVpls) vplsCommand.vpls).initSampleData();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        PrintStream ps = new PrintStream(baos);
+        System.setOut(ps);
+        vplsCommand.command = VplsCommandEnum.ADD_IFACE.toString();
+        vplsCommand.vplsName = VPLS1;
+        vplsCommand.optArg = V200H1.name();
+        vplsCommand.execute();
+
+        String result = baos.toString();
+        assertEquals(IFACE_ALREADY_USED, result);
+    }
+
+    /**
+     * Removes all VPLS.
+     */
+    @Test
+    public void testClean() {
+        ((TestVpls) vplsCommand.vpls).initSampleData();
+        vplsCommand.command = VplsCommandEnum.CLEAN.toString();
+        vplsCommand.execute();
+        Collection<VplsData> vplss = vplsCommand.vpls.getAllVpls();
+        assertEquals(0, vplss.size());
+    }
+}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/cli/completer/VplsCommandCompleterTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/cli/completer/VplsCommandCompleterTest.java
new file mode 100644
index 0000000..90d48df
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/cli/completer/VplsCommandCompleterTest.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vpls.cli.completer;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.karaf.shell.console.CommandSessionHolder;
+import org.apache.karaf.shell.console.completer.ArgumentCompleter;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.vpls.VplsTest;
+import org.onosproject.vpls.cli.VplsCommandEnum;
+
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.*;
+
+public class VplsCommandCompleterTest extends VplsTest {
+    private static final String VPLS_CMD = "vpls";
+    private TestCommandSession commandSession;
+
+    @Before
+    public void setup() {
+        commandSession = new TestCommandSession();
+        CommandSessionHolder.setSession(commandSession);
+    }
+
+    /**
+     * Test VPLS command completer.
+     */
+    @Test
+    public void testCommandCompleter() {
+        VplsCommandCompleter commandCompleter = new VplsCommandCompleter();
+        List<String> choices = commandCompleter.choices();
+        List<String> expected = VplsCommandEnum.toStringList();
+        assertEquals(expected, choices);
+    }
+
+    /**
+     * Test VPLS name completer.
+     */
+    @Test
+    public void testNameCompleter() {
+        VplsNameCompleter vplsNameCompleter = new VplsNameCompleter();
+        vplsNameCompleter.vpls = new TestVpls();
+        ((TestVpls) vplsNameCompleter.vpls).initSampleData();
+        List<String> choices = vplsNameCompleter.choices();
+        List<String> expected = ImmutableList.of(VPLS1, VPLS2);
+
+        // Can not ensure the order, use contains all instead of equals
+        assertEquals(choices.size(), expected.size());
+        assertTrue(choices.containsAll(expected));
+    }
+
+    /**
+     * Test VPLS option arguments completer.
+     */
+    @Test
+    public void testOptArgCompleter() {
+        VplsOptArgCompleter completer = new VplsOptArgCompleter();
+        completer.vpls = new TestVpls();
+        ((TestVpls) completer.vpls).initSampleData();
+        completer.interfaceService = new TestInterfaceService();
+
+        // Add interface to VPLS
+        commandSession.updateArguments(VPLS_CMD, VplsCommandEnum.ADD_IFACE.toString(), VPLS1);
+
+        List<String> choices = completer.choices();
+        List<String> expected = ImmutableList.of(V300H1.name(),
+                                                 V300H2.name(),
+                                                 V400H1.name(),
+                                                 VNONEH1.name(),
+                                                 VNONEH2.name(),
+                                                 VNONEH3.name());
+
+        // Can not ensure the order, use contains all instead of equals
+        assertEquals(choices.size(), expected.size());
+        assertTrue(choices.containsAll(expected));
+
+        // Removes interface from VPLS
+        commandSession.updateArguments(VPLS_CMD, VplsCommandEnum.REMOVE_IFACE.toString(), VPLS1);
+        choices = completer.choices();
+        expected = completer.vpls.getVpls(VPLS1).interfaces().stream()
+                .map(Interface::name)
+                .collect(Collectors.toList());
+
+        // Can not ensure the order, use contains all instead of equals
+        assertEquals(choices.size(), expected.size());
+        assertTrue(choices.containsAll(expected));
+
+        // Sets encapsulation
+        commandSession.updateArguments(VPLS_CMD, VplsCommandEnum.SET_ENCAP.toString(), VPLS1);
+        choices = completer.choices();
+        expected = Arrays.stream(EncapsulationType.values())
+                .map(Enum::toString)
+                .collect(Collectors.toList());
+
+        // Can not ensure the order, use contains all instead of equals
+        assertEquals(choices.size(), expected.size());
+        assertTrue(choices.containsAll(expected));
+    }
+
+    /**
+     * Test command session.
+     */
+    class TestCommandSession implements CommandSession {
+        ArgumentCompleter.ArgumentList argumentList;
+        public TestCommandSession() {
+            String[] emptyStringArr = new String[0];
+            argumentList = new ArgumentCompleter.ArgumentList(emptyStringArr,
+                                                              0,
+                                                              0,
+                                                              0);
+        }
+
+        /**
+         * Updates argument list for the command session.
+         *
+         * @param args new arguments
+         */
+        public void updateArguments(String... args) {
+            argumentList = new ArgumentCompleter.ArgumentList(args,
+                                                              0,
+                                                              0,
+                                                              0);
+        }
+
+        @Override
+        public Object execute(CharSequence charSequence) throws Exception {
+            return null;
+        }
+
+        @Override
+        public void close() {
+
+        }
+
+        @Override
+        public InputStream getKeyboard() {
+            return null;
+        }
+
+        @Override
+        public PrintStream getConsole() {
+            return null;
+        }
+
+        @Override
+        public Object get(String s) {
+            return argumentList;
+        }
+
+        @Override
+        public void put(String s, Object o) {
+
+        }
+
+        @Override
+        public CharSequence format(Object o, int i) {
+            return null;
+        }
+
+        @Override
+        public Object convert(Class<?> aClass, Object o) {
+            return null;
+        }
+    }
+}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/config/VplsAppConfigTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/config/VplsAppConfigTest.java
index b3ca89d..37e7598 100644
--- a/apps/vpls/src/test/java/org/onosproject/vpls/config/VplsAppConfigTest.java
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/config/VplsAppConfigTest.java
@@ -246,19 +246,28 @@
                      vplsAppConfig.getVplsWithName(VPLS1).encap());
     }
 
-    private class MockCfgDelegate implements ConfigApplyDelegate {
-
+    public static class MockCfgDelegate implements ConfigApplyDelegate {
         @Override
         public void onApply(@SuppressWarnings("rawtypes") Config config) {
             config.apply();
         }
     }
 
+    /**
+     * Creates a basic VPLS config.
+     *
+     * @return the VPLS config
+     */
     private VplsConfig createInitialVpls() {
         Set<String> ifaces = new HashSet<>(Arrays.asList(IF1, IF2, IF3));
         return new VplsConfig(VPLS1, ifaces, EncapsulationType.NONE);
     }
 
+    /**
+     * Creates another basic VPLS config.
+     *
+     * @return the VPLS config
+     */
     private VplsConfig createNewVpls() {
         Set<String> ifaces = new HashSet<>(Arrays.asList(IF4, IF5));
         return new VplsConfig(NEWVPLS, ifaces, EncapsulationType.NONE);
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/config/VplsConfigManagerTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/config/VplsConfigManagerTest.java
new file mode 100644
index 0000000..8baae6c
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/config/VplsConfigManagerTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vpls.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.ImmutableSet;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.config.ConfigApplyDelegate;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigRegistryAdapter;
+import org.onosproject.vpls.VplsTest;
+import org.onosproject.vpls.api.VplsData;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import static org.junit.Assert.*;
+public class VplsConfigManagerTest extends VplsTest {
+    VplsConfigManager vplsConfigManager;
+
+    @Before
+    public void setup() {
+        vplsConfigManager = new VplsConfigManager();
+        vplsConfigManager.configService = new TestConfigService();
+        vplsConfigManager.coreService = new TestCoreService();
+        vplsConfigManager.interfaceService = new TestInterfaceService();
+        vplsConfigManager.registry = new NetworkConfigRegistryAdapter();
+        vplsConfigManager.vpls = new TestVpls();
+        vplsConfigManager.leadershipService = new TestLeadershipService();
+
+        vplsConfigManager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        vplsConfigManager.deactivate();
+    }
+
+    /**
+     * Reloads network configuration by sending a network config event.
+     */
+    @Test
+    public void testReloadConfig() {
+        NetworkConfigEvent event = new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_ADDED,
+                                                          null,
+                                                          VplsAppConfig.class);
+        ((TestConfigService) vplsConfigManager.configService).sendEvent(event);
+
+        Collection<VplsData> vplss = vplsConfigManager.vpls.getAllVpls();
+        assertEquals(2, vplss.size());
+
+        VplsData expect = VplsData.of(VPLS1);
+        expect.addInterfaces(ImmutableSet.of(V100H1, V100H2));
+        expect.state(VplsData.VplsState.ADDED);
+        assertTrue(vplss.contains(expect));
+
+        expect = VplsData.of(VPLS2, EncapsulationType.VLAN);
+        expect.addInterfaces(ImmutableSet.of(V200H1, V200H2));
+        expect.state(VplsData.VplsState.ADDED);
+        System.out.println(vplss);
+        assertTrue(vplss.contains(expect));
+    }
+
+    /**
+     * Sends a network config event with null network config.
+     */
+    @Test
+    public void testReloadNullConfig() {
+        ((TestConfigService) vplsConfigManager.configService).setConfig(null);
+        NetworkConfigEvent event = new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_ADDED,
+                                                          null,
+                                                          VplsAppConfig.class);
+        ((TestConfigService) vplsConfigManager.configService).sendEvent(event);
+
+        Collection<VplsData> vplss = vplsConfigManager.vpls.getAllVpls();
+        assertEquals(0, vplss.size());
+    }
+
+    /**
+     * Updates VPLSs by sending new VPLS config.
+     */
+    @Test
+    public void testReloadConfigUpdateVpls() {
+        ((TestVpls) vplsConfigManager.vpls).initSampleData();
+
+        VplsAppConfig vplsAppConfig = new VplsAppConfig();
+        final ObjectMapper mapper = new ObjectMapper();
+        final ConfigApplyDelegate delegate = new VplsAppConfigTest.MockCfgDelegate();
+        JsonNode tree = null;
+        try {
+            tree = new ObjectMapper().readTree(TestConfigService.EMPTY_JSON_TREE);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        vplsAppConfig.init(APPID, APP_NAME, tree, mapper, delegate);
+        VplsConfig vplsConfig = new VplsConfig(VPLS1,
+                                               ImmutableSet.of(V100H1.name()),
+                                               EncapsulationType.MPLS);
+        vplsAppConfig.addVpls(vplsConfig);
+        ((TestConfigService) vplsConfigManager.configService).setConfig(vplsAppConfig);
+        NetworkConfigEvent event = new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_ADDED,
+                                                          null,
+                                                          VplsAppConfig.class);
+        ((TestConfigService) vplsConfigManager.configService).sendEvent(event);
+
+        Collection<VplsData> vplss = vplsConfigManager.vpls.getAllVpls();
+        assertEquals(1, vplss.size());
+
+        VplsData expect = VplsData.of(VPLS1, EncapsulationType.MPLS);
+        expect.addInterfaces(ImmutableSet.of(V100H1));
+        expect.state(VplsData.VplsState.ADDED);
+        assertTrue(vplss.contains(expect));
+    }
+
+    /**
+     * Remvoes all VPLS by sending CONFIG_REMOVED event.
+     */
+    @Test
+    public void testRemoveConfig() {
+        NetworkConfigEvent event = new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_REMOVED,
+                                                          null,
+                                                          VplsAppConfig.class);
+        ((TestConfigService) vplsConfigManager.configService).sendEvent(event);
+
+        Collection<VplsData> vplss = vplsConfigManager.vpls.getAllVpls();
+        assertEquals(0, vplss.size());
+    }
+}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/store/VplsStoreAdapter.java b/apps/vpls/src/test/java/org/onosproject/vpls/store/VplsStoreAdapter.java
new file mode 100644
index 0000000..bcc70af
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/store/VplsStoreAdapter.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vpls.store;
+
+import com.google.common.collect.Maps;
+import org.onosproject.store.StoreDelegate;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.api.VplsStore;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Test adapter for VPLS store.
+ */
+public class VplsStoreAdapter implements VplsStore {
+    protected Map<String, VplsData> vplsDataMap;
+    protected StoreDelegate<VplsStoreEvent> delegate;
+
+    public VplsStoreAdapter() {
+        vplsDataMap = Maps.newHashMap();
+    }
+
+    @Override
+    public void setDelegate(StoreDelegate<VplsStoreEvent> delegate) {
+        this.delegate = delegate;
+    }
+
+    @Override
+    public void unsetDelegate(StoreDelegate<VplsStoreEvent> delegate) {
+        this.delegate = null;
+    }
+
+    @Override
+    public boolean hasDelegate() {
+        return this.delegate != null;
+    }
+
+    @Override
+    public void addVpls(VplsData vplsData) {
+        vplsDataMap.put(vplsData.name(), vplsData);
+    }
+
+    @Override
+    public void removeVpls(VplsData vplsData) {
+        vplsDataMap.remove(vplsData.name());
+    }
+
+    @Override
+    public void updateVpls(VplsData vplsData) {
+        vplsDataMap.put(vplsData.name(), vplsData);
+    }
+
+    @Override
+    public VplsData getVpls(String vplsName) {
+        return vplsDataMap.get(vplsName);
+    }
+
+    @Override
+    public Collection<VplsData> getAllVpls() {
+        return vplsDataMap.values();
+    }
+}
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/store/VplsStoreTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/store/VplsStoreTest.java
new file mode 100644
index 0000000..31a2176
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/store/VplsStoreTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vpls.store;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.store.service.TestStorageService;
+import org.onosproject.vpls.VplsTest;
+import org.onosproject.vpls.api.VplsData;
+import org.onosproject.vpls.config.VplsAppConfig;
+import org.onosproject.vpls.config.VplsConfig;
+
+import java.util.Collection;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.EncapsulationType.VLAN;
+
+public class VplsStoreTest extends VplsTest {
+    private DistributedVplsStore vplsStore;
+
+    @Before
+    public void setup() {
+        vplsStore = new DistributedVplsStore();
+        vplsStore.coreService = new TestCoreService();
+        vplsStore.storageService = new TestStorageService();
+        vplsStore.networkConfigService = new TestConfigService();
+        vplsStore.active();
+    }
+
+    @After
+    public void tearDown() {
+        vplsStore.deactive();
+    }
+
+    /**
+     * Adds a VPLS to the store; checks if config store is also updated.
+     */
+    @Test
+    public void testAddVpls() {
+        VplsData vplsData = VplsData.of(VPLS1, VLAN);
+        vplsStore.addVpls(vplsData);
+        Collection<VplsData> vplsDataCollection = vplsStore.getAllVpls();
+
+        assertEquals(1, vplsDataCollection.size());
+        assertTrue(vplsDataCollection.contains(vplsData));
+
+        VplsAppConfig storedConfig = vplsStore.networkConfigService
+                .getConfig(null, VplsAppConfig.class);
+        assertNotEquals(-1L, storedConfig.updateTime());
+
+        assertEquals(1, storedConfig.vplss().size());
+
+        VplsConfig vplsConfig = storedConfig.vplss().iterator().next();
+
+        assertEquals(VPLS1, vplsConfig.name());
+        assertEquals(0, vplsConfig.ifaces().size());
+        assertEquals(VLAN, vplsConfig.encap());
+    }
+
+    /**
+     * Removes a VPLS from store; checks if config store is also updated.
+     */
+    @Test
+    public void testRemoveVpls() {
+        VplsData vplsData = VplsData.of(VPLS1, VLAN);
+        vplsStore.addVpls(vplsData);
+        vplsStore.removeVpls(vplsData);
+
+        Collection<VplsData> vplsDataCollection = vplsStore.getAllVpls();
+        assertEquals(0, vplsDataCollection.size());
+
+        VplsAppConfig storedConfig = vplsStore.networkConfigService
+                .getConfig(null, VplsAppConfig.class);
+
+        assertNotEquals(-1L, storedConfig.updateTime());
+
+        assertEquals(0, storedConfig.vplss().size());
+    }
+
+    /**
+     * Updates a VPLS from store; checks if config store is also updated.
+     */
+    @Test
+    public void testUpdateVpls() {
+        VplsData vplsData = VplsData.of(VPLS1, VLAN);
+        vplsStore.addVpls(vplsData);
+        vplsData.addInterface(V100H1);
+        vplsData.addInterface(V100H2);
+        vplsStore.updateVpls(vplsData);
+
+        Collection<VplsData> vplsDataCollection = vplsStore.getAllVpls();
+        assertEquals(1, vplsDataCollection.size());
+        VplsData newVplsData = vplsDataCollection.iterator().next();
+
+        assertEquals(vplsData, newVplsData);
+
+        VplsAppConfig storedConfig = vplsStore.networkConfigService
+                .getConfig(null, VplsAppConfig.class);
+
+        assertNotEquals(-1L, storedConfig.updateTime());
+
+        assertEquals(1, storedConfig.vplss().size());
+
+        VplsConfig vplsConfig = storedConfig.vplss().iterator().next();
+
+        assertEquals(VPLS1, vplsConfig.name());
+        assertEquals(2, vplsConfig.ifaces().size());
+        assertTrue(vplsConfig.ifaces().contains(V100H1.name()));
+        assertTrue(vplsConfig.ifaces().contains(V100H2.name()));
+        assertEquals(VLAN, vplsConfig.encap());
+    }
+}
