diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java
index 38aad30..bd2c7c7 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java
@@ -91,8 +91,6 @@
             link(d2p1, d3p0)
     );
 
-
-
     final Set<Link> linksForSp2Mp = ImmutableSet.of(
             link(d3p0, d2p1),
             link(d2p0, d1p0)
@@ -103,6 +101,15 @@
             link(d2p1, d3p1)
     );
 
+    final Set<Link> linksForSp2MpCoLoc = ImmutableSet.of(
+            link(d1p0, d2p0),
+            link(d2p1, d3p0)
+    );
+
+    final Set<Link> linksForMp2SpCoLoc = ImmutableSet.of(
+            link(d2p0, d1p0)
+    );
+
     final TrafficTreatment treatment = emptyTreatment();
     final TrafficTreatment ethDstTreatment = macDstTreatment("C0:FF:EE:C0:FF:EE");
     final TrafficTreatment decTllTreatment = decTtlTreatment();
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionEncapIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionEncapIntentCompilerTest.java
index eb58cce..27ef08b 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionEncapIntentCompilerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionEncapIntentCompilerTest.java
@@ -43,14 +43,12 @@
 import java.util.List;
 import java.util.stream.Collectors;
 
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.*;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.core.Is.is;
 import static org.onlab.packet.EthType.EtherType.IPV4;
-import static org.onosproject.net.NetTestTools.*;
+import static org.onosproject.net.NetTestTools.APP_ID;
 import static org.onosproject.net.flow.criteria.Criterion.Type.*;
 import static org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
 
@@ -64,8 +62,7 @@
     public void setUp() {
         sut = new LinkCollectionIntentCompiler();
         coreService = createMock(CoreService.class);
-        expect(coreService.registerApplication("org.onosproject.net.intent"))
-                .andReturn(appId);
+        expect(coreService.registerApplication("org.onosproject.net.intent")).andReturn(appId);
         sut.coreService = coreService;
 
         Intent.bindIdGenerator(idGenerator);
@@ -101,11 +98,8 @@
     public void testVlanEncapsulationForMp() {
 
         intent = LinkCollectionIntent.builder()
-                .appId(APP_ID)
-                .selector(selector)
-                .treatment(treatment)
-                .constraints(constraintsForVlan)
-                .links(linksForMp2Sp)
+                .appId(APP_ID).selector(selector).treatment(treatment)
+                .constraints(constraintsForVlan).links(linksForMp2Sp)
                 .filteredIngressPoints(ImmutableSet.of(
                         new FilteredConnectPoint(d1p10),
                         new FilteredConnectPoint(d1p11),
@@ -134,9 +128,7 @@
                 .filter(rule -> {
                         PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
                         return inPort.port().equals(d1p10.port());
-                })
-                .findFirst()
-                .get();
+                }).findFirst().get();
         assertThat(ruleS1.selector(), is(
                 DefaultTrafficSelector
                         .builder(intent.selector())
@@ -253,23 +245,17 @@
     public void testMplsEncapsulationForSp() {
 
         intent = LinkCollectionIntent.builder()
-                .appId(APP_ID)
-                .selector(selector)
-                .treatment(treatment)
-                .constraints(constraintsForMPLS)
-                .links(linksForSp2Mp)
+                .appId(APP_ID).selector(selector).treatment(treatment)
+                .constraints(constraintsForMPLS).links(linksForSp2Mp)
                 .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10)))
                 .filteredEgressPoints(ImmutableSet.of(
                         new FilteredConnectPoint(d1p10),
                         new FilteredConnectPoint(d1p11),
                         new FilteredConnectPoint(d2p10)
-                ))
-                .build();
+                )).build();
 
         sut.activate();
-        /*
-         * We use the FIRST_FIT to simplify tests.
-         */
+
         LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
 
         List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -356,23 +342,17 @@
     public void testMplsEncapsulationFilteredForMp() {
 
         intent = LinkCollectionIntent.builder()
-                .appId(APP_ID)
-                .selector(selector)
-                .treatment(treatment)
-                .constraints(constraintsForMPLS)
-                .links(linksForMp2Sp)
+                .appId(APP_ID).selector(selector).treatment(treatment)
+                .constraints(constraintsForMPLS).links(linksForMp2Sp)
                 .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, vlan69Selector)))
                 .filteredIngressPoints(ImmutableSet.of(
                         new FilteredConnectPoint(d1p10, vlan100Selector),
                         new FilteredConnectPoint(d1p11, vlan200Selector),
                         new FilteredConnectPoint(d2p10, vlan300Selector)
-                ))
-                .build();
+                )).build();
 
         sut.activate();
-        /*
-         * We use the FIRST_FIT to simplify tests.
-         */
+
         LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
 
         List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -516,23 +496,17 @@
     public void testVlanEncapsulationFilteredForSp() {
 
         intent = LinkCollectionIntent.builder()
-                .appId(APP_ID)
-                .selector(selector)
-                .treatment(treatment)
-                .constraints(constraintsForVlan)
-                .links(linksForSp2Mp)
+                .appId(APP_ID).selector(selector).treatment(treatment)
+                .constraints(constraintsForVlan).links(linksForSp2Mp)
                 .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls69Selector)))
                 .filteredEgressPoints(ImmutableSet.of(
                         new FilteredConnectPoint(d1p10, mpls100Selector),
                         new FilteredConnectPoint(d1p11, mpls200Selector),
                         new FilteredConnectPoint(d2p10, mpls80Selector)
-                ))
-                .build();
+                )).build();
 
         sut.activate();
-        /*
-         * We use the FIRST_FIT to simplify tests.
-         */
+
         LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
 
         List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -624,23 +598,17 @@
     public void testVlanEncapsulationNonTrivialForMp() {
 
         intent = LinkCollectionIntent.builder()
-                .appId(APP_ID)
-                .selector(ipPrefixSelector)
-                .treatment(ethDstTreatment)
-                .constraints(constraintsForVlan)
-                .links(linksForMp2Sp)
+                .appId(APP_ID).selector(ipPrefixSelector).treatment(ethDstTreatment)
+                .constraints(constraintsForVlan).links(linksForMp2Sp)
                 .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls69Selector)))
                 .filteredIngressPoints(ImmutableSet.of(
                         new FilteredConnectPoint(d1p10, mpls80Selector),
                         new FilteredConnectPoint(d1p11, mpls100Selector),
                         new FilteredConnectPoint(d2p10, mpls200Selector)
-                ))
-                .build();
+                )).build();
 
         sut.activate();
-        /*
-         * We use the FIRST_FIT to simplify tests.
-         */
+
         LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
 
         List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -786,23 +754,17 @@
     public void testMplsEncapsulationNonTrivialForSp() {
 
         intent = LinkCollectionIntent.builder()
-                .appId(APP_ID)
-                .selector(ipPrefixSelector)
-                .treatment(ethDstTreatment)
-                .constraints(constraintsForMPLS)
-                .links(linksForSp2Mp)
+                .appId(APP_ID).selector(ipPrefixSelector).treatment(ethDstTreatment)
+                .constraints(constraintsForMPLS).links(linksForSp2Mp)
                 .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, vlan69Selector)))
                 .filteredEgressPoints(ImmutableSet.of(
                         new FilteredConnectPoint(d1p10, vlan100Selector),
                         new FilteredConnectPoint(d1p11, vlan200Selector),
                         new FilteredConnectPoint(d2p10, vlan300Selector)
-                ))
-                .build();
+                )).build();
 
         sut.activate();
-        /*
-         * We use the FIRST_FIT to simplify tests.
-         */
+
         LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
 
         List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -912,23 +874,17 @@
     public void testMplsEncapsulationDifferentFilterForMp() {
 
         intent = LinkCollectionIntent.builder()
-                .appId(APP_ID)
-                .selector(selector)
-                .treatment(treatment)
-                .constraints(constraintsForMPLS)
-                .links(linksForMp2Sp)
+                .appId(APP_ID).selector(selector).treatment(treatment)
+                .constraints(constraintsForMPLS).links(linksForMp2Sp)
                 .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls100Selector)))
                 .filteredIngressPoints(ImmutableSet.of(
                         new FilteredConnectPoint(d1p10, vlan100Selector),
                         new FilteredConnectPoint(d1p11, mpls200Selector),
                         new FilteredConnectPoint(d2p10, vlan200Selector)
-                ))
-                .build();
+                )).build();
 
         sut.activate();
-        /*
-         * We use the FIRST_FIT to simplify tests.
-         */
+
         LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
 
         List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -1065,26 +1021,20 @@
      * encapsulation and filtered selectors of different type.
      */
     @Test
-    public void testVlanEncapsulationDifferentFilter() {
+    public void testVlanEncapsulationDifferentFilterForSp() {
 
         intent = LinkCollectionIntent.builder()
-                .appId(APP_ID)
-                .selector(selector)
-                .treatment(treatment)
-                .constraints(constraintsForVlan)
-                .links(linksForSp2Mp)
+                .appId(APP_ID).selector(selector).treatment(treatment)
+                .constraints(constraintsForVlan).links(linksForSp2Mp)
                 .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, vlan200Selector)))
                 .filteredEgressPoints(ImmutableSet.of(
                         new FilteredConnectPoint(d1p10, mpls100Selector),
                         new FilteredConnectPoint(d1p11, vlan100Selector),
                         new FilteredConnectPoint(d2p10, mpls200Selector)
-                ))
-                .build();
+                )).build();
 
         sut.activate();
-        /*
-         * We use the FIRST_FIT to simplify tests.
-         */
+
         LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
 
         List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -1165,26 +1115,26 @@
     }
 
     /**
-     * We test the proper compilation of p2p with the VLAN
-     * encapsulation and trivial filtered points.
+     * We test the proper compilation of sp2mp with trivial selector,
+     * trivial treatment, vlan encapsulation and co-located
+     * ingress/egress points.
      */
     @Test
-    public void testVlanEncapsulationForP2P() {
+    public void testCoLocatedPointsTrivialForSp() {
 
         intent = LinkCollectionIntent.builder()
-                .appId(APP_ID)
-                .selector(selector)
-                .treatment(treatment)
+                .appId(APP_ID).selector(selector).treatment(treatment)
+                .applyTreatmentOnEgress(true).links(linksForSp2MpCoLoc)
                 .constraints(constraintsForVlan)
-                .links(linksForMp2Sp)
-                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
-                .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls200Selector)))
-                .build();
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10)))
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p11),
+                        new FilteredConnectPoint(d2p10),
+                        new FilteredConnectPoint(d3p10)
+                )).build();
 
         sut.activate();
-        /*
-         * We use the FIRST_FIT to simplify tests.
-         */
+
         LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
 
         List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -1197,18 +1147,21 @@
                 .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
                 .collect(Collectors.toSet());
         assertThat(rulesS1, hasSize(1));
+
         FlowRule ruleS1 = rulesS1.iterator().next();
         assertThat(ruleS1.selector(), is(
                 DefaultTrafficSelector
-                        .builder(vlan100Selector)
+                        .builder(selector)
                         .matchInPort(d1p10.port())
                         .build()
         ));
         assertThat(ruleS1.treatment(), is(
                 DefaultTrafficTreatment
                         .builder()
+                        .pushVlan()
                         .setVlanId(VlanId.vlanId(LABEL))
                         .setOutput(d1p0.port())
+                        .setOutput(d1p11.port())
                         .build()
         ));
 
@@ -1216,6 +1169,7 @@
                 .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
                 .collect(Collectors.toSet());
         assertThat(rulesS2, hasSize(1));
+
         FlowRule ruleS2 = rulesS2.iterator().next();
         assertThat(ruleS2.selector(), is(
                 DefaultTrafficSelector
@@ -1229,13 +1183,16 @@
                         .builder()
                         .setVlanId(VlanId.vlanId(LABEL))
                         .setOutput(d2p1.port())
+                        .popVlan()
+                        .setOutput(d2p10.port())
                         .build()
         ));
 
         Collection<FlowRule> rulesS3 = rules.stream()
-                .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
+                .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
                 .collect(Collectors.toSet());
         assertThat(rulesS3, hasSize(1));
+
         FlowRule ruleS3 = rulesS3.iterator().next();
         assertThat(ruleS3.selector(), is(
                 DefaultTrafficSelector
@@ -1248,8 +1205,6 @@
                 DefaultTrafficTreatment
                         .builder()
                         .popVlan()
-                        .pushMpls()
-                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
                         .setOutput(d3p10.port())
                         .build()
         ));
@@ -1259,26 +1214,127 @@
     }
 
     /**
-     * We test the proper compilation of p2p with the MPLS
-     * encapsulation and trivial filtered points.
+     * We test the proper compilation of mp2sp with trivial selector,
+     * trivial treatment, mpls encapsulation and co-located
+     * ingress/egress points.
      */
     @Test
-    public void testMplsEncapsulationForP2P() {
+    public void testCoLocatedPointsTrivialForMp() {
 
         intent = LinkCollectionIntent.builder()
-                .appId(APP_ID)
-                .selector(selector)
-                .treatment(treatment)
+                .appId(APP_ID).selector(selector).treatment(treatment)
+                .links(linksForMp2SpCoLoc).constraints(constraintsForMPLS)
+                .filteredIngressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10),
+                        new FilteredConnectPoint(d2p10)
+                ))
+                .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p11)))
+                .build();
+
+        sut.activate();
+
+        LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(2));
+
+        FlowRule ruleS1 = rulesS1.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d1p10.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d1p10.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        ruleS1 = rulesS1.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d1p0.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchEthType(Ethernet.MPLS_UNICAST)
+                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+                        .matchInPort(d1p0.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popMpls(IPV4.ethType())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS2 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS2, hasSize(1));
+
+        FlowRule ruleS2 = rulesS2.iterator().next();
+        assertThat(ruleS2.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d2p10.port())
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .pushMpls()
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
+                        .setOutput(d2p0.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of sp2mp with trivial selector,
+     * trivial treatment, mpls encapsulation and co-located
+     * filtered ingress/egress points.
+     */
+    @Test
+    public void testCoLocatedFilteredPointsTrivialForSp() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID).selector(selector).treatment(treatment)
+                .applyTreatmentOnEgress(true).links(linksForSp2MpCoLoc)
                 .constraints(constraintsForMPLS)
-                .links(linksForMp2Sp)
                 .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
-                .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls200Selector)))
-                .build();
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p11, vlan200Selector),
+                        new FilteredConnectPoint(d2p10, vlan300Selector),
+                        new FilteredConnectPoint(d3p10, vlan69Selector)
+                )).build();
 
         sut.activate();
-        /*
-         * We use the FIRST_FIT to simplify tests.
-         */
+
         LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
 
         List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -1291,6 +1347,7 @@
                 .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
                 .collect(Collectors.toSet());
         assertThat(rulesS1, hasSize(1));
+
         FlowRule ruleS1 = rulesS1.iterator().next();
         assertThat(ruleS1.selector(), is(
                 DefaultTrafficSelector
@@ -1305,20 +1362,24 @@
                         .pushMpls()
                         .setMpls(MplsLabel.mplsLabel(LABEL))
                         .setOutput(d1p0.port())
+                        .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d1p11.port())
                         .build()
         ));
 
+
         Collection<FlowRule> rulesS2 = rules.stream()
                 .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
                 .collect(Collectors.toSet());
         assertThat(rulesS2, hasSize(1));
+
         FlowRule ruleS2 = rulesS2.iterator().next();
         assertThat(ruleS2.selector(), is(
                 DefaultTrafficSelector
                         .builder()
                         .matchInPort(d2p0.port())
-                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
                         .matchEthType(Ethernet.MPLS_UNICAST)
+                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
                         .build()
         ));
         assertThat(ruleS2.treatment(), is(
@@ -1326,26 +1387,34 @@
                         .builder()
                         .setMpls(MplsLabel.mplsLabel(LABEL))
                         .setOutput(d2p1.port())
+                        .popMpls(IPV4.ethType())
+                        .pushVlan()
+                        .setVlanId(((VlanIdCriterion) vlan300Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d2p10.port())
                         .build()
         ));
 
+
         Collection<FlowRule> rulesS3 = rules.stream()
-                .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
+                .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
                 .collect(Collectors.toSet());
         assertThat(rulesS3, hasSize(1));
+
         FlowRule ruleS3 = rulesS3.iterator().next();
         assertThat(ruleS3.selector(), is(
                 DefaultTrafficSelector
                         .builder()
                         .matchInPort(d3p0.port())
-                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
                         .matchEthType(Ethernet.MPLS_UNICAST)
+                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
                         .build()
         ));
         assertThat(ruleS3.treatment(), is(
                 DefaultTrafficTreatment
                         .builder()
-                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+                        .popMpls(IPV4.ethType())
+                        .pushVlan()
+                        .setVlanId(((VlanIdCriterion) vlan69Selector.getCriterion(VLAN_VID)).vlanId())
                         .setOutput(d3p10.port())
                         .build()
         ));
@@ -1355,26 +1424,25 @@
     }
 
     /**
-     * We test the proper compilation of p2p with the VLAN
-     * encapsulation, filtered points, selector and treatment.
+     * We test the proper compilation of mp2sp with trivial selector,
+     * trivial treatment, vlan encapsulation and co-located
+     * filtered ingress/egress points.
      */
     @Test
-    public void testVlanEncapsulationNonTrivialForP2P() {
+    public void testCoLocatedFilteredPointsTrivialForMp() {
 
         intent = LinkCollectionIntent.builder()
-                .appId(APP_ID)
-                .selector(ipPrefixSelector)
-                .treatment(ethDstTreatment)
+                .appId(APP_ID).selector(selector).treatment(treatment).links(linksForMp2SpCoLoc)
                 .constraints(constraintsForVlan)
-                .links(linksForMp2Sp)
-                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
-                .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls69Selector)))
+                .filteredIngressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10, mpls100Selector),
+                        new FilteredConnectPoint(d2p10, mpls200Selector)
+                ))
+                .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p11, mpls69Selector)))
                 .build();
 
         sut.activate();
-        /*
-         * We use the FIRST_FIT to simplify tests.
-         */
+
         LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
 
         List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -1386,66 +1454,170 @@
         Collection<FlowRule> rulesS1 = rules.stream()
                 .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
                 .collect(Collectors.toSet());
-        assertThat(rulesS1, hasSize(1));
-        FlowRule ruleS1 = rulesS1.iterator().next();
+        assertThat(rulesS1, hasSize(2));
+
+        FlowRule ruleS1 = rulesS1.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d1p10.port());
+                })
+                .findFirst()
+                .get();
         assertThat(ruleS1.selector(), is(
                 DefaultTrafficSelector
-                        .builder(ipPrefixSelector)
+                        .builder(mpls100Selector)
                         .matchInPort(d1p10.port())
-                        .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
                         .build()
         ));
         assertThat(ruleS1.treatment(), is(
                 DefaultTrafficTreatment
                         .builder()
-                        .setVlanId(VlanId.vlanId(LABEL))
-                        .setOutput(d1p0.port())
+                        .setMpls(((MplsCriterion) mpls69Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p11.port())
                         .build()
         ));
 
-        Collection<FlowRule> rulesS2 = rules.stream()
-                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
-                .collect(Collectors.toSet());
-        assertThat(rulesS2, hasSize(1));
-        FlowRule ruleS2 = rulesS2.iterator().next();
-        assertThat(ruleS2.selector(), is(
+        ruleS1 = rulesS1.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d1p0.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS1.selector(), is(
                 DefaultTrafficSelector
                         .builder()
-                        .matchInPort(d2p0.port())
                         .matchVlanId(VlanId.vlanId(LABEL))
+                        .matchInPort(d1p0.port())
                         .build()
         ));
-        assertThat(ruleS2.treatment(), is(
+        assertThat(ruleS1.treatment(), is(
                 DefaultTrafficTreatment
                         .builder()
-                        .setVlanId(VlanId.vlanId(LABEL))
-                        .setOutput(d2p1.port())
-                        .build()
-        ));
-
-        Collection<FlowRule> rulesS3 = rules.stream()
-                .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
-                .collect(Collectors.toSet());
-        assertThat(rulesS3, hasSize(1));
-        FlowRule ruleS3 = rulesS3.iterator().next();
-        assertThat(ruleS3.selector(), is(
-                DefaultTrafficSelector
-                        .builder()
-                        .matchInPort(d3p0.port())
-                        .matchVlanId(VlanId.vlanId(LABEL))
-                        .build()
-        ));
-        assertThat(ruleS3.treatment(), is(
-                DefaultTrafficTreatment
-                        .builder()
-                        .setEthDst(((ModEtherInstruction) ethDstTreatment
-                                .allInstructions()
-                                .stream()
-                                .filter(instruction -> instruction instanceof ModEtherInstruction)
-                                .findFirst().get()).mac())
                         .popVlan()
                         .pushMpls()
                         .setMpls(((MplsCriterion) mpls69Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS2 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS2, hasSize(1));
+        FlowRule ruleS2 = rulesS2.iterator().next();
+        assertThat(ruleS2.selector(), is(
+                DefaultTrafficSelector
+                        .builder(mpls200Selector)
+                        .matchInPort(d2p10.port())
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popMpls(IPV4.ethType())
+                        .pushVlan()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d2p0.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of sp2mp with trivial selector,
+     * trivial treatment, vlan encapsulation and co-located
+     * different filtered ingress/egress points.
+     */
+    @Test
+    public void testCoLocatedDifferentFilteredPointsTrivialForSp() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID).selector(selector).treatment(treatment)
+                .applyTreatmentOnEgress(true).links(linksForSp2MpCoLoc)
+                .constraints(constraintsForVlan)
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p11, mpls100Selector),
+                        new FilteredConnectPoint(d2p10, vlan200Selector),
+                        new FilteredConnectPoint(d3p10, mpls200Selector)
+                )).build();
+
+        sut.activate();
+
+        LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(1));
+        FlowRule ruleS1 = rulesS1.iterator().next();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder(vlan100Selector)
+                        .matchInPort(d1p10.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d1p0.port())
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS2 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS2, hasSize(1));
+        FlowRule ruleS2 = rulesS2.iterator().next();
+        assertThat(ruleS2.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d2p0.port())
+                        .matchVlanId(VlanId.vlanId(LABEL))
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d2p1.port())
+                        .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d2p10.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS3 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS3, hasSize(1));
+        FlowRule ruleS3 = rulesS3.iterator().next();
+        assertThat(ruleS3.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchVlanId(VlanId.vlanId(LABEL))
+                        .matchInPort(d3p0.port())
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
                         .setOutput(d3p10.port())
                         .build()
         ));
@@ -1455,26 +1627,126 @@
     }
 
     /**
-     * We test the proper compilation of p2p with the MPLS
-     * encapsulation, filtered points, selector and treatment.
+     * We test the proper compilation of mp2sp with trivial selector,
+     * trivial treatment, mpls encapsulation and co-located
+     * filtered ingress/egress points.
      */
     @Test
-    public void testMplsEncapsulationNonTrivialForP2P() {
+    public void testCoLocatedDifferentFilteredPointsTrivialForMp() {
 
         intent = LinkCollectionIntent.builder()
-                .appId(APP_ID)
-                .selector(ipPrefixSelector)
-                .treatment(ethDstTreatment)
-                .constraints(constraintsForMPLS)
-                .links(linksForMp2Sp)
-                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
-                .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls69Selector)))
+                .appId(APP_ID).selector(selector).treatment(treatment)
+                .links(linksForMp2SpCoLoc).constraints(constraintsForMPLS)
+                .filteredIngressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10, mpls100Selector),
+                        new FilteredConnectPoint(d2p10, vlan100Selector)
+                ))
+                .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p11, mpls200Selector)))
                 .build();
 
         sut.activate();
-        /*
-         * We use the FIRST_FIT to simplify tests.
-         */
+
+        LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(2));
+        FlowRule ruleS1 = rulesS1.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d1p10.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder(mpls100Selector)
+                        .matchInPort(d1p10.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+        ruleS1 = rulesS1.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d1p0.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchEthType(Ethernet.MPLS_UNICAST)
+                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+                        .matchInPort(d1p0.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS2 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS2, hasSize(1));
+        FlowRule ruleS2 = rulesS2.iterator().next();
+        assertThat(ruleS2.selector(), is(
+                DefaultTrafficSelector
+                        .builder(vlan100Selector)
+                        .matchInPort(d2p10.port())
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
+                        .setOutput(d2p0.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of sp2mp with selector,
+     * treatment, mpls encapsulation and co-located
+     * different filtered ingress/egress points.
+     */
+    @Test
+    public void testCoLocatedDifferentFilteredPointsNonTrivialForSp() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID).selector(ipPrefixSelector).treatment(ethDstTreatment)
+                .applyTreatmentOnEgress(true).links(linksForSp2MpCoLoc)
+                .constraints(constraintsForMPLS)
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p11, mpls100Selector),
+                        new FilteredConnectPoint(d2p10, vlan200Selector),
+                        new FilteredConnectPoint(d3p10, mpls200Selector)
+                )).build();
+
+        sut.activate();
+
         LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
 
         List<Intent> compiled = sut.compile(intent, Collections.emptyList());
@@ -1502,6 +1774,15 @@
                         .pushMpls()
                         .setMpls(MplsLabel.mplsLabel(LABEL))
                         .setOutput(d1p0.port())
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                .allInstructions()
+                                .stream()
+                                .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                .findFirst().get()).mac())
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p11.port())
                         .build()
         ));
 
@@ -1514,8 +1795,8 @@
                 DefaultTrafficSelector
                         .builder()
                         .matchInPort(d2p0.port())
-                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
                         .matchEthType(Ethernet.MPLS_UNICAST)
+                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
                         .build()
         ));
         assertThat(ruleS2.treatment(), is(
@@ -1523,20 +1804,29 @@
                         .builder()
                         .setMpls(MplsLabel.mplsLabel(LABEL))
                         .setOutput(d2p1.port())
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                .allInstructions()
+                                .stream()
+                                .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                .findFirst().get()).mac())
+                        .popMpls(IPV4.ethType())
+                        .pushVlan()
+                        .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d2p10.port())
                         .build()
         ));
 
         Collection<FlowRule> rulesS3 = rules.stream()
-                .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
+                .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
                 .collect(Collectors.toSet());
         assertThat(rulesS3, hasSize(1));
         FlowRule ruleS3 = rulesS3.iterator().next();
         assertThat(ruleS3.selector(), is(
                 DefaultTrafficSelector
                         .builder()
-                        .matchInPort(d3p0.port())
-                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
                         .matchEthType(Ethernet.MPLS_UNICAST)
+                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+                        .matchInPort(d3p0.port())
                         .build()
         ));
         assertThat(ruleS3.treatment(), is(
@@ -1547,7 +1837,7 @@
                                 .stream()
                                 .filter(instruction -> instruction instanceof ModEtherInstruction)
                                 .findFirst().get()).mac())
-                        .setMpls(((MplsCriterion) mpls69Selector.getCriterion(MPLS_LABEL)).label())
+                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
                         .setOutput(d3p10.port())
                         .build()
         ));
@@ -1556,4 +1846,116 @@
 
     }
 
+    /**
+     * We test the proper compilation of mp2sp with selector,
+     * treatment, vlan encapsulation and co-located
+     * filtered ingress/egress points.
+     */
+    @Test
+    public void testCoLocatedDifferentFilteredPointsNonTrivialForMp() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID).selector(ipPrefixSelector).treatment(ethDstTreatment)
+                .links(linksForMp2SpCoLoc).constraints(constraintsForVlan)
+                .filteredIngressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10, mpls100Selector),
+                        new FilteredConnectPoint(d2p10, vlan100Selector)
+                ))
+                .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p11, mpls200Selector)))
+                .build();
+
+        sut.activate();
+
+        LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(2));
+        FlowRule ruleS1 = rulesS1.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d1p10.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder(ipPrefixSelector)
+                        .matchInPort(d1p10.port())
+                        .matchMplsLabel(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                .allInstructions()
+                                .stream()
+                                .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                .findFirst().get()).mac())
+                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        ruleS1 = rulesS1.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d1p0.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchVlanId(VlanId.vlanId(LABEL))
+                        .matchInPort(d1p0.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                .allInstructions()
+                                .stream()
+                                .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                .findFirst().get()).mac())
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS2 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS2, hasSize(1));
+        FlowRule ruleS2 = rulesS2.iterator().next();
+        assertThat(ruleS2.selector(), is(
+                DefaultTrafficSelector
+                        .builder(ipPrefixSelector)
+                        .matchInPort(d2p10.port())
+                        .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d2p0.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
 }
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompilerP2PTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompilerP2PTest.java
new file mode 100644
index 0000000..84720b5
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompilerP2PTest.java
@@ -0,0 +1,768 @@
+/*
+ * 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.net.intent.impl.compiler;
+
+import com.google.common.collect.ImmutableSet;
+import org.hamcrest.core.Is;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onosproject.cfg.ComponentConfigAdapter;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.criteria.MplsCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.intent.FlowRuleIntent;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentExtensionService;
+import org.onosproject.net.intent.LinkCollectionIntent;
+import org.onosproject.net.resource.MockResourceService;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.core.Is.is;
+import static org.onosproject.net.NetTestTools.APP_ID;
+import static org.onosproject.net.flow.criteria.Criterion.Type.MPLS_LABEL;
+import static org.onosproject.net.flow.criteria.Criterion.Type.VLAN_VID;
+import static org.onosproject.net.flow.instructions.L2ModificationInstruction.*;
+
+/**
+ * This set of tests are meant to test the proper compilation
+ * of p2p intents.
+ */
+public class LinkCollectionIntentCompilerP2PTest extends AbstractLinkCollectionTest {
+
+    @Before
+    public void setUp() {
+        sut = new LinkCollectionIntentCompiler();
+        coreService = createMock(CoreService.class);
+        expect(coreService.registerApplication("org.onosproject.net.intent"))
+                .andReturn(appId);
+        sut.coreService = coreService;
+
+        Intent.bindIdGenerator(idGenerator);
+
+        intentExtensionService = createMock(IntentExtensionService.class);
+        intentExtensionService.registerCompiler(LinkCollectionIntent.class, sut);
+        intentExtensionService.unregisterCompiler(LinkCollectionIntent.class);
+
+        registrator = new IntentConfigurableRegistrator();
+        registrator.extensionService = intentExtensionService;
+        registrator.cfgService = new ComponentConfigAdapter();
+        registrator.activate();
+
+        sut.registrator = registrator;
+        sut.resourceService = new MockResourceService();
+
+        LinkCollectionCompiler.optimize = false;
+        LinkCollectionCompiler.copyTtl = false;
+
+        replay(coreService, intentExtensionService);
+    }
+
+    @After
+    public void tearDown() {
+        Intent.unbindIdGenerator(idGenerator);
+    }
+
+    /**
+     * We test the proper compilation of p2p with
+     * trivial selector and trivial treatment.
+     */
+    @Test
+    public void testCompilationTrivialForP2P() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(treatment)
+                .applyTreatmentOnEgress(true)
+                .links(p2pLinks)
+                .filteredIngressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10)
+                ))
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d3p0)
+                ))
+                .build();
+
+        sut.activate();
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(1));
+        FlowRule ruleS1 = rulesS1.iterator().next();
+        assertThat(ruleS1.selector(), Is.is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d1p10.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setOutput(d1p0.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS2 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS2, hasSize(1));
+        FlowRule ruleS2 = rulesS2.iterator().next();
+        assertThat(ruleS2.selector(), Is.is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d2p0.port())
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setOutput(d2p1.port())
+                        .build()
+        ));
+
+
+        Collection<FlowRule> rulesS3 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS3, hasSize(1));
+        FlowRule ruleS3 = rulesS3.iterator().next();
+        assertThat(ruleS3.selector(), Is.is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d3p1.port())
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setOutput(d3p0.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of p2p with
+     * trivial selector, trivial treatment and
+     * filtered points.
+     */
+    @Test
+    public void testCompilationFilteredPointForP2P() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(treatment)
+                .applyTreatmentOnEgress(true)
+                .links(p2pLinks)
+                .filteredIngressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10, vlan100Selector)
+                ))
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d3p0, mpls200Selector)
+                ))
+                .build();
+
+        sut.activate();
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(1));
+        FlowRule ruleS1 = rulesS1.iterator().next();
+        assertThat(ruleS1.selector(), Is.is(
+                DefaultTrafficSelector
+                        .builder(vlan100Selector)
+                        .matchInPort(d1p10.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setOutput(d1p0.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS2 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS2, hasSize(1));
+        FlowRule ruleS2 = rulesS2.iterator().next();
+        assertThat(ruleS2.selector(), Is.is(
+                DefaultTrafficSelector
+                        .builder(vlan100Selector)
+                        .matchInPort(d2p0.port())
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setOutput(d2p1.port())
+                        .build()
+        ));
+
+
+        Collection<FlowRule> rulesS3 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS3, hasSize(1));
+        FlowRule ruleS3 = rulesS3.iterator().next();
+        assertThat(ruleS3.selector(), Is.is(
+                DefaultTrafficSelector
+                        .builder(vlan100Selector)
+                        .matchInPort(d3p1.port())
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d3p0.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of p2p with
+     * selector, treatment and filtered points.
+     */
+    @Test
+    public void testCompilationNonTrivialForP2P() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(ipPrefixSelector)
+                .treatment(ethDstTreatment)
+                .applyTreatmentOnEgress(true)
+                .links(p2pLinks)
+                .filteredIngressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10, vlan100Selector)
+                ))
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d3p0, mpls200Selector)
+                ))
+                .build();
+
+        sut.activate();
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(1));
+        FlowRule ruleS1 = rulesS1.iterator().next();
+        assertThat(ruleS1.selector(), Is.is(
+                DefaultTrafficSelector
+                        .builder(ipPrefixSelector)
+                        .matchInPort(d1p10.port())
+                        .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setOutput(d1p0.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS2 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS2, hasSize(1));
+        FlowRule ruleS2 = rulesS2.iterator().next();
+        assertThat(ruleS2.selector(), Is.is(
+                DefaultTrafficSelector
+                        .builder(ipPrefixSelector)
+                        .matchInPort(d2p0.port())
+                        .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setOutput(d2p1.port())
+                        .build()
+        ));
+
+
+        Collection<FlowRule> rulesS3 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS3, hasSize(1));
+        FlowRule ruleS3 = rulesS3.iterator().next();
+        assertThat(ruleS3.selector(), Is.is(
+                DefaultTrafficSelector
+                        .builder(ipPrefixSelector)
+                        .matchInPort(d3p1.port())
+                        .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                .allInstructions()
+                                .stream()
+                                .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                .findFirst().get()).mac())
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d3p0.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of p2p with the VLAN
+     * encapsulation and trivial filtered points.
+     */
+    @Test
+    public void testVlanEncapsulationForP2P() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(treatment)
+                .constraints(constraintsForVlan)
+                .links(linksForMp2Sp)
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
+                .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls200Selector)))
+                .build();
+
+        sut.activate();
+        /*
+         * We use the FIRST_FIT to simplify tests.
+         */
+        LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(1));
+        FlowRule ruleS1 = rulesS1.iterator().next();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder(vlan100Selector)
+                        .matchInPort(d1p10.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d1p0.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS2 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS2, hasSize(1));
+        FlowRule ruleS2 = rulesS2.iterator().next();
+        assertThat(ruleS2.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d2p0.port())
+                        .matchVlanId(VlanId.vlanId(LABEL))
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d2p1.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS3 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS3, hasSize(1));
+        FlowRule ruleS3 = rulesS3.iterator().next();
+        assertThat(ruleS3.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d3p0.port())
+                        .matchVlanId(VlanId.vlanId(LABEL))
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d3p10.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+
+    /**
+     * We test the proper compilation of p2p with the MPLS
+     * encapsulation and trivial filtered points.
+     */
+    @Test
+    public void testMplsEncapsulationForP2P() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(treatment)
+                .constraints(constraintsForMPLS)
+                .links(linksForMp2Sp)
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
+                .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls200Selector)))
+                .build();
+
+        sut.activate();
+        /*
+         * We use the FIRST_FIT to simplify tests.
+         */
+        LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(1));
+        FlowRule ruleS1 = rulesS1.iterator().next();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder(vlan100Selector)
+                        .matchInPort(d1p10.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
+                        .setOutput(d1p0.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS2 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS2, hasSize(1));
+        FlowRule ruleS2 = rulesS2.iterator().next();
+        assertThat(ruleS2.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d2p0.port())
+                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+                        .matchEthType(Ethernet.MPLS_UNICAST)
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
+                        .setOutput(d2p1.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS3 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS3, hasSize(1));
+        FlowRule ruleS3 = rulesS3.iterator().next();
+        assertThat(ruleS3.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d3p0.port())
+                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+                        .matchEthType(Ethernet.MPLS_UNICAST)
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d3p10.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of p2p with the VLAN
+     * encapsulation, filtered points, selector and treatment.
+     */
+    @Test
+    public void testVlanEncapsulationNonTrivialForP2P() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(ipPrefixSelector)
+                .treatment(ethDstTreatment)
+                .constraints(constraintsForVlan)
+                .links(linksForMp2Sp)
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
+                .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls69Selector)))
+                .build();
+
+        sut.activate();
+        /*
+         * We use the FIRST_FIT to simplify tests.
+         */
+        LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(1));
+        FlowRule ruleS1 = rulesS1.iterator().next();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder(ipPrefixSelector)
+                        .matchInPort(d1p10.port())
+                        .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d1p0.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS2 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS2, hasSize(1));
+        FlowRule ruleS2 = rulesS2.iterator().next();
+        assertThat(ruleS2.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d2p0.port())
+                        .matchVlanId(VlanId.vlanId(LABEL))
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d2p1.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS3 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS3, hasSize(1));
+        FlowRule ruleS3 = rulesS3.iterator().next();
+        assertThat(ruleS3.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d3p0.port())
+                        .matchVlanId(VlanId.vlanId(LABEL))
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                .allInstructions()
+                                .stream()
+                                .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                .findFirst().get()).mac())
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(((MplsCriterion) mpls69Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d3p10.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of p2p with the MPLS
+     * encapsulation, filtered points, selector and treatment.
+     */
+    @Test
+    public void testMplsEncapsulationNonTrivialForP2P() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(ipPrefixSelector)
+                .treatment(ethDstTreatment)
+                .constraints(constraintsForMPLS)
+                .links(linksForMp2Sp)
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p10, vlan100Selector)))
+                .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls69Selector)))
+                .build();
+
+        sut.activate();
+        /*
+         * We use the FIRST_FIT to simplify tests.
+         */
+        LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(1));
+        FlowRule ruleS1 = rulesS1.iterator().next();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder(ipPrefixSelector)
+                        .matchInPort(d1p10.port())
+                        .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
+                        .setOutput(d1p0.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS2 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS2, hasSize(1));
+        FlowRule ruleS2 = rulesS2.iterator().next();
+        assertThat(ruleS2.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d2p0.port())
+                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+                        .matchEthType(Ethernet.MPLS_UNICAST)
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
+                        .setOutput(d2p1.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS3 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS3, hasSize(1));
+        FlowRule ruleS3 = rulesS3.iterator().next();
+        assertThat(ruleS3.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d3p0.port())
+                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+                        .matchEthType(Ethernet.MPLS_UNICAST)
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                .allInstructions()
+                                .stream()
+                                .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                .findFirst().get()).mac())
+                        .setMpls(((MplsCriterion) mpls69Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d3p10.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+}
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompilerTest.java
index 3970f8d..45e8485 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompilerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompilerTest.java
@@ -65,6 +65,10 @@
 import static org.onosproject.net.flow.criteria.Criterion.Type.VLAN_VID;
 import static org.onosproject.net.flow.instructions.L2ModificationInstruction.*;
 
+/**
+ * This set of tests are meant to test the LinkCollectionIntent
+ * compiler.
+ */
 public class LinkCollectionIntentCompilerTest extends AbstractLinkCollectionTest {
 
     @Before
@@ -110,6 +114,10 @@
         Intent.unbindIdGenerator(idGenerator);
     }
 
+    /**
+     * We test the proper compilation of a simple link collection intent
+     * with connect points, trivial treatment and trivial selector.
+     */
     @Test
     public void testCompile() {
         sut.activate();
@@ -166,10 +174,14 @@
     }
 
     /**
-     * Single point to multi point case.
+     * Single point to multi point case. Scenario is the follow:
+     *
      * -1 of1 2-1 of2 2--1 of3 2-
      *             3
      *             `-1 of4 2-
+     *
+     * We test the proper compilation of sp2mp with trivial selector,
+     * trivial treatment and different filtered points
      */
     @Test
     public void testFilteredConnectPointForSp() {
@@ -286,10 +298,14 @@
 
     /**
      * Multi point to single point intent with filtered connect point.
+     * Scenario is the follow:
      *
      * -1 of1 2-1 of2 2-1 of4 2-
      *             3
      * -1 of3 2---/
+     *
+     * We test the proper compilation of mp2sp intents with trivial selector,
+     * trivial treatment and different filtered point.
      */
     @Test
     public void testFilteredConnectPointForMp() {
@@ -408,9 +424,14 @@
 
     /**
      * Single point to multi point without filtered connect point case.
+     * Scenario is the follow:
+     *
      * -1 of1 2-1 of2 2--1 of3 2-
      *             3
      *             `-1 of4 2-
+     *
+     * We test the proper compilation of sp2mp with non trivial selector,
+     * non trivial treatment and simple connect points.
      */
     @Test
     public void nonTrivialTranslationForSp() {
@@ -527,10 +548,14 @@
 
     /**
      * Multi point to single point intent without filtered connect point.
+     * Scenario is the follow:
      *
      * -1 of1 2-1 of2 2-1 of4 2-
      *             3
      * -1 of3 2---/
+     *
+     * We test the proper compilation of mp2sp intent with non trivial selector,
+     * non trivial treatment and simple connect points.
      */
     @Test
     public void nonTrivialTranslationForMp() {
@@ -1085,282 +1110,4 @@
 
     }
 
-    /**
-     * We test the proper compilation of p2p with
-     * trivial selector and trivial treatment.
-     */
-    @Test
-    public void p2p() {
-
-        intent = LinkCollectionIntent.builder()
-                .appId(APP_ID)
-                .selector(selector)
-                .treatment(treatment)
-                .applyTreatmentOnEgress(true)
-                .links(p2pLinks)
-                .filteredIngressPoints(ImmutableSet.of(
-                        new FilteredConnectPoint(d1p10)
-                ))
-                .filteredEgressPoints(ImmutableSet.of(
-                        new FilteredConnectPoint(d3p0)
-                ))
-                .build();
-
-        sut.activate();
-
-        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
-        assertThat(compiled, hasSize(1));
-
-        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
-        assertThat(rules, hasSize(3));
-
-        Collection<FlowRule> rulesS1 = rules.stream()
-                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
-                .collect(Collectors.toSet());
-        assertThat(rulesS1, hasSize(1));
-        FlowRule ruleS1 = rulesS1.iterator().next();
-        assertThat(ruleS1.selector(), Is.is(
-                DefaultTrafficSelector
-                        .builder()
-                        .matchInPort(d1p10.port())
-                        .build()
-        ));
-        assertThat(ruleS1.treatment(), Is.is(
-                DefaultTrafficTreatment
-                        .builder()
-                        .setOutput(d1p0.port())
-                        .build()
-        ));
-
-        Collection<FlowRule> rulesS2 = rules.stream()
-                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
-                .collect(Collectors.toSet());
-        assertThat(rulesS2, hasSize(1));
-        FlowRule ruleS2 = rulesS2.iterator().next();
-        assertThat(ruleS2.selector(), Is.is(
-                DefaultTrafficSelector
-                        .builder()
-                        .matchInPort(d2p0.port())
-                        .build()
-        ));
-        assertThat(ruleS2.treatment(), Is.is(
-                DefaultTrafficTreatment
-                        .builder()
-                        .setOutput(d2p1.port())
-                        .build()
-        ));
-
-
-        Collection<FlowRule> rulesS3 = rules.stream()
-                .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
-                .collect(Collectors.toSet());
-        assertThat(rulesS3, hasSize(1));
-        FlowRule ruleS3 = rulesS3.iterator().next();
-        assertThat(ruleS3.selector(), Is.is(
-                DefaultTrafficSelector
-                        .builder()
-                        .matchInPort(d3p1.port())
-                        .build()
-        ));
-        assertThat(ruleS3.treatment(), Is.is(
-                DefaultTrafficTreatment
-                        .builder()
-                        .setOutput(d3p0.port())
-                        .build()
-        ));
-
-        sut.deactivate();
-
-    }
-
-    /**
-     * We test the proper compilation of p2p with
-     * trivial selector, trivial treatment and filtered points.
-     */
-    @Test
-    public void p2pFilteredPoint() {
-
-        intent = LinkCollectionIntent.builder()
-                .appId(APP_ID)
-                .selector(selector)
-                .treatment(treatment)
-                .applyTreatmentOnEgress(true)
-                .links(p2pLinks)
-                .filteredIngressPoints(ImmutableSet.of(
-                        new FilteredConnectPoint(d1p10, vlan100Selector)
-                ))
-                .filteredEgressPoints(ImmutableSet.of(
-                        new FilteredConnectPoint(d3p0, mpls200Selector)
-                ))
-                .build();
-
-        sut.activate();
-
-        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
-        assertThat(compiled, hasSize(1));
-
-        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
-        assertThat(rules, hasSize(3));
-
-        Collection<FlowRule> rulesS1 = rules.stream()
-                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
-                .collect(Collectors.toSet());
-        assertThat(rulesS1, hasSize(1));
-        FlowRule ruleS1 = rulesS1.iterator().next();
-        assertThat(ruleS1.selector(), Is.is(
-                DefaultTrafficSelector
-                        .builder(vlan100Selector)
-                        .matchInPort(d1p10.port())
-                        .build()
-        ));
-        assertThat(ruleS1.treatment(), Is.is(
-                DefaultTrafficTreatment
-                        .builder()
-                        .setOutput(d1p0.port())
-                        .build()
-        ));
-
-        Collection<FlowRule> rulesS2 = rules.stream()
-                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
-                .collect(Collectors.toSet());
-        assertThat(rulesS2, hasSize(1));
-        FlowRule ruleS2 = rulesS2.iterator().next();
-        assertThat(ruleS2.selector(), Is.is(
-                DefaultTrafficSelector
-                        .builder(vlan100Selector)
-                        .matchInPort(d2p0.port())
-                        .build()
-        ));
-        assertThat(ruleS2.treatment(), Is.is(
-                DefaultTrafficTreatment
-                        .builder()
-                        .setOutput(d2p1.port())
-                        .build()
-        ));
-
-
-        Collection<FlowRule> rulesS3 = rules.stream()
-                .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
-                .collect(Collectors.toSet());
-        assertThat(rulesS3, hasSize(1));
-        FlowRule ruleS3 = rulesS3.iterator().next();
-        assertThat(ruleS3.selector(), Is.is(
-                DefaultTrafficSelector
-                        .builder(vlan100Selector)
-                        .matchInPort(d3p1.port())
-                        .build()
-        ));
-        assertThat(ruleS3.treatment(), Is.is(
-                DefaultTrafficTreatment
-                        .builder()
-                        .popVlan()
-                        .pushMpls()
-                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
-                        .setOutput(d3p0.port())
-                        .build()
-        ));
-
-        sut.deactivate();
-
-    }
-
-    /**
-     * We test the proper compilation of p2p with
-     * selector, treatment and filtered points.
-     */
-    @Test
-    public void p2pNonTrivial() {
-
-        intent = LinkCollectionIntent.builder()
-                .appId(APP_ID)
-                .selector(ipPrefixSelector)
-                .treatment(ethDstTreatment)
-                .applyTreatmentOnEgress(true)
-                .links(p2pLinks)
-                .filteredIngressPoints(ImmutableSet.of(
-                        new FilteredConnectPoint(d1p10, vlan100Selector)
-                ))
-                .filteredEgressPoints(ImmutableSet.of(
-                        new FilteredConnectPoint(d3p0, mpls200Selector)
-                ))
-                .build();
-
-        sut.activate();
-
-        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
-        assertThat(compiled, hasSize(1));
-
-        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
-        assertThat(rules, hasSize(3));
-
-        Collection<FlowRule> rulesS1 = rules.stream()
-                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
-                .collect(Collectors.toSet());
-        assertThat(rulesS1, hasSize(1));
-        FlowRule ruleS1 = rulesS1.iterator().next();
-        assertThat(ruleS1.selector(), Is.is(
-                DefaultTrafficSelector
-                        .builder(ipPrefixSelector)
-                        .matchInPort(d1p10.port())
-                        .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
-                        .build()
-        ));
-        assertThat(ruleS1.treatment(), Is.is(
-                DefaultTrafficTreatment
-                        .builder()
-                        .setOutput(d1p0.port())
-                        .build()
-        ));
-
-        Collection<FlowRule> rulesS2 = rules.stream()
-                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
-                .collect(Collectors.toSet());
-        assertThat(rulesS2, hasSize(1));
-        FlowRule ruleS2 = rulesS2.iterator().next();
-        assertThat(ruleS2.selector(), Is.is(
-                DefaultTrafficSelector
-                        .builder(ipPrefixSelector)
-                        .matchInPort(d2p0.port())
-                        .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
-                        .build()
-        ));
-        assertThat(ruleS2.treatment(), Is.is(
-                DefaultTrafficTreatment
-                        .builder()
-                        .setOutput(d2p1.port())
-                        .build()
-        ));
-
-
-        Collection<FlowRule> rulesS3 = rules.stream()
-                .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
-                .collect(Collectors.toSet());
-        assertThat(rulesS3, hasSize(1));
-        FlowRule ruleS3 = rulesS3.iterator().next();
-        assertThat(ruleS3.selector(), Is.is(
-                DefaultTrafficSelector
-                        .builder(ipPrefixSelector)
-                        .matchInPort(d3p1.port())
-                        .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
-                        .build()
-        ));
-        assertThat(ruleS3.treatment(), Is.is(
-                DefaultTrafficTreatment
-                        .builder()
-                        .setEthDst(((ModEtherInstruction) ethDstTreatment
-                                .allInstructions()
-                                .stream()
-                                .filter(instruction -> instruction instanceof ModEtherInstruction)
-                                .findFirst().get()).mac())
-                        .popVlan()
-                        .pushMpls()
-                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
-                        .setOutput(d3p0.port())
-                        .build()
-        ));
-
-        sut.deactivate();
-
-    }
-
 }
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionOptimizationTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionOptimizationTest.java
index 4b58fba..b0465f0 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionOptimizationTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionOptimizationTest.java
@@ -1057,4 +1057,487 @@
 
     }
 
+    /**
+     * We test the proper optimization of sp2mp with trivial selector,
+     * trivial treatment, vlan encapsulation and co-located
+     * ingress/egress points.
+     */
+    @Test
+    public void testOptimizationCoLocatedPointsTrivialForSp() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(treatment)
+                .applyTreatmentOnEgress(true)
+                .links(linksForSp2MpCoLoc)
+                .constraints(constraintsForVlan)
+                .filteredIngressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10)
+                ))
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p11),
+                        new FilteredConnectPoint(d2p10),
+                        new FilteredConnectPoint(d3p10)
+                ))
+                .build();
+
+        sut.activate();
+
+        /*
+         * We use the FIRST_FIT to simplify tests.
+         */
+        LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(1));
+
+        FlowRule ruleS1 = rulesS1.iterator().next();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder(selector)
+                        .matchInPort(d1p10.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .pushVlan()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d1p0.port())
+                        .popVlan()
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS2 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS2, hasSize(1));
+
+        FlowRule ruleS2 = rulesS2.iterator().next();
+        assertThat(ruleS2.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d2p0.port())
+                        .matchVlanId(VlanId.vlanId(LABEL))
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d2p1.port())
+                        .popVlan()
+                        .setOutput(d2p10.port())
+                        .build()
+        ));
+
+        Collection<FlowRule> rulesS3 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS3, hasSize(1));
+
+        FlowRule ruleS3 = rulesS3.iterator().next();
+        assertThat(ruleS3.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d3p0.port())
+                        .matchVlanId(VlanId.vlanId(LABEL))
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popVlan()
+                        .setOutput(d3p10.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper optimization of sp2mp with trivial selector,
+     * trivial treatment, mpls encapsulation and co-located
+     * filtered ingress/egress points.
+     */
+    @Test
+    public void testCoLocatedFilteredPointsTrivialForSp() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(treatment)
+                .applyTreatmentOnEgress(true)
+                .links(linksForSp2MpCoLoc)
+                .constraints(constraintsForMPLS)
+                .filteredIngressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10, vlan100Selector)
+                ))
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p11, vlan200Selector),
+                        new FilteredConnectPoint(d2p10, vlan300Selector),
+                        new FilteredConnectPoint(d3p10, vlan69Selector)
+                ))
+                .build();
+
+        sut.activate();
+
+        /*
+         * We use the FIRST_FIT to simplify tests.
+         */
+        LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(1));
+
+        FlowRule ruleS1 = rulesS1.iterator().next();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder(vlan100Selector)
+                        .matchInPort(d1p10.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popVlan()
+                        .pushMpls()
+                        .copyTtlOut()
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
+                        .setOutput(d1p0.port())
+                        .copyTtlIn()
+                        .popMpls(IPV4.ethType())
+                        .pushVlan()
+                        .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+
+        Collection<FlowRule> rulesS2 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS2, hasSize(1));
+
+        FlowRule ruleS2 = rulesS2.iterator().next();
+        assertThat(ruleS2.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d2p0.port())
+                        .matchEthType(Ethernet.MPLS_UNICAST)
+                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
+                        .setOutput(d2p1.port())
+                        .copyTtlIn()
+                        .popMpls(IPV4.ethType())
+                        .pushVlan()
+                        .setVlanId(((VlanIdCriterion) vlan300Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d2p10.port())
+                        .build()
+        ));
+
+
+        Collection<FlowRule> rulesS3 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS3, hasSize(1));
+
+        FlowRule ruleS3 = rulesS3.iterator().next();
+        assertThat(ruleS3.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d3p0.port())
+                        .matchEthType(Ethernet.MPLS_UNICAST)
+                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .copyTtlIn()
+                        .popMpls(IPV4.ethType())
+                        .pushVlan()
+                        .setVlanId(((VlanIdCriterion) vlan69Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d3p10.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper optimization of sp2mp with trivial selector,
+     * trivial treatment, vlan encapsulation and co-located
+     * different filtered ingress/egress points.
+     */
+    @Test
+    public void testCoLocatedDifferentFilteredPointsTrivialForSp() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(treatment)
+                .applyTreatmentOnEgress(true)
+                .links(linksForSp2MpCoLoc)
+                .constraints(constraintsForVlan)
+                .filteredIngressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10, vlan100Selector)
+                ))
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p11, mpls100Selector),
+                        new FilteredConnectPoint(d2p10, vlan200Selector),
+                        new FilteredConnectPoint(d3p10, mpls200Selector)
+                ))
+                .build();
+
+        sut.activate();
+
+        /*
+         * We use the FIRST_FIT to simplify tests.
+         */
+        LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(1));
+
+        FlowRule ruleS1 = rulesS1.iterator().next();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder(vlan100Selector)
+                        .matchInPort(d1p10.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d1p0.port())
+                        .popVlan()
+                        .pushMpls()
+                        .copyTtlOut()
+                        .setMpls(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+
+        Collection<FlowRule> rulesS2 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS2, hasSize(1));
+
+        FlowRule ruleS2 = rulesS2.iterator().next();
+        assertThat(ruleS2.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d2p0.port())
+                        .matchVlanId(VlanId.vlanId(LABEL))
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d2p1.port())
+                        .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d2p10.port())
+                        .build()
+        ));
+
+
+        Collection<FlowRule> rulesS3 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS3, hasSize(1));
+
+        FlowRule ruleS3 = rulesS3.iterator().next();
+        assertThat(ruleS3.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchVlanId(VlanId.vlanId(LABEL))
+                        .matchInPort(d3p0.port())
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popVlan()
+                        .pushMpls()
+                        .copyTtlOut()
+                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d3p10.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper optimization of sp2mp with selector,
+     * treatment, mpls encapsulation and co-located
+     * different filtered ingress/egress points.
+     */
+    @Test
+    public void testCoLocatedDifferentFilteredPointsNonTrivialForSp() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(ipPrefixSelector)
+                .treatment(ethDstTreatment)
+                .applyTreatmentOnEgress(true)
+                .links(linksForSp2MpCoLoc)
+                .constraints(constraintsForMPLS)
+                .filteredIngressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10, vlan100Selector)
+                ))
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p11, mpls100Selector),
+                        new FilteredConnectPoint(d2p10, vlan200Selector),
+                        new FilteredConnectPoint(d3p10, mpls200Selector)
+                ))
+                .build();
+
+        sut.activate();
+
+        /*
+         * We use the FIRST_FIT to simplify tests.
+         */
+        LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(1));
+
+        FlowRule ruleS1 = rulesS1.iterator().next();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder(ipPrefixSelector)
+                        .matchInPort(d1p10.port())
+                        .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popVlan()
+                        .pushMpls()
+                        .copyTtlOut()
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
+                        .setOutput(d1p0.port())
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                .allInstructions()
+                                .stream()
+                                .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                .findFirst().get()).mac())
+                        .setMpls(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+
+        Collection<FlowRule> rulesS2 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS2, hasSize(1));
+
+        FlowRule ruleS2 = rulesS2.iterator().next();
+        assertThat(ruleS2.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d2p0.port())
+                        .matchEthType(Ethernet.MPLS_UNICAST)
+                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
+                        .setOutput(d2p1.port())
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                .allInstructions()
+                                .stream()
+                                .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                .findFirst().get()).mac())
+                        .copyTtlIn()
+                        .popMpls(IPV4.ethType())
+                        .pushVlan()
+                        .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d2p10.port())
+                        .build()
+        ));
+
+
+        Collection<FlowRule> rulesS3 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d3p1.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS3, hasSize(1));
+
+        FlowRule ruleS3 = rulesS3.iterator().next();
+        assertThat(ruleS3.selector(), is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchEthType(Ethernet.MPLS_UNICAST)
+                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+                        .matchInPort(d3p0.port())
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                .allInstructions()
+                                .stream()
+                                .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                .findFirst().get()).mac())
+                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d3p10.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
 }
