diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionCompiler.java
index 2176a20..df87844 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionCompiler.java
@@ -260,6 +260,103 @@
     }
 
     /**
+     * Helper method which handles the proper generation of the ouput actions.
+     *
+     * @param outPorts the output ports
+     * @param deviceId the current device
+     * @param intent the intent to compile
+     * @param outLabels the output labels
+     * @param type the encapsulation type
+     * @param preCondition the previous state
+     * @param treatmentBuilder the builder to update with the ouput actions
+     */
+    private void manageOutputPorts(Set<PortNumber> outPorts,
+                                   DeviceId deviceId,
+                                   LinkCollectionIntent intent,
+                                   Map<ConnectPoint, Identifier<?>> outLabels,
+                                   EncapsulationType type,
+                                   TrafficSelector.Builder preCondition,
+                                   TrafficTreatment.Builder treatmentBuilder) {
+        /*
+         * We need to order the actions. First the actions
+         * related to the not-egress points. At the same time we collect
+         * also the egress points.
+         */
+        List<FilteredConnectPoint> egressPoints = Lists.newArrayList();
+        for (PortNumber outPort : outPorts) {
+            Optional<FilteredConnectPoint> filteredEgressPoint =
+                    getFilteredConnectPointFromIntent(deviceId, outPort, intent);
+            if (!filteredEgressPoint.isPresent()) {
+                /*
+                 * We build a temporary selector for the encapsulation.
+                 */
+                TrafficSelector.Builder encapBuilder = DefaultTrafficSelector.builder();
+                /*
+                 * We retrieve the associated label to the output port.
+                 */
+                ConnectPoint cp = new ConnectPoint(deviceId, outPort);
+                Identifier<?> outLabel = outLabels.get(cp);
+                /*
+                 * If there are not labels, we cannot handle.
+                 */
+                if (outLabel == null) {
+                    throw new IntentCompilationException(String.format(NO_LABELS, cp));
+                }
+                /*
+                 * In the core we match using encapsulation.
+                 */
+                updateSelectorFromEncapsulation(
+                        encapBuilder,
+                        type,
+                        outLabel
+                );
+                /*
+                 * We generate the transition.
+                 */
+                TrafficTreatment forwardingTreatment =
+                        forwardingTreatment(preCondition.build(),
+                                            encapBuilder.build(),
+                                            getEthType(intent.selector()));
+                /*
+                 * We add the instruction necessary to the transition.
+                 */
+                forwardingTreatment.allInstructions().stream()
+                        .filter(inst -> inst.type() != Instruction.Type.NOACTION)
+                        .forEach(treatmentBuilder::add);
+                /*
+                 * Finally we set the output action.
+                 */
+                treatmentBuilder.setOutput(outPort);
+                /*
+                 * The encapsulation modifies the packet. If we are optimizing
+                 * we have to update the state.
+                 */
+                if (optimize) {
+                    preCondition = encapBuilder;
+                }
+            } else {
+                egressPoints.add(filteredEgressPoint.get());
+            }
+        }
+        /*
+         * The idea is to order the egress points. Before we deal
+         * with the egress points which looks like similar to the
+         * selector derived from the previous state then the
+         * the others.
+         */
+        TrafficSelector prevState = preCondition.build();
+        if (optimize) {
+            egressPoints = orderedEgressPoints(prevState, egressPoints);
+        }
+        /*
+         * In this case, we have to transit to the final
+         * state.
+         */
+        generateEgressActions(treatmentBuilder, egressPoints, prevState, intent);
+
+    }
+
+    /**
      * Helper method to generate the egress actions.
      *
      * @param treatmentBuilder the treatment builder to update
@@ -654,60 +751,23 @@
                 .criteria()
                 .forEach(selectorBuilder::add);
         /*
-         * In this scenario, we can have several output ports.
+         * In this case the precondition is the selector of the filtered
+         * ingress point.
          */
-        outPorts.forEach(outPort -> {
-            Optional<FilteredConnectPoint> filteredEgressPoint =
-                    getFilteredConnectPointFromIntent(deviceId, outPort, intent);
-            /*
-             * If we are at the egress, we don't handle
-             * with encapsulation. Error scenario
-             */
-            if (filteredEgressPoint.isPresent()) {
-                throw new IntentCompilationException(WRONG_ENCAPSULATION);
-            }
-            /*
-             * Transit/core, we have to transit to the intermediate
-             * state. We build a temporary selector for the encapsulation.
-             */
-            TrafficSelector.Builder encapBuilder = DefaultTrafficSelector.builder();
-            /*
-             * We retrieve the associated label to the output port.
-             */
-            ConnectPoint cp = new ConnectPoint(deviceId, outPort);
-            Identifier<?> outLabel = outLabels.get(cp);
-            /*
-             * If there aren't labels, we cannot handle.
-             */
-            if (outLabel == null) {
-                throw new IntentCompilationException(String.format(NO_LABELS, cp));
-            }
-            /*
-             * In the core we match using encapsulation.
-             */
-            updateSelectorFromEncapsulation(
-                    encapBuilder,
-                    type,
-                    outLabel
-            );
-            /*
-             * We generate the transition.
-             */
-            TrafficTreatment forwardingTreatment =
-                    forwardingTreatment(filteredIngressPoint.get().trafficSelector(),
-                                        encapBuilder.build(),
-                                        getEthType(intent.selector()));
-            /*
-             * We add the instruction necessary to the transition.
-             */
-            forwardingTreatment.allInstructions().stream()
-                    .filter(inst -> inst.type() != Instruction.Type.NOACTION)
-                    .forEach(treatmentBuilder::add);
-            /*
-             * Finally we set the output action.
-             */
-            treatmentBuilder.setOutput(outPort);
-        });
+        TrafficSelector.Builder preCondition = DefaultTrafficSelector
+                .builder(filteredIngressPoint.get().trafficSelector());
+        /*
+         * Generate the output actions.
+         */
+        manageOutputPorts(
+                outPorts,
+                deviceId,
+                intent,
+                outLabels,
+                type,
+                preCondition,
+                treatmentBuilder
+        );
 
     }
 
@@ -751,74 +811,18 @@
                 inLabel
         );
         /*
-         * We need to order the actions. First the actions
-         * related to the not-egress points. At the same time we collect
-         * also the egress points.
+         * Generate the output actions.
          */
-        List<FilteredConnectPoint> egressPoints = Lists.newArrayList();
-        for (PortNumber outPort : outPorts) {
-            Optional<FilteredConnectPoint> filteredEgressPoint =
-                    getFilteredConnectPointFromIntent(deviceId, outPort, intent);
-            if (!filteredEgressPoint.isPresent()) {
-                /*
-                 * We build a temporary selector for the encapsulation.
-                 */
-                TrafficSelector.Builder encapBuilder = DefaultTrafficSelector.builder();
-                /*
-                 * We retrieve the associated label to the output port.
-                 */
-                ConnectPoint cp = new ConnectPoint(deviceId, outPort);
-                Identifier<?> outLabel = outLabels.get(cp);
-                /*
-                 * If there are not labels, we cannot handle.
-                 */
-                if (outLabel == null) {
-                    throw new IntentCompilationException(String.format(NO_LABELS, cp));
-                }
-                /*
-                 * In the core we match using encapsulation.
-                 */
-                updateSelectorFromEncapsulation(
-                        encapBuilder,
-                        type,
-                        outLabel
-                );
-                /*
-                 * We generate the transition.
-                 */
-                TrafficTreatment forwardingTreatment =
-                        forwardingTreatment(selectorBuilder.build(),
-                                            encapBuilder.build(),
-                                            getEthType(intent.selector()));
-                /*
-                 * We add the instruction necessary to the transition.
-                 */
-                forwardingTreatment.allInstructions().stream()
-                        .filter(inst -> inst.type() != Instruction.Type.NOACTION)
-                        .forEach(treatmentBuilder::add);
-                /*
-                 * Finally we set the output action.
-                 */
-                treatmentBuilder.setOutput(outPort);
-            } else {
-                egressPoints.add(filteredEgressPoint.get());
-            }
-        }
-        /*
-         * The idea is to order the egress points. Before we deal
-         * with the egress points which looks like similar to the
-         * selector derived from the encpsulation constraint then
-         * the others.
-         */
-        TrafficSelector prevState = selectorBuilder.build();
-        if (optimize) {
-            egressPoints = orderedEgressPoints(prevState, egressPoints);
-        }
-        /*
-         * In this case, we have to transit to the final
-         * state.
-         */
-        generateEgressActions(treatmentBuilder, egressPoints, prevState, intent);
+        manageOutputPorts(
+                outPorts,
+                deviceId,
+                intent,
+                outLabels,
+                type,
+                selectorBuilder,
+                treatmentBuilder
+        );
+
     }
 
     /**
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();
+
+    }
+
 }
