diff --git a/apps/pom.xml b/apps/pom.xml
index 8377ff3..032b327 100644
--- a/apps/pom.xml
+++ b/apps/pom.xml
@@ -67,6 +67,7 @@
         <module>vrouter</module>
         <module>openstackrouting</module>
         <module>cordmcast</module>
+        <module>vpls</module>
   </modules>
 
     <properties>
diff --git a/apps/vpls/features.xml b/apps/vpls/features.xml
new file mode 100644
index 0000000..6674db8
--- /dev/null
+++ b/apps/vpls/features.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ Copyright 2015 Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
+    <feature name="${project.artifactId}" version="${project.version}"
+             description="${project.description}">
+        <feature>onos-api</feature>
+        <bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-app-routing-api/${project.version}</bundle>
+    </feature>
+</features>
diff --git a/apps/vpls/pom.xml b/apps/vpls/pom.xml
new file mode 100644
index 0000000..3e79be2
--- /dev/null
+++ b/apps/vpls/pom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2014-2016 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-apps</artifactId>
+        <version>1.5.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>onos-app-vpls</artifactId>
+    <packaging>bundle</packaging>
+
+    <description>Application to create L2 broadcast network using VLAN</description>
+
+    <properties>
+        <onos.app.name>org.onosproject.vpls</onos.app.name>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-incubator-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-routing-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+            <version>${project.version}</version>
+            <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>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-junit</artifactId>
+            <scope>test</scope>
+        </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
new file mode 100644
index 0000000..d493773
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java
@@ -0,0 +1,241 @@
+package org.onosproject.vpls;
+
+import com.google.common.collect.SetMultimap;
+import javafx.util.Pair;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.net.intent.SinglePointToMultiPointIntent;
+import org.onosproject.routing.IntentSynchronizationService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Synchronizes intents between the in-memory intent store and the
+ * IntentService.
+ */
+public class IntentInstaller {
+    private static final Logger log = LoggerFactory.getLogger(
+            IntentInstaller.class);
+
+    private static final int PRIORITY_OFFSET = 1000;
+
+    private static final String PREFIX_BROADCAST = "brc";
+    private static final String PREFIX_UNICAST = "uni";
+
+    private final ApplicationId appId;
+    private final IntentSynchronizationService intentSynchronizer;
+    private final IntentService intentService;
+
+    /**
+     * 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;
+    }
+
+    /**
+     * Formats the requests for creating and submit intents.
+     * Single Points to Multi Point intents are created for all the conigured
+     * Connect Points. Multi Point to Single Point intents are created for
+     * Connect Points configured that have hosts attached.
+     *
+     * @param confHostPresentCPoint A map of Connect Points with the eventual
+     *                              MAC address of the host attached, by VLAN
+     */
+    protected void installIntents(SetMultimap<VlanId,
+            Pair<ConnectPoint,
+                    MacAddress>> confHostPresentCPoint) {
+        List<Intent> intents = new ArrayList<>();
+
+        confHostPresentCPoint.asMap().keySet()
+                .forEach(vlanId -> {
+                    List<Pair<ConnectPoint, MacAddress>> cPoints =
+                            confHostPresentCPoint.get(vlanId).stream().collect(Collectors.toList());
+
+                    if (cPoints != null && !cPoints.isEmpty()) {
+                        for (int i = 0; i < cPoints.size(); i++) {
+                            ConnectPoint src = cPoints.get(i).getKey();
+                            Set<ConnectPoint> dsts = new HashSet<>();
+                            MacAddress mac = cPoints.get(i).getValue();
+                            for (int j = 0; j < cPoints.size(); j++) {
+                                ConnectPoint dst = cPoints.get(j).getKey();
+                                if (!dst.equals(src)) {
+                                    dsts.add(dst);
+                                }
+                            }
+                            Key brcKey = buildKey(PREFIX_BROADCAST, src, vlanId);
+                            if (intentService.getIntent(brcKey) == null) {
+                                SinglePointToMultiPointIntent brcIntent =
+                                        buildBrcIntent(brcKey, src, dsts, vlanId);
+                                intents.add(brcIntent);
+                            }
+                            if (mac != null && countMacInCPoints(cPoints) > 1) {
+                                Key uniKey = buildKey(PREFIX_UNICAST, src, vlanId);
+                                if (intentService.getIntent(uniKey) == null) {
+                                    MultiPointToSinglePointIntent uniIntent =
+                                            buildUniIntent(uniKey,
+                                                           dsts,
+                                                           src,
+                                                           vlanId,
+                                                           mac);
+                                    intents.add(uniIntent);
+                                }
+                            }
+                        }
+                    }
+                });
+        submitIntents(intents);
+    }
+
+    /**
+     * Requests to install the intents passed as argument to the Intent Service.
+     *
+     * @param intents intents to be submitted
+     */
+    private void submitIntents(Collection<Intent> intents) {
+        log.debug("Submitting intents to the IntentSynchronizer");
+
+        for (Intent intent : intents) {
+            intentSynchronizer.submit(intent);
+        }
+    }
+
+    /**
+     * Builds a Single Point to Multi Point intent.
+     *
+     * @param src  The source Connect Point
+     * @param dsts The destination Connect Points
+     * @return Single Point to Multi Point intent generated.
+     */
+    private SinglePointToMultiPointIntent buildBrcIntent(Key key,
+                                                         ConnectPoint src,
+                                                         Set<ConnectPoint> dsts,
+                                                         VlanId vlanId) {
+        log.debug("Building p2mp intent from {}", src);
+
+        SinglePointToMultiPointIntent intent;
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+
+        TrafficSelector.Builder builder = DefaultTrafficSelector.builder()
+                .matchEthDst(MacAddress.BROADCAST)
+                .matchVlanId(vlanId);
+
+        TrafficSelector selector = builder.build();
+
+        intent = SinglePointToMultiPointIntent.builder()
+                .appId(appId)
+                .key(key)
+                .selector(selector)
+                .treatment(treatment)
+                .ingressPoint(src)
+                .egressPoints(dsts)
+                .priority(PRIORITY_OFFSET)
+                .build();
+        return intent;
+    }
+
+    /**
+     * Builds a Multi Point to Single Point intent.
+     *
+     * @param srcs The source Connect Points
+     * @param dst  The destination Connect Point
+     * @return Multi Point to Single Point intent generated.
+     */
+    private MultiPointToSinglePointIntent buildUniIntent(Key key,
+                                                         Set<ConnectPoint> srcs,
+                                                         ConnectPoint dst,
+                                                         VlanId vlanId,
+                                                         MacAddress mac) {
+        log.debug("Building mp2p intent to {}", dst);
+
+        MultiPointToSinglePointIntent intent;
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+
+        TrafficSelector.Builder builder = DefaultTrafficSelector.builder()
+                .matchEthDst(mac)
+                .matchVlanId(vlanId);
+
+        TrafficSelector selector = builder.build();
+
+        intent = MultiPointToSinglePointIntent.builder()
+                .appId(appId)
+                .key(key)
+                .selector(selector)
+                .treatment(treatment)
+                .ingressPoints(srcs)
+                .egressPoint(dst)
+                .priority(PRIORITY_OFFSET)
+                .build();
+        return intent;
+    }
+
+    /**
+     * Builds an intent Key for either for a Single Point to Multi Point or
+     * Multi Point to Single Point intent, based on a prefix that defines
+     * the type of intent, the single connection point representing the source
+     * or the destination and the vlan id representing the network.
+     *
+     * @param cPoint the source or destination connect point
+     * @param vlanId the network vlan id
+     * @param prefix prefix string
+     * @return
+     */
+    private Key buildKey(String prefix, ConnectPoint cPoint, VlanId vlanId) {
+        String keyString = new StringBuilder()
+                .append(prefix)
+                .append("-")
+                .append(cPoint.deviceId())
+                .append("-")
+                .append(cPoint.port())
+                .append("-")
+                .append(vlanId)
+                .toString();
+
+        return Key.of(keyString, appId);
+    }
+
+    /**
+     * Counts the number of mac addresses associated to a specific list of
+     * ConnectPoint.
+     *
+     * @param cPoints List of ConnectPoints, eventually binded to the MAC of the
+     *                host attached
+     * @return number of mac addresses found.
+     */
+    private int countMacInCPoints(List<Pair<ConnectPoint, MacAddress>> cPoints) {
+        int macFound = 0;
+        for (Pair<ConnectPoint, MacAddress> p : cPoints) {
+            if (p.getValue() != null) {
+                macFound++;
+            }
+        }
+        return macFound;
+    }
+
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java b/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java
new file mode 100644
index 0000000..a60694b
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vpls;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.SetMultimap;
+import javafx.util.Pair;
+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.InterfaceService;
+import org.onosproject.net.ConnectPoint;
+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.net.intent.IntentService;
+import org.onosproject.routing.IntentSynchronizationAdminService;
+import org.onosproject.routing.IntentSynchronizationService;
+import org.slf4j.Logger;
+
+import java.util.Map;
+import java.util.Set;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Application to create L2 broadcast overlay networks using VLAN.
+ */
+@Component(immediate = true)
+public class Vpls {
+    private static final String VPLS_APP = "org.onosproject.vpls";
+    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 IntentSynchronizationAdminService intentSynchronizerAdmin;
+
+    private final HostListener hostListener = new InternalHostListener();
+
+    private IntentInstaller intentInstaller;
+
+    private ApplicationId appId;
+
+    @Activate
+    public void activate() {
+        appId = coreService.registerApplication(VPLS_APP);
+
+        intentInstaller = new IntentInstaller(appId,
+                                              intentService,
+                                              intentSynchronizer);
+
+        applicationService.registerDeactivateHook(appId,
+                                                  intentSynchronizerAdmin::removeIntents);
+
+        hostService.addListener(hostListener);
+
+        setupConnectivity();
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.info("Stopped");
+    }
+
+    protected void setupConnectivity() {
+        /*
+         * Parse Configuration and get Connect Point by VlanId.
+         */
+        SetMultimap<VlanId, ConnectPoint> confCPointsByVlan = getConfigCPoints();
+
+        /*
+         * Check that configured Connect Points have hosts attached and
+         * associate their Mac Address to the Connect Points configured.
+         */
+        SetMultimap<VlanId, Pair<ConnectPoint, MacAddress>> confHostPresentCPoint =
+                pairAvailableHosts(confCPointsByVlan);
+
+        /*
+         * Create and submit intents between the Connect Points.
+         * Intents for broadcast between all the configured Connect Points.
+         * Intents for unicast between all the configured Connect Points with
+         * hosts attached.
+         */
+        intentInstaller.installIntents(confHostPresentCPoint);
+    }
+
+    /**
+     * Computes the list of configured interfaces with a VLAN Id.
+     *
+     * @return the interfaces grouped by vlan id
+     */
+    protected SetMultimap<VlanId, ConnectPoint> getConfigCPoints() {
+        log.debug("Checking interface configuration");
+
+        SetMultimap<VlanId, ConnectPoint> confCPointsByVlan =
+                HashMultimap.create();
+
+        interfaceService.getInterfaces()
+                .forEach(intf -> confCPointsByVlan.put(intf.vlan(),
+                                                       intf.connectPoint()));
+        return confCPointsByVlan;
+    }
+
+    /**
+     * Checks if for any ConnectPoint configured there's an host present
+     * and in case it associate them together.
+     *
+     * @param confCPointsByVlan the configured ConnectPoints grouped by vlan id
+     * @return the configured ConnectPoints with eventual hosts associated.
+     */
+    protected SetMultimap<VlanId, Pair<ConnectPoint, MacAddress>> pairAvailableHosts(
+            SetMultimap<VlanId, ConnectPoint> confCPointsByVlan) {
+        log.debug("Binding connected hosts mac addresses");
+
+        SetMultimap<VlanId, Pair<ConnectPoint, MacAddress>> confHostPresentCPoint =
+                HashMultimap.create();
+
+        confCPointsByVlan.entries()
+                .forEach(e -> bindMacAddr(e, confHostPresentCPoint));
+
+        return confHostPresentCPoint;
+    }
+
+    private void bindMacAddr(Map.Entry<VlanId, ConnectPoint> e,
+                             SetMultimap<VlanId, Pair<ConnectPoint,
+                             MacAddress>> confHostPresentCPoint) {
+        VlanId vlanId = e.getKey();
+        ConnectPoint cp = e.getValue();
+        Set<Host> connectedHosts = hostService.getConnectedHosts(cp);
+        if (!connectedHosts.isEmpty()) {
+            connectedHosts.forEach(host -> {
+                if (host.vlan().equals(vlanId)) {
+                    confHostPresentCPoint.put(vlanId, new Pair<>(cp, host.mac()));
+                } else {
+                    confHostPresentCPoint.put(vlanId, new Pair<>(cp, null));
+                }
+            });
+        } else {
+            confHostPresentCPoint.put(vlanId, new Pair<>(cp, null));
+        }
+    }
+
+    /**
+     * Listener for host events.
+     */
+    class InternalHostListener implements HostListener {
+        @Override
+        public void event(HostEvent event) {
+            log.debug("Received HostEvent {}", event);
+            switch (event.type()) {
+                case HOST_ADDED:
+                case HOST_UPDATED:
+                case HOST_REMOVED:
+                    setupConnectivity();
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/package-info.java b/apps/vpls/src/main/java/org/onosproject/vpls/package-info.java
new file mode 100644
index 0000000..e62e979
--- /dev/null
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2014 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Application to create L2 broadcast network using VLAN.
+ */
+package org.onosproject.vpls;
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java
new file mode 100644
index 0000000..4d2d37a
--- /dev/null
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java
@@ -0,0 +1,674 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vpls;
+
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.TestApplicationId;
+import org.onosproject.app.ApplicationService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.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.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.provider.ProviderId;
+import org.onosproject.routing.IntentSynchronizationAdminService;
+import org.onosproject.routing.IntentSynchronizationService;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+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.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for the {@link Vpls} class.
+ */
+public class VplsTest {
+
+    private static final int NUM_DEVICES = 7;
+
+    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 Ip4Address IP1 = Ip4Address.valueOf("192.168.1.1");
+    private static final Ip4Address IP2 = Ip4Address.valueOf("192.168.1.2");
+
+    private static final PortNumber P1 = PortNumber.portNumber(1);
+
+    private static final VlanId VLAN1 = VlanId.vlanId((short) 1);
+    private static final VlanId VLAN2 = VlanId.vlanId((short) 2);
+
+    private static final int PRIORITY_OFFSET = 1000;
+    private static final String PREFIX_BROADCAST = "brc";
+    private static final String PREFIX_UNICAST = "uni";
+
+    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);
+
+    private static final ConnectPoint C1 = new ConnectPoint(DID1, P1);
+    private static final ConnectPoint C2 = new ConnectPoint(DID2, P1);
+    private static final ConnectPoint C3 = new ConnectPoint(DID3, P1);
+    private static final ConnectPoint C4 = new ConnectPoint(DID4, P1);
+    private static final ConnectPoint C5 = new ConnectPoint(DID5, P1);
+    private static final ConnectPoint C6 = new ConnectPoint(DID6, P1);
+
+    private static final HostId HID1 = HostId.hostId(MAC1, VLAN1);
+    private static final HostId HID2 = HostId.hostId(MAC2, VLAN1);
+    private static final HostId HID3 = HostId.hostId(MAC3, VLAN1);
+    private static final HostId HID4 = HostId.hostId(MAC4, VLAN2);
+    private static final HostId HID5 = HostId.hostId(MAC5, VLAN2);
+    private static final HostId HID6 = HostId.hostId(MAC6, VLAN2);
+    private static final HostId HID7 = HostId.hostId(MAC7, VlanId.NONE);
+
+    private ApplicationService applicationService;
+    private CoreService coreService;
+    private HostListener hostListener;
+    private Set<Host> hostsAvailable;
+    private HostService hostService;
+    private IntentService intentService;
+    private InterfaceService interfaceService;
+    private Vpls vpls;
+
+    private static final String APP_NAME = "org.onosproject.vpls";
+    private static final ApplicationId APPID = TestApplicationId.create(APP_NAME);
+
+    private static final ProviderId PID = new ProviderId("of", "foo");
+
+    @BeforeClass
+    public static void setUpClass() {
+        IdGenerator idGenerator = new TestIdGenerator();
+        Intent.bindIdGenerator(idGenerator);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        applicationService = createMock(ApplicationService.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);
+        addIntfConfig();
+
+        vpls = new Vpls();
+        vpls.applicationService = applicationService;
+        vpls.coreService = coreService;
+        vpls.hostService = hostService;
+        vpls.intentService = intentService;
+        vpls.interfaceService = interfaceService;
+        vpls.intentSynchronizer = intentSynchronizer;
+        vpls.intentSynchronizerAdmin = intentSynchronizer;
+    }
+
+    /**
+     * Creates the interface configuration. On devices 1, 2 and 3 is configured
+     * an interface on port 1 with vlan 1. On devices 4, 5 and 6 is configured
+     * an interface on port 1 with vlan 2. On device 5 no interfaces are
+     * configured.
+     */
+    private void addIntfConfig() {
+        Set<Interface> interfaces = Sets.newHashSet();
+        Set<Interface> vlanOneSet = new HashSet<>();
+        Set<Interface> vlanTwoSet = new HashSet<>();
+
+        for (int i = 1; i <= NUM_DEVICES - 1; i++) {
+            ConnectPoint cp = new ConnectPoint(getDeviceId(i), P1);
+
+            Interface intf =
+                    new Interface(cp, Collections.emptySet(), null, VlanId.NONE);
+
+            if (i <= 3) {
+                intf = new Interface(cp, Collections.emptySet(), null, VLAN1);
+                interfaces.add(intf);
+                vlanOneSet.add(intf);
+            } else if (i > 3 && i <= 6) {
+                intf = new Interface(cp, Collections.emptySet(), null, VLAN2);
+                interfaces.add(intf);
+                vlanTwoSet.add(intf);
+            }
+            expect(interfaceService.getInterfacesByPort(cp))
+                    .andReturn(Sets.newHashSet(intf)).anyTimes();
+        }
+        expect(interfaceService.getInterfacesByVlan(VLAN1))
+                .andReturn(vlanOneSet).anyTimes();
+        expect(interfaceService.getInterfacesByVlan(VLAN2))
+                .andReturn(vlanTwoSet).anyTimes();
+        expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
+
+        replay(interfaceService);
+    }
+
+    /**
+     * Checks the case in which six ports are configured with VLANs but no
+     * hosts are registered by the HostService. The first three ports have an
+     * interface configured on VLAN1, the other three on VLAN2. The number of
+     * intents expected is six: three for VLAN1, three for VLAN2. three sp2mp
+     * intents, three mp2sp intents.
+     */
+    @Test
+    public void testActivateNoHosts() {
+        vpls.activate();
+
+        List<Intent> expectedIntents = new ArrayList<>();
+        expectedIntents.addAll(generateVlanOneBrc());
+        expectedIntents.addAll(generateVlanTwoBrc());
+
+        checkIntents(expectedIntents);
+    }
+
+    /**
+     * Checks the case in which six ports are configured with VLANs and four
+     * hosts are registered by the HostService. The first three ports have an
+     * interface configured on VLAN1, the other three on VLAN2. The number of
+     * intents expected is twelve: six for VLAN1, six for VLAN2. six sp2mp
+     * intents, six mp2sp intents. For VLAN1 IPs are added to demonstrate it
+     * doesn't influence the number of intents created.
+     */
+    @Test
+    public void testFourInterfacesConfiguredHostsPresent() {
+        Host h1 = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(1),
+                                  Collections.singleton(IP1));
+        Host h2 = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(2),
+                                  Collections.singleton(IP2));
+        Host h3 = new DefaultHost(PID, HID3, MAC3, VLAN1, getLocation(3),
+                                  Collections.EMPTY_SET);
+        Host h4 = new DefaultHost(PID, HID4, MAC4, VLAN2, getLocation(4),
+                                  Collections.EMPTY_SET);
+        Host h5 = new DefaultHost(PID, HID5, MAC5, VLAN2, getLocation(5),
+                                  Collections.EMPTY_SET);
+        Host h6 = new DefaultHost(PID, HID6, MAC6, VLAN2, getLocation(6),
+                                  Collections.EMPTY_SET);
+        hostsAvailable.addAll(Sets.newHashSet(h1, h2, h3, h4, h5, h6));
+
+        vpls.activate();
+
+        List<Intent> expectedIntents = new ArrayList<>();
+        expectedIntents.addAll(generateVlanOneBrc());
+        expectedIntents.addAll(generateVlanOneUni());
+        expectedIntents.addAll(generateVlanTwoBrc());
+        expectedIntents.addAll(generateVlanTwoUni());
+
+        checkIntents(expectedIntents);
+    }
+
+    /**
+     * Checks the case in which six ports are configured with VLANs and
+     * initially no hosts are registered by the HostService. The first three
+     * ports have an interface configured on VLAN1, the other three have an
+     * interface configured on VLAN2. When the module starts up, three hosts -
+     * on device one, two and three - port 1 (both on VLAN1), 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 nine: six for VLAN1, three for VLAN2.
+     * Six sp2mp intents, three mp2sp intents. IPs are added on the first two
+     * hosts only to demonstrate it doesn't influence the number of intents
+     * created.
+     * An additional host is added on device seven, port one to demonstrate
+     * that, even if it's on the same VLAN of other interfaces configured in
+     * the system, it doesn't let the application generate intents, since it's
+     * not connected to the interface configured.
+     */
+    @Test
+    public void testFourInterfacesThreeHostEventsSameVlan() {
+        vpls.activate();
+
+        Host h1 = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(1),
+                                  Collections.singleton(IP1));
+        Host h2 = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(2),
+                                  Collections.singleton(IP2));
+        Host h3 = new DefaultHost(PID, HID3, MAC3, VLAN1, getLocation(3),
+                                  Collections.EMPTY_SET);
+        Host h7 = new DefaultHost(PID, HID7, MAC7, VLAN1, getLocation(7),
+                                  Collections.EMPTY_SET);
+        hostsAvailable.addAll(Sets.newHashSet(h1, h2, h3, h7));
+
+        hostsAvailable.forEach(host ->
+            hostListener.event(new HostEvent(HostEvent.Type.HOST_ADDED, host)));
+
+        List<Intent> expectedIntents = new ArrayList<>();
+        expectedIntents.addAll(generateVlanOneBrc());
+        expectedIntents.addAll(generateVlanOneUni());
+        expectedIntents.addAll(generateVlanTwoBrc());
+
+        checkIntents(expectedIntents);
+    }
+
+    /**
+     * Checks the case in which six ports are configured with VLANs and
+     * initially no hosts are registered by the HostService. The first three
+     * ports have an interface configured on VLAN1, the other three have an
+     * interface configured on VLAN2. When the module starts up, two hosts -
+     * on device one and four - port 1 (VLAN 1 and VLAN 2), are registered by
+     * the HostService and events are sent to the application. sp2mp intents
+     * are created for all interfaces configured and no mp2sp intents are created
+     * at all, since the minimum number of hosts needed on the same vlan to
+     * create mp2sp intents is 2.
+     * The number of intents expected is six: three for VLAN1, three for VLAN2.
+     * six sp2mp intents, zero mp2sp intents. IPs are added on the first host
+     * only to demonstrate it doesn't influence the number of intents created.
+     */
+    @Test
+    public void testFourInterfacesTwoHostEventsDifferentVlan() {
+        vpls.activate();
+
+        Host h1 = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(1),
+                                  Collections.singleton(IP1));
+        Host h4 = new DefaultHost(PID, HID4, MAC4, VLAN2, getLocation(4),
+                                  Collections.EMPTY_SET);
+        hostsAvailable.addAll(Sets.newHashSet(h1, h4));
+
+        hostsAvailable.forEach(host -> {
+            hostListener.event(new HostEvent(HostEvent.Type.HOST_ADDED, host));
+        });
+
+        List<Intent> expectedIntents = new ArrayList<>();
+        expectedIntents.addAll(generateVlanOneBrc());
+        expectedIntents.addAll(generateVlanTwoBrc());
+
+        checkIntents(expectedIntents);
+    }
+
+    /**
+     * Checks both that the number of intents in submitted in the intent
+     * framework it's equal to the number of intents expected and that all
+     * intents are equivalent.
+     *
+     * @param intents the list of intents expected
+     */
+    private void checkIntents(List<Intent> intents) {
+        assertEquals(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("Comparing %s and %s", intentOne, intentTwo),
+                               IntentUtils.intentsAreEqual(intentOne, intentTwo));
+                    break;
+                }
+            }
+            assertTrue(found);
+        }
+    }
+
+    /**
+     * Generates the list of the expected sp2mp intents for VLAN 1.
+     *
+     * @return the list of expected sp2mp intents for VLAN 1
+     */
+    private List<SinglePointToMultiPointIntent> generateVlanOneBrc() {
+        Key key = null;
+
+        List<SinglePointToMultiPointIntent> intents = new ArrayList<>();
+
+        // Building sp2mp intent for H1 - VLAN1
+        key = Key.of((PREFIX_BROADCAST + "-" + DID1 + "-" + P1 + "-" + VLAN1),
+                     APPID);
+        intents.add(buildBrcIntent(key, C1, Sets.newHashSet(C2, C3), VLAN1));
+
+        // Building sp2mp intent for H2 - VLAN1
+        key = Key.of((PREFIX_BROADCAST + "-" + DID2 + "-" + P1 + "-" + VLAN1),
+                     APPID);
+        intents.add(buildBrcIntent(key, C2, Sets.newHashSet(C1, C3), VLAN1));
+
+        // Building sp2mp intent for H3 - VLAN1
+        key = Key.of((PREFIX_BROADCAST + "-" + DID3 + "-" + P1 + "-" + VLAN1),
+                     APPID);
+        intents.add(buildBrcIntent(key, C3, Sets.newHashSet(C1, C2), VLAN1));
+
+        return intents;
+    }
+
+    /**
+     * Generates the list of the expected mp2sp intents for VLAN 1.
+     *
+     * @return the list of expected mp2sp intents for VLAN 1
+     */
+    private List<MultiPointToSinglePointIntent> generateVlanOneUni() {
+        Key key = null;
+
+        List<MultiPointToSinglePointIntent> intents = new ArrayList<>();
+
+        // Building mp2sp intent for H1 - VLAN1
+        key = Key.of((PREFIX_UNICAST + "-" + DID1 + "-" + P1 + "-" + VLAN1),
+                     APPID);
+        intents.add(buildUniIntent(key, Sets.newHashSet(C2, C3), C1, VLAN1, MAC1));
+
+        // Building mp2sp intent for H2 - VLAN1
+        key = Key.of((PREFIX_UNICAST + "-" + DID2 + "-" + P1 + "-" + VLAN1),
+                     APPID);
+        intents.add(buildUniIntent(key, Sets.newHashSet(C1, C3), C2, VLAN1, MAC2));
+
+        // Building mp2sp intent for H3 - VLAN1
+        key = Key.of((PREFIX_UNICAST + "-" + DID3 + "-" + P1 + "-" + VLAN1),
+                     APPID);
+        intents.add(buildUniIntent(key, Sets.newHashSet(C1, C2), C3, VLAN1, MAC3));
+
+        return intents;
+    }
+
+    /**
+     * Generates the list of the expected sp2mp intents for VLAN 2.
+     *
+     * @return the list of expected sp2mp intents for VLAN 2
+     */
+    private List<SinglePointToMultiPointIntent> generateVlanTwoBrc() {
+        Key key = null;
+
+        List<SinglePointToMultiPointIntent> intents = new ArrayList<>();
+
+        // Building sp2mp intent for H4 - VLAN2
+        key = Key.of((PREFIX_BROADCAST + "-" + DID4 + "-" + P1 + "-" + VLAN2),
+                     APPID);
+        intents.add(buildBrcIntent(key, C4, Sets.newHashSet(C5, C6), VLAN2));
+
+        // Building sp2mp intent for H5 - VLAN2
+        key = Key.of((PREFIX_BROADCAST + "-" + DID5 + "-" + P1 + "-" + VLAN2),
+                     APPID);
+        intents.add(buildBrcIntent(key, C5, Sets.newHashSet(C4, C6), VLAN2));
+
+        // Building sp2mp intent for H6 - VLAN2
+        key = Key.of((PREFIX_BROADCAST + "-" + DID6 + "-" + P1 + "-" + VLAN2),
+                     APPID);
+        intents.add(buildBrcIntent(key, C6, Sets.newHashSet(C4, C5), VLAN2));
+
+        return intents;
+    }
+
+    /**
+     * Generates the list of the expected mp2sp intents for VLAN 2.
+     *
+     * @return the list of expected mp2sp intents for VLAN 2
+     */
+    private List<MultiPointToSinglePointIntent> generateVlanTwoUni() {
+        Key key = null;
+
+        List<MultiPointToSinglePointIntent> intents = new ArrayList<>();
+
+        // Building mp2sp intent for H4 - VLAN2
+        key = Key.of((PREFIX_UNICAST + "-" + DID4 + "-" + P1 + "-" + VLAN2),
+                     APPID);
+        intents.add(buildUniIntent(key, Sets.newHashSet(C5, C6), C4, VLAN2, MAC4));
+
+        // Building mp2sp intent for H5 - VLAN2
+        key = Key.of((PREFIX_UNICAST + "-" + DID5 + "-" + P1 + "-" + VLAN2),
+                     APPID);
+        intents.add(buildUniIntent(key, Sets.newHashSet(C4, C6), C5, VLAN2, MAC5));
+
+        // Building mp2sp intent for H6 - VLAN2
+        key = Key.of((PREFIX_UNICAST + "-" + DID6 + "-" + P1 + "-" + VLAN2),
+                     APPID);
+        intents.add(buildUniIntent(key, Sets.newHashSet(C4, C5), C6, VLAN2, MAC6));
+
+        return intents;
+    }
+
+    /**
+     * Builds a Single Point to Multi Point intent.
+     *
+     * @param key  The intent key
+     * @param src  The source Connect Point
+     * @param dsts The destination Connect Points
+     * @return Single Point to Multi Point intent generated.
+     */
+    private SinglePointToMultiPointIntent buildBrcIntent(Key key,
+                                                         ConnectPoint src,
+                                                         Set<ConnectPoint> dsts,
+                                                         VlanId vlanId) {
+        SinglePointToMultiPointIntent intent;
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthDst(MacAddress.BROADCAST)
+                .matchVlanId(vlanId)
+                .build();
+
+        intent = SinglePointToMultiPointIntent.builder()
+                .appId(APPID)
+                .key(key)
+                .selector(selector)
+                .treatment(treatment)
+                .ingressPoint(src)
+                .egressPoints(dsts)
+                .priority(PRIORITY_OFFSET)
+                .build();
+        return intent;
+    }
+
+    /**
+     * Builds a Multi Point to Single Point intent.
+     *
+     * @param key  The intent key
+     * @param srcs The source Connect Points
+     * @param dst  The destination Connect Point
+     * @return Multi Point to Single Point intent generated.
+     */
+    private MultiPointToSinglePointIntent buildUniIntent(Key key,
+                                                         Set<ConnectPoint> srcs,
+                                                         ConnectPoint dst,
+                                                         VlanId vlanId,
+                                                         MacAddress mac) {
+        MultiPointToSinglePointIntent intent;
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+
+        TrafficSelector.Builder builder = DefaultTrafficSelector.builder()
+                .matchEthDst(mac)
+                .matchVlanId(vlanId);
+
+        TrafficSelector selector = builder.build();
+
+        intent = MultiPointToSinglePointIntent.builder()
+                .appId(APPID)
+                .key(key)
+                .selector(selector)
+                .treatment(treatment)
+                .ingressPoints(srcs)
+                .egressPoint(dst)
+                .priority(PRIORITY_OFFSET)
+                .build();
+        return intent;
+    }
+
+    /**
+     * Returns the device ID of the ith device.
+     *
+     * @param i device to get the ID of
+     * @return the device ID
+     */
+    private static DeviceId getDeviceId(int i) {
+        return DeviceId.deviceId("" + i);
+    }
+
+    private static HostLocation getLocation(int i) {
+        return new HostLocation(new ConnectPoint(getDeviceId(i), P1), 123L);
+    }
+
+    /**
+     * Represents a fake IntentService class that easily allows to store and
+     * retrieve intents without implementing the IntentService logic.
+     */
+    private class TestIntentService extends IntentServiceAdapter {
+
+        private Set<Intent> intents;
+
+        public TestIntentService() {
+            intents = Sets.newHashSet();
+        }
+
+        @Override
+        public void submit(Intent intent) {
+            intents.add(intent);
+        }
+
+        @Override
+        public long getIntentCount() {
+            return intents.size();
+        }
+
+        @Override
+        public Iterable<Intent> getIntents() {
+            return intents;
+        }
+
+        @Override
+        public Intent getIntent(Key intentKey) {
+            for (Intent intent : intents) {
+                if (intent.key().equals(intentKey)) {
+                    return intent;
+                }
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Represents a fake HostService class which allows to add hosts manually
+     * in each test, when needed.
+     */
+    private class TestHostService extends HostServiceAdapter {
+
+        private Set<Host> hosts;
+
+        public TestHostService(Set<Host> hosts) {
+            this.hosts = hosts;
+        }
+
+        @Override
+        public void addListener(HostListener listener) {
+            VplsTest.this.hostListener = listener;
+        }
+
+        @Override
+        public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
+            return hosts.stream()
+                    .filter(h -> h.location().elementId().equals(connectPoint.elementId())
+                              && h.location().port().equals(connectPoint.port()))
+                    .collect(Collectors.toSet());
+        }
+
+    }
+
+    private static class TestIdGenerator implements IdGenerator {
+
+        private final AtomicLong id = new AtomicLong(0);
+
+        @Override
+        public long getNewId() {
+            return id.getAndIncrement();
+        }
+
+    }
+
+    /**
+     * Test IntentSynchronizer that passes all intents straight through to the
+     * intent service.
+     */
+    private class TestIntentSynchronizer implements IntentSynchronizationService,
+            IntentSynchronizationAdminService {
+
+        private final IntentService intentService;
+
+        /**
+         * Creates a new test intent synchronizer.
+         *
+         * @param intentService intent service
+         */
+        public TestIntentSynchronizer(IntentService intentService) {
+            this.intentService = intentService;
+        }
+
+        @Override
+        public void submit(Intent intent) {
+            intentService.submit(intent);
+        }
+
+        @Override
+        public void withdraw(Intent intent) {
+            intentService.withdraw(intent);
+        }
+
+        @Override
+        public void modifyPrimary(boolean isPrimary) {
+
+        }
+
+        @Override
+        public void removeIntents() {
+
+        }
+    }
+
+}
