diff --git a/core/api/src/test/java/org/onosproject/net/NetTestTools.java b/core/api/src/test/java/org/onosproject/net/NetTestTools.java
index 8898008..842c86d 100644
--- a/core/api/src/test/java/org/onosproject/net/NetTestTools.java
+++ b/core/api/src/test/java/org/onosproject/net/NetTestTools.java
@@ -15,12 +15,23 @@
  */
 package org.onosproject.net;
 
+import com.google.common.collect.ImmutableList;
 import org.onlab.junit.TestUtils;
 import org.onlab.packet.ChassisId;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
 import org.onosproject.TestApplicationId;
 import org.onosproject.cluster.NodeId;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.event.EventDeliveryService;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.constraint.EncapsulationConstraint;
 import org.onosproject.net.provider.ProviderId;
 
 import java.lang.reflect.Field;
@@ -84,6 +95,17 @@
                                Link.Type.DIRECT, Link.State.ACTIVE);
     }
 
+    /**
+     * Short-hand for creating a link.
+     *
+     * @param src the src of the link
+     * @param dst the dst of the link
+     * @return a link
+     */
+    public static Link link(ConnectPoint src, ConnectPoint dst) {
+        return new DefaultLink(PID, src, dst, Link.Type.DIRECT, Link.State.ACTIVE);
+    }
+
     // Creates a path that leads through the given devices.
     public static Path createPath(String... ids) {
         List<Link> links = new ArrayList<>();
@@ -152,4 +174,88 @@
         }
     }
 
+    /**
+     * Builds an empty selector.
+     *
+     * @return the selector
+     */
+    public static TrafficSelector emptySelector() {
+        return DefaultTrafficSelector.emptySelector();
+    }
+
+    /**
+     * Builds a vlan selector.
+     *
+     * @return the selector
+     */
+    public static TrafficSelector vlanSelector(String vlanId) {
+        return DefaultTrafficSelector.builder()
+                .matchVlanId(VlanId.vlanId(vlanId))
+                .build();
+    }
+
+    /**
+     * Builds a mpls selector.
+     *
+     * @return the selector
+     */
+    public static TrafficSelector mplsSelector(String mplsLabel) {
+        return DefaultTrafficSelector.builder()
+                .matchMplsLabel(MplsLabel.mplsLabel(mplsLabel))
+                .build();
+    }
+
+    /**
+     * Builds an ip prefix dst selector.
+     *
+     * @return the selector
+     */
+    public static TrafficSelector ipPrefixDstSelector(String prefix) {
+        return DefaultTrafficSelector.builder()
+                .matchIPDst(IpPrefix.valueOf(prefix))
+                .build();
+    }
+
+    /**
+     * Builds an empty treatment.
+     *
+     * @return the treatment
+     */
+    public static TrafficTreatment emptyTreatment() {
+        return DefaultTrafficTreatment.emptyTreatment();
+    }
+
+    /**
+     * Builds a mac dst treatment.
+     *
+     * @return the treatment
+     */
+    public static TrafficTreatment macDstTreatment(String mac) {
+        return DefaultTrafficTreatment.builder()
+                .setEthDst(MacAddress.valueOf(mac))
+                .build();
+    }
+
+    /**
+     * Builds a list containing a vlan encapsulation constraint.
+     *
+     * @return the list of constraints
+     */
+    public static List<Constraint> vlanConstraint() {
+        return ImmutableList.of(
+                new EncapsulationConstraint(EncapsulationType.VLAN)
+        );
+    }
+
+    /**
+     * Builds a list containing a mpls encapsulation constraint.
+     *
+     * @return the list of constraints
+     */
+    public static List<Constraint> mplsConstraint() {
+        return ImmutableList.of(
+                new EncapsulationConstraint(EncapsulationType.MPLS)
+        );
+    }
+
 }
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/IntentConfigurableRegistrator.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/IntentConfigurableRegistrator.java
index 50578de..38be5e4 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/IntentConfigurableRegistrator.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/IntentConfigurableRegistrator.java
@@ -170,7 +170,7 @@
     }
 
     private void changeLabelSelections() {
-        PathCompiler.labelAllocator.setLabelSelection(labelSelection);
+        LinkCollectionCompiler.labelAllocator.setLabelSelection(labelSelection);
     }
 
 }
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 7701f29..d5df116 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
@@ -16,12 +16,19 @@
 
 package org.onosproject.net.intent.impl.compiler;
 
+import com.google.common.collect.Maps;
 import com.google.common.collect.SetMultimap;
 import com.google.common.collect.Sets;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onlab.util.Identifier;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.EncapsulationType;
 import org.onosproject.net.Link;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.FilteredConnectPoint;
@@ -31,6 +38,7 @@
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.flow.criteria.Criteria;
 import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
 import org.onosproject.net.flow.criteria.MplsCriterion;
 import org.onosproject.net.flow.criteria.TunnelIdCriterion;
 import org.onosproject.net.flow.criteria.VlanIdCriterion;
@@ -54,27 +62,696 @@
 import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction;
 import org.onosproject.net.intent.IntentCompilationException;
 import org.onosproject.net.intent.LinkCollectionIntent;
+import org.onosproject.net.intent.constraint.EncapsulationConstraint;
+import org.onosproject.net.resource.impl.LabelAllocator;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 import static org.onosproject.net.flow.criteria.Criterion.Type.MPLS_LABEL;
 import static org.onosproject.net.flow.criteria.Criterion.Type.TUNNEL_ID;
 import static org.onosproject.net.flow.criteria.Criterion.Type.VLAN_VID;
 
-
 /**
  * Shared APIs and implementations for Link Collection compilers.
  */
 public class LinkCollectionCompiler<T> {
 
+    /**
+     * Reference to the label allocator.
+     */
+    static LabelAllocator labelAllocator;
+
+    /**
+     * The allowed tag criterions.
+     */
     private static final Set<Criterion.Type> TAG_CRITERION_TYPES =
             Sets.immutableEnumSet(VLAN_VID, MPLS_LABEL, TUNNEL_ID);
 
     /**
-     * Helper class to encapsulate treatment and selector.
+     * Error message for wrong egress scenario.
+     */
+    private static final String WRONG_EGRESS = "Egress points not equal to 1 " +
+            "and apply treatment at ingress, " +
+            "which treatments should I apply ???";
+
+    /**
+     * Error message for wrong ingress scenario.
+     */
+    private static final String WRONG_INGRESS = "Ingress points not equal to 1 " +
+            "and apply treatment at egress, " +
+            "how can I match in the core ???";
+
+    /**
+     * Error message for wrong encapsulation scenario.
+     */
+    private static final String WRONG_ENCAPSULATION = "Wrong scenario - 1 hop with " +
+            "encapsualtion";
+
+    /**
+     * Error message for unavailable labels.
+     */
+    private static final String NO_LABELS = "No available label for %s";
+
+    /**
+     * Error message for wrong encapsulation.
+     */
+    private static final String UNKNOWN_ENCAPSULATION = "Unknown encapsulation type";
+
+    /**
+     * Error message for unsupported L0 instructions.
+     */
+    private static final String UNSUPPORTED_L0 = "L0 not supported";
+
+    /**
+     * Error message for unsupported L1 instructions.
+     */
+    private static final String UNSUPPORTED_L1 = "L1 not supported";
+
+    /**
+     * Error message for unsupported eth subtype.
+     */
+    private static final String UNSUPPORTED_ETH_SUBTYPE = "Bad eth subtype";
+
+    /**
+     * Error message for unsupported pop action.
+     */
+    private static final String UNSUPPORTED_POP_ACTION = "Can't handle pop label";
+
+    /**
+     * Error message for unsupported L2 instructions.
+     */
+    private static final String UNSUPPORTED_L2 = "Unknown L2 Modification instruction";
+
+    /**
+     * Error message for unsupported IP subtype.
+     */
+    private static final String UNSUPPORTED_IP_SUBTYPE = "Bad ip subtype";
+
+    /**
+     * Error message for unsupported ARP.
+     */
+    private static final String UNSUPPORTED_ARP = "IPv6 not supported for ARP";
+
+    /**
+     * Error message for unsupported L3 instructions.
+     */
+    private static final String UNSUPPORTED_L3 = "Unknown L3 Modification instruction";
+
+    /**
+     * Error message for unsupported L4 subtype.
+     */
+    private static final String UNSUPPORTED_L4_SUBTYPE = "Unknown L4 subtype";
+
+    /**
+     * Error message for unsupported L4 instructions.
+     */
+    private static final String UNSUPPORTED_L4 = "Unknown L4 Modification instruction";
+
+    /**
+     * Error message for unsupported instructions.
+     */
+    private static final String UNSUPPORTED_INSTRUCTION = "Unknown instruction type";
+
+    /**
+     * Creates the flows representations. This default implementation does
+     * nothing. Subclasses should override this method to create their
+     * specific flows representations (flow rule, flow objective).
+     *
+     * @param intent the intent to compile
+     * @param deviceId the affected device
+     * @param inPorts the input ports
+     * @param outPorts the output ports
+     * @param labels the labels for the label switching hop by hop
+     * @return the list of flows representations
+     */
+    protected List<T> createRules(LinkCollectionIntent intent,
+                                  DeviceId deviceId,
+                                  Set<PortNumber> inPorts,
+                                  Set<PortNumber> outPorts,
+                                  Map<ConnectPoint, Identifier<?>> labels) {
+        return null;
+    }
+
+    /**
+     * Helper method to handle the different scenario (not encap, single hop, encap).
+     *
+     * @param encapConstraint the encapsulation constraint if it is present
+     * @param intent the link collection intent
+     * @param inPort the in port
+     * @param outPorts the out ports
+     * @param deviceId the current device
+     * @param labels the labels used by the encapsulation
+     * @return the forwarding instruction
+     */
+    protected ForwardingInstructions createForwardingInstruction(Optional<EncapsulationConstraint> encapConstraint,
+                                                                 LinkCollectionIntent intent,
+                                                                 PortNumber inPort,
+                                                                 Set<PortNumber> outPorts,
+                                                                 DeviceId deviceId,
+                                                                 Map<ConnectPoint, Identifier<?>> labels) {
+        ForwardingInstructions instructions = null;
+        /*
+         * If not encapsulation or single hop.
+         */
+        if (!encapConstraint.isPresent() || intent.links().isEmpty()) {
+            instructions = this.createForwardingInstructions(
+                    intent,
+                    inPort,
+                    deviceId,
+                    outPorts
+            );
+        /*
+         * If encapsulation is present. We retrieve the labels
+         * for this iteration;
+         */
+        } else {
+            Identifier<?> inLabel = labels.get(new ConnectPoint(deviceId, inPort));
+            Map<ConnectPoint, Identifier<?>> outLabels = Maps.newHashMap();
+            outPorts.forEach(outPort -> {
+                ConnectPoint key = new ConnectPoint(deviceId, outPort);
+                outLabels.put(key, labels.get(key));
+            });
+            instructions = this.createForwardingInstructions(
+                    intent,
+                    inPort,
+                    inLabel,
+                    deviceId,
+                    outPorts,
+                    outLabels,
+                    encapConstraint.get().encapType()
+            );
+        }
+        return instructions;
+    }
+
+    /**
+     * Manages the Intents with a single ingress point (p2p, sp2mp)
+     * creating properly the selector builder and the treatment builder.
+     *
+     * @param selectorBuilder the selector builder to update
+     * @param treatmentBuilder the treatment builder to update
+     * @param intent the intent to compile
+     * @param deviceId the current device
+     * @param outPorts the output ports of this device
+     */
+    private void manageSpIntent(TrafficSelector.Builder selectorBuilder,
+                                TrafficTreatment.Builder treatmentBuilder,
+                                LinkCollectionIntent intent,
+                                DeviceId deviceId,
+                                Set<PortNumber> outPorts) {
+        /*
+         * Sanity check.
+         */
+        if (intent.filteredIngressPoints().size() != 1) {
+            throw new IntentCompilationException(WRONG_INGRESS);
+        }
+        /*
+         * For the p2p and sp2mp the transition initial state
+         * to final state is performed at the egress.
+         */
+        Optional<FilteredConnectPoint> filteredIngressPoint =
+                intent.filteredIngressPoints().stream().findFirst();
+        /*
+         * We build the final selector, adding the selector
+         * of the FIP to the Intent selector and potentially
+         * overriding its matches.
+         */
+        filteredIngressPoint.get()
+                .trafficSelector()
+                .criteria()
+                .forEach(selectorBuilder::add);
+        /*
+         * In this scenario, potentially we can have several output
+         * ports.
+         */
+        for (PortNumber outPort : outPorts) {
+            Optional<FilteredConnectPoint> filteredEgressPoint =
+                    getFilteredConnectPointFromIntent(deviceId, outPort, intent);
+            /*
+             * If we are at the egress, we have to transit to the final
+             * state.
+             */
+            if (filteredEgressPoint.isPresent()) {
+                /*
+                 * We add the Intent treatment.
+                 */
+                intent.treatment().allInstructions().stream()
+                        .filter(inst -> inst.type() != Instruction.Type.NOACTION)
+                        .forEach(treatmentBuilder::add);
+                /*
+                 * We generate the transition FIP->FEP.
+                 */
+                TrafficTreatment forwardingTreatment =
+                        forwardingTreatment(filteredIngressPoint.get().trafficSelector(),
+                                            filteredEgressPoint.get().trafficSelector(),
+                                            getEthType(intent.selector()));
+                /*
+                 * We add the instruction necessary to the transition.
+                 * Potentially we override the intent treatment.
+                 */
+                forwardingTreatment.allInstructions().stream()
+                        .filter(inst -> inst.type() != Instruction.Type.NOACTION)
+                        .forEach(treatmentBuilder::add);
+            }
+            /*
+             * Finally we set the output action.
+             */
+            treatmentBuilder.setOutput(outPort);
+        }
+    }
+
+    /**
+     * Manages the Intents with multiple ingress points creating properly
+     * the selector builder and the treatment builder.
+     *
+     * @param selectorBuilder the selector builder to update
+     * @param treatmentBuilder the treatment builder to update
+     * @param intent the intent to compile
+     * @param inPort the input port of the current device
+     * @param deviceId the current device
+     * @param outPorts the output ports of this device
+     */
+    private void manageMpIntent(TrafficSelector.Builder selectorBuilder,
+                                TrafficTreatment.Builder treatmentBuilder,
+                                LinkCollectionIntent intent,
+                                PortNumber inPort,
+                                DeviceId deviceId,
+                                Set<PortNumber> outPorts) {
+        /*
+         * Sanity check
+         */
+        if (intent.filteredEgressPoints().size() != 1) {
+            throw new IntentCompilationException(WRONG_EGRESS);
+        }
+        /*
+         * We try to understand if the device is one of the ingress points.
+         */
+        Optional<FilteredConnectPoint> filteredIngressPoint =
+                getFilteredConnectPointFromIntent(deviceId, inPort, intent);
+        /*
+         * We retrieve from the Intent the unique egress points.
+         */
+        Optional<FilteredConnectPoint> filteredEgressPoint =
+                intent.filteredEgressPoints().stream().findFirst();
+        /*
+         * We check if the device is the ingress device
+         */
+        if (filteredIngressPoint.isPresent()) {
+            /*
+             * We are at ingress, so basically what we have to do is this:
+             * apply a set of operations (treatment, FEP) in order to have
+             * a transition from the initial state to the final state.
+             *
+             * We initialize the treatment with the Intent treatment
+             */
+            intent.treatment().allInstructions().stream()
+                    .filter(inst -> inst.type() != Instruction.Type.NOACTION)
+                    .forEach(treatmentBuilder::add);
+            /*
+             * We build the final selector, adding the selector
+             * of the FIP to the Intent selector and potentially
+             * overriding its matches.
+             */
+            filteredIngressPoint.get()
+                    .trafficSelector()
+                    .criteria()
+                    .forEach(selectorBuilder::add);
+            /*
+             * We define the transition FIP->FEP, basically
+             * the set of the operations we need for reaching
+             * the final state.
+             */
+            TrafficTreatment forwardingTreatment =
+                    forwardingTreatment(filteredIngressPoint.get().trafficSelector(),
+                                        filteredEgressPoint.get().trafficSelector(),
+                                        getEthType(intent.selector()));
+            /*
+             * We add to the treatment the actions necessary for the
+             * transition, potentially overriding the treatment of the
+             * Intent. The Intent treatment has always a low priority
+             * in respect of the FEP.
+             */
+            forwardingTreatment.allInstructions().stream()
+                    .filter(inst -> inst.type() != Instruction.Type.NOACTION)
+                    .forEach(treatmentBuilder::add);
+        } else {
+            /*
+             * We are in the core or in the egress switch.
+             * The packets are in their final state. We need
+             * to match against this final state.
+             *
+             * we derive the final state defined by the intent
+             * treatment.
+             */
+            updateBuilder(selectorBuilder, intent.treatment());
+            /*
+             * We derive the final state defined by the unique
+             * FEP. We merge the two states.
+             */
+            filteredEgressPoint.get()
+                    .trafficSelector()
+                    .criteria()
+                    .forEach(selectorBuilder::add);
+        }
+        /*
+         * Finally we set the output action.
+         */
+        outPorts.forEach(treatmentBuilder::setOutput);
+    }
+
+    /**
+     * Computes treatment and selector which will be used
+     * in the flow representation (Rule, Objective).
+     *
+     * @param intent the intent to compile
+     * @param inPort the input port of this device
+     * @param deviceId the current device
+     * @param outPorts the output ports of this device
+     * @return the forwarding instruction object which encapsulates treatment and selector
+     */
+    protected ForwardingInstructions createForwardingInstructions(LinkCollectionIntent intent,
+                                                                  PortNumber inPort,
+                                                                  DeviceId deviceId,
+                                                                  Set<PortNumber> outPorts) {
+
+        /*
+         * We build an empty treatment and we initialize the selector with
+         * the intent selector.
+         */
+        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment
+                .builder();
+        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector
+                .builder(intent.selector())
+                .matchInPort(inPort);
+
+        if (!intent.applyTreatmentOnEgress()) {
+            manageMpIntent(selectorBuilder,
+                           treatmentBuilder,
+                           intent,
+                           inPort,
+                           deviceId,
+                           outPorts
+            );
+        } else {
+            manageSpIntent(selectorBuilder,
+                           treatmentBuilder,
+                           intent,
+                           deviceId,
+                           outPorts
+            );
+        }
+        /*
+         * We return selector and treatment necessary to build the flow rule
+         * or the flow objective.
+         */
+        return new ForwardingInstructions(treatmentBuilder.build(), selectorBuilder.build());
+    }
+
+    /**
+     * Manages the ingress of the Intents (p2p, sp2mp, mp2sp) with encapsulation.
+     *
+     * @param selectorBuilder the selector builder to update
+     * @param treatmentBuilder the treatment builder to update
+     * @param intent the intent to compile
+     * @param inPort the input port of this device
+     * @param deviceId the current device
+     * @param outPorts the output ports of this device
+     * @param outLabels the labels associated to the output port
+     * @param type the encapsulation type
+     */
+    private void manageEncapAtIngress(TrafficSelector.Builder selectorBuilder,
+                                      TrafficTreatment.Builder treatmentBuilder,
+                                      LinkCollectionIntent intent,
+                                      PortNumber inPort,
+                                      DeviceId deviceId,
+                                      Set<PortNumber> outPorts,
+                                      Map<ConnectPoint, Identifier<?>> outLabels,
+                                      EncapsulationType type) {
+
+        Optional<FilteredConnectPoint> filteredIngressPoint =
+                getFilteredConnectPointFromIntent(deviceId, inPort, intent);
+        /*
+         * We fill the selector builder with the intent selector.
+         */
+        intent.selector().criteria().forEach(selectorBuilder::add);
+        /*
+         * We build the final selector, adding the selector
+         * of the FIP to the Intent selector and potentially
+         * overriding its matches.
+         */
+        filteredIngressPoint.get()
+                .trafficSelector()
+                .criteria()
+                .forEach(selectorBuilder::add);
+        /*
+         * In this scenario, we can have several output ports.
+         */
+        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);
+        });
+
+    }
+
+    /**
+     * Manages the core and transit of the Intents (p2p, sp2mp, mp2sp)
+     * with encapsulation.
+     *
+     * @param selectorBuilder the selector builder to update
+     * @param treatmentBuilder the treatment builder to update
+     * @param intent the intent to compile
+     * @param inPort the input port of this device
+     * @param inLabel the label associated to the input port
+     * @param deviceId the current device
+     * @param outPorts the output ports of this device
+     * @param outLabels the labels associated to the output port
+     * @param type the encapsulation type
+     */
+    private void manageEncapAtCoreAndEgress(TrafficSelector.Builder selectorBuilder,
+                                            TrafficTreatment.Builder treatmentBuilder,
+                                            LinkCollectionIntent intent,
+                                            PortNumber inPort,
+                                            Identifier<?> inLabel,
+                                            DeviceId deviceId,
+                                            Set<PortNumber> outPorts,
+                                            Map<ConnectPoint, Identifier<?>> outLabels,
+                                            EncapsulationType type) {
+
+        /*
+         * If there are not labels, we cannot handle.
+         */
+        ConnectPoint inCp = new ConnectPoint(deviceId, inPort);
+        if (inLabel == null) {
+            throw new IntentCompilationException(String.format(NO_LABELS, inCp));
+        }
+        /*
+         * In the core and at egress we match using encapsulation.
+         */
+        updateSelectorFromEncapsulation(
+                selectorBuilder,
+                type,
+                inLabel
+        );
+        /*
+         * We need to order the actions. First the actions
+         * related to the not-egress points.
+         */
+        outPorts.forEach(outPort -> {
+            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);
+            }
+
+        });
+        /*
+         * In this case, we have to transit to the final
+         * state.
+         */
+        outPorts.forEach(outPort -> {
+            Optional<FilteredConnectPoint> filteredEgressPoint =
+                    getFilteredConnectPointFromIntent(deviceId, outPort, intent);
+            if (filteredEgressPoint.isPresent()) {
+                /*
+                 * We add the Intent treatment to the final
+                 * treatment.
+                 */
+                intent.treatment().allInstructions().stream()
+                        .filter(inst -> inst.type() != Instruction.Type.NOACTION)
+                        .forEach(treatmentBuilder::add);
+                /*
+                 * We generate the transition FIP->FEP.
+                 */
+                TrafficTreatment forwardingTreatment =
+                        forwardingTreatment(selectorBuilder.build(),
+                                            filteredEgressPoint.get().trafficSelector(),
+                                            getEthType(intent.selector()));
+                /*
+                 * We add the instruction necessary to the transition.
+                 * Potentially we override the intent treatment.
+                 */
+                forwardingTreatment.allInstructions().stream()
+                        .filter(inst -> inst.type() != Instruction.Type.NOACTION)
+                        .forEach(treatmentBuilder::add);
+                /*
+                 * Finally we set the output action.
+                 */
+                treatmentBuilder.setOutput(outPort);
+            }
+        });
+
+    }
+
+    /**
+     * Computes treatment and selector which will be used
+     * in the flow representation (Rule, Objective).
+     *
+     * @param intent the intent to compile
+     * @param inPort the input port of this device
+     * @param inLabel the label associated to the input port
+     * @param deviceId the current device
+     * @param outPorts the output ports of this device
+     * @param outLabels the labels associated to the output port
+     * @param type the encapsulation type
+     * @return the forwarding instruction object which encapsulates treatment and selector
+     */
+    protected ForwardingInstructions createForwardingInstructions(LinkCollectionIntent intent,
+                                                                  PortNumber inPort,
+                                                                  Identifier<?> inLabel,
+                                                                  DeviceId deviceId,
+                                                                  Set<PortNumber> outPorts,
+                                                                  Map<ConnectPoint, Identifier<?>> outLabels,
+                                                                  EncapsulationType type) {
+        /*
+         * We build an empty treatment and an empty selector.
+         */
+        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+        selectorBuilder.matchInPort(inPort);
+        Optional<FilteredConnectPoint> filteredIngressPoint =
+                getFilteredConnectPointFromIntent(deviceId, inPort, intent);
+
+        if (filteredIngressPoint.isPresent()) {
+            manageEncapAtIngress(selectorBuilder,
+                                 treatmentBuilder,
+                                 intent,
+                                 inPort,
+                                 deviceId,
+                                 outPorts,
+                                 outLabels,
+                                 type
+            );
+        } else {
+            manageEncapAtCoreAndEgress(selectorBuilder,
+                                       treatmentBuilder,
+                                       intent,
+                                       inPort,
+                                       inLabel,
+                                       deviceId,
+                                       outPorts,
+                                       outLabels,
+                                       type);
+        }
+        /*
+         * We return selector and treatment necessary to build the flow rule
+         * or the flow objective.
+         */
+        return new ForwardingInstructions(treatmentBuilder.build(), selectorBuilder.build());
+    }
+
+    /**
+     * Helper class to encapsulate treatment and selector
+     * in an unique abstraction.
      */
     protected class ForwardingInstructions {
 
@@ -100,7 +777,8 @@
     }
 
     /**
-     * Helper method to compute input and output ports.
+     * Helper method to compute input and output ports
+     * for each device crossed in the path.
      *
      * @param intent the related intents
      * @param inputPorts the input ports to compute
@@ -122,169 +800,25 @@
         for (ConnectPoint egressPoint : intent.egressPoints()) {
             outputPorts.put(egressPoint.deviceId(), egressPoint.port());
         }
-    }
-
-    /**
-     * Gets ingress and egress port number of specific device.
-     *
-     * @param intent the related
-     * @param deviceId device Id
-     * @param ingressPorts the ingress ports to compute
-     * @param egressPorts the egress ports to compute
-     */
-    protected void computePorts(LinkCollectionIntent intent,
-                                DeviceId deviceId,
-                                Set<PortNumber> ingressPorts,
-                                Set<PortNumber> egressPorts) {
-
-        if (!intent.applyTreatmentOnEgress()) {
-            ingressPorts.addAll(intent.ingressPoints().stream()
-                    .filter(point -> point.deviceId().equals(deviceId))
-                    .map(ConnectPoint::port)
-                    .collect(Collectors.toSet()));
-        } else {
-            egressPorts.addAll(intent.egressPoints().stream()
-                    .filter(point -> point.deviceId().equals(deviceId))
-                    .map(ConnectPoint::port)
-                    .collect(Collectors.toSet()));
-        }
 
     }
 
     /**
-     * Creates the flows representations.
+     * Retrieves the encapsulation constraint from the link collection intent.
      *
-     * @param intent the intent to compile
-     * @param deviceId the affected device
-     * @param inPorts the input ports
-     * @param outPorts the output ports
-     * @return the list of flows representations
+     * @param intent the intent to analyze
+     * @return the encapsulation constraint
      */
-    protected List<T> createRules(LinkCollectionIntent intent, DeviceId deviceId,
-                                       Set<PortNumber> inPorts, Set<PortNumber> outPorts) {
-        return null;
+    protected Optional<EncapsulationConstraint> getIntentEncapConstraint(LinkCollectionIntent intent) {
+        return intent.constraints().stream()
+                .filter(constraint -> constraint instanceof EncapsulationConstraint)
+                .map(x -> (EncapsulationConstraint) x).findAny();
     }
 
 
     /**
-     * Computes treatment and selector which will be used
-     * in the flow representation (Rule, Objective).
-     *
-     * @param intent the intent to compile
-     * @param inPort the input port of this device
-     * @param deviceId the current device
-     * @param outPorts the output ports of this device
-     * @param ingressPorts intent ingress ports of this device
-     * @param egressPorts intent egress ports of this device
-     * @return the forwarding instruction object which encapsulates treatment and selector
-     */
-    protected ForwardingInstructions createForwardingInstructions(LinkCollectionIntent intent,
-                                                                  PortNumber inPort,
-                                                                  DeviceId deviceId,
-                                                                  Set<PortNumber> outPorts,
-                                                                  Set<PortNumber> ingressPorts,
-                                                                  Set<PortNumber> egressPorts) {
-
-        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
-        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
-        selectorBuilder.matchInPort(inPort);
-
-        if (!intent.applyTreatmentOnEgress()) {
-            // FIXME: currently, we assume this intent is compile from mp2sp intent
-            Optional<FilteredConnectPoint> filteredIngressPoint =
-                    getFilteredConnectPointFromIntent(deviceId, inPort, intent);
-            Optional<FilteredConnectPoint> filteredEgressPoint =
-                    intent.filteredEgressPoints().stream().findFirst();
-
-            if (filteredIngressPoint.isPresent()) {
-                // Ingress device
-                intent.treatment().allInstructions().stream()
-                        .filter(inst -> inst.type() != Instruction.Type.NOACTION)
-                        .forEach(treatmentBuilder::add);
-
-                if (filteredEgressPoint.isPresent()) {
-                    // Apply selector from ingress point
-                    filteredIngressPoint.get()
-                            .trafficSelector()
-                            .criteria()
-                            .forEach(selectorBuilder::add);
-
-                    TrafficTreatment forwardingTreatment =
-                            forwardingTreatment(filteredIngressPoint.get(),
-                                                filteredEgressPoint.get());
-
-                    forwardingTreatment.allInstructions().stream()
-                            .filter(inst -> inst.type() != Instruction.Type.NOACTION)
-                            .forEach(treatmentBuilder::add);
-                } else {
-                    throw new IntentCompilationException("Can't find filtered connection point");
-                }
-
-            } else {
-                // Not ingress device, won't apply treatments.
-                // Use selector by treatment from intent.
-                updateBuilder(selectorBuilder, intent.treatment());
-
-                // Selector should be overridden by selector from connect point.
-                if (filteredEgressPoint.isPresent()) {
-                    filteredEgressPoint.get()
-                            .trafficSelector()
-                            .criteria()
-                            .forEach(selectorBuilder::add);
-                }
-
-            }
-
-            outPorts.forEach(treatmentBuilder::setOutput);
-
-        } else {
-            // FIXME: currently, we assume this intent is compile from sp2mp intent
-            Optional<FilteredConnectPoint> filteredIngressPoint =
-                    intent.filteredIngressPoints().stream().findFirst();
-
-            if (filteredIngressPoint.isPresent()) {
-                // Apply selector from ingress point
-                filteredIngressPoint.get()
-                        .trafficSelector()
-                        .criteria()
-                        .forEach(selectorBuilder::add);
-            } else {
-                throw new IntentCompilationException(
-                        "Filtered connection point for ingress" +
-                                "point does not exist");
-            }
-
-            for (PortNumber outPort : outPorts) {
-                Optional<FilteredConnectPoint> filteredEgressPoint =
-                        getFilteredConnectPointFromIntent(deviceId, outPort, intent);
-
-                if (filteredEgressPoint.isPresent()) {
-                    // Egress port, apply treatment + forwarding treatment
-                    intent.treatment().allInstructions().stream()
-                            .filter(inst -> inst.type() != Instruction.Type.NOACTION)
-                            .forEach(treatmentBuilder::add);
-
-                    TrafficTreatment forwardingTreatment =
-                            forwardingTreatment(filteredIngressPoint.get(),
-                                                filteredEgressPoint.get());
-                    forwardingTreatment.allInstructions().stream()
-                            .filter(inst -> inst.type() != Instruction.Type.NOACTION)
-                            .forEach(treatmentBuilder::add);
-                }
-
-                treatmentBuilder.setOutput(outPort);
-
-            }
-
-        }
-
-
-        return new ForwardingInstructions(treatmentBuilder.build(), selectorBuilder.build());
-
-    }
-
-    /**
      * Get FilteredConnectPoint from LinkCollectionIntent.
+     *
      * @param deviceId device Id for connect point
      * @param portNumber port number
      * @param intent source intent
@@ -320,15 +854,17 @@
      * Compares tag type between ingress and egress point and generate
      * treatment for egress point of intent.
      *
-     * @param ingress ingress point for the intent
-     * @param egress egress point for the intent
+     * @param ingress ingress selector for the intent
+     * @param egress egress selector for the intent
+     * @param ethType the ethertype to use in mpls_pop
      * @return Builder of TrafficTreatment
      */
-    private TrafficTreatment forwardingTreatment(FilteredConnectPoint ingress,
-                                                         FilteredConnectPoint egress) {
+    private TrafficTreatment forwardingTreatment(TrafficSelector ingress,
+                                                 TrafficSelector egress,
+                                                 EthType ethType) {
 
 
-        if (ingress.trafficSelector().equals(egress.trafficSelector())) {
+        if (ingress.equals(egress)) {
             return DefaultTrafficTreatment.emptyTreatment();
         }
 
@@ -338,8 +874,8 @@
          * "null" means there is no tag for the port
          * Tag criterion will be null if port is normal connection point
          */
-        Criterion ingressTagCriterion = getTagCriterion(ingress.trafficSelector());
-        Criterion egressTagCriterion = getTagCriterion(egress.trafficSelector());
+        Criterion ingressTagCriterion = getTagCriterion(ingress);
+        Criterion egressTagCriterion = getTagCriterion(egress);
 
         if (ingressTagCriterion.type() != egressTagCriterion.type()) {
 
@@ -353,11 +889,14 @@
                 case VLAN_VID:
                     builder.popVlan();
                     break;
+
                 case MPLS_LABEL:
-                    builder.popMpls();
+                    builder.popMpls(ethType);
                     break;
+
                 default:
                     break;
+
             }
 
             /*
@@ -367,11 +906,14 @@
                 case VLAN_VID:
                     builder.pushVlan();
                     break;
+
                 case MPLS_LABEL:
                     builder.pushMpls();
                     break;
+
                 default:
                     break;
+
             }
         }
 
@@ -380,16 +922,20 @@
                 VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) egressTagCriterion;
                 builder.setVlanId(vlanIdCriterion.vlanId());
                 break;
+
             case MPLS_LABEL:
                 MplsCriterion mplsCriterion = (MplsCriterion) egressTagCriterion;
                 builder.setMpls(mplsCriterion.label());
                 break;
+
             case TUNNEL_ID:
                 TunnelIdCriterion tunnelIdCriterion = (TunnelIdCriterion) egressTagCriterion;
                 builder.setTunnelId(tunnelIdCriterion.tunnelId());
                 break;
+
             default:
                 break;
+
         }
 
         return builder.build();
@@ -402,7 +948,7 @@
      * @param l0instruction the l0 instruction to use
      */
     private void updateBuilder(TrafficSelector.Builder builder, L0ModificationInstruction l0instruction) {
-        throw new IntentCompilationException("L0 not supported");
+        throw new IntentCompilationException(UNSUPPORTED_L0);
     }
 
     /**
@@ -412,7 +958,7 @@
      * @param l1instruction the l1 instruction to use
      */
     private void updateBuilder(TrafficSelector.Builder builder, L1ModificationInstruction l1instruction) {
-        throw new IntentCompilationException("L1 not supported");
+        throw new IntentCompilationException(UNSUPPORTED_L1);
     }
 
     /**
@@ -430,49 +976,59 @@
                     case ETH_SRC:
                         builder.matchEthSrc(ethInstr.mac());
                         break;
+
                     case ETH_DST:
                         builder.matchEthDst(ethInstr.mac());
                         break;
+
                     default:
-                        throw new IntentCompilationException("Bad eth subtype");
+                        throw new IntentCompilationException(UNSUPPORTED_ETH_SUBTYPE);
                 }
                 break;
+
             case VLAN_ID:
                 ModVlanIdInstruction vlanIdInstr = (ModVlanIdInstruction) l2instruction;
                 builder.matchVlanId(vlanIdInstr.vlanId());
                 break;
+
             case VLAN_PUSH:
                 //FIXME
                 break;
+
             case VLAN_POP:
                 //TODO how do we handle dropped label? remove the selector?
-                throw new IntentCompilationException("Can't handle pop label");
+                throw new IntentCompilationException(UNSUPPORTED_POP_ACTION);
             case VLAN_PCP:
                 ModVlanPcpInstruction vlanPcpInstruction = (ModVlanPcpInstruction) l2instruction;
                 builder.matchVlanPcp(vlanPcpInstruction.vlanPcp());
                 break;
+
             case MPLS_LABEL:
             case MPLS_PUSH:
                 //FIXME
                 ModMplsLabelInstruction mplsInstr = (ModMplsLabelInstruction) l2instruction;
                 builder.matchMplsLabel(mplsInstr.label());
                 break;
+
             case MPLS_POP:
                 //TODO how do we handle dropped label? remove the selector?
-                throw new IntentCompilationException("Can't handle pop label");
+                throw new IntentCompilationException(UNSUPPORTED_POP_ACTION);
             case DEC_MPLS_TTL:
                 // no-op
                 break;
+
             case MPLS_BOS:
                 ModMplsBosInstruction mplsBosInstr = (ModMplsBosInstruction) l2instruction;
                 builder.matchMplsBos(mplsBosInstr.mplsBos());
                 break;
+
             case TUNNEL_ID:
                 ModTunnelIdInstruction tunInstr = (ModTunnelIdInstruction) l2instruction;
                 builder.matchTunnelId(tunInstr.tunnelId());
                 break;
+
             default:
-                throw new IntentCompilationException("Unknown L2 Modification instruction");
+                throw new IntentCompilationException(UNSUPPORTED_L2);
         }
 
     }
@@ -497,51 +1053,63 @@
                     case IPV4_SRC:
                         builder.matchIPSrc(prefix);
                         break;
+
                     case IPV4_DST:
                         builder.matchIPSrc(prefix);
                         break;
+
                     case IPV6_SRC:
                         builder.matchIPv6Src(prefix);
                         break;
+
                     case IPV6_DST:
                         builder.matchIPv6Dst(prefix);
                         break;
+
                     default:
-                        throw new IntentCompilationException("Bad type for IP instruction");
+                        throw new IntentCompilationException(UNSUPPORTED_IP_SUBTYPE);
                 }
                 break;
+
             case IPV6_FLABEL:
                 ModIPv6FlowLabelInstruction ipFlowInstr = (ModIPv6FlowLabelInstruction) l3instruction;
                 builder.matchIPv6FlowLabel(ipFlowInstr.flowLabel());
                 break;
+
             case DEC_TTL:
                 // no-op
                 break;
+
             case TTL_OUT:
                 // no-op
                 break;
+
             case TTL_IN:
                 // no-op
                 break;
+
             case ARP_SPA:
                 ModArpIPInstruction arpIpInstr = (ModArpIPInstruction) l3instruction;
                 if (arpIpInstr.ip().isIp4()) {
                     builder.matchArpSpa((Ip4Address) arpIpInstr.ip());
                 } else {
-                    throw new IntentCompilationException("IPv6 not supported for ARP");
+                    throw new IntentCompilationException(UNSUPPORTED_ARP);
                 }
                 break;
+
             case ARP_SHA:
                 ModArpEthInstruction arpEthInstr = (ModArpEthInstruction) l3instruction;
                 builder.matchArpSha(arpEthInstr.mac());
                 break;
+
             case ARP_OP:
                 ModArpOpInstruction arpOpInstr = (ModArpOpInstruction) l3instruction;
                 //FIXME is the long to int cast safe?
                 builder.matchArpOp((int) arpOpInstr.op());
                 break;
+
             default:
-                throw new IntentCompilationException("Unknown L3 Modification instruction");
+                throw new IntentCompilationException(UNSUPPORTED_L3);
         }
     }
 
@@ -559,20 +1127,24 @@
                 case TCP_SRC:
                     builder.matchTcpSrc(l4mod.port());
                     break;
+
                 case TCP_DST:
                     builder.matchTcpDst(l4mod.port());
                     break;
+
                 case UDP_SRC:
                     builder.matchUdpSrc(l4mod.port());
                     break;
+
                 case UDP_DST:
                     builder.matchUdpDst(l4mod.port());
                     break;
+
                 default:
-                    throw new IntentCompilationException("Unknown L4 Modification instruction");
+                    throw new IntentCompilationException(UNSUPPORTED_L4_SUBTYPE);
             }
         } else {
-            throw new IntentCompilationException("Unknown L4 Modification instruction");
+            throw new IntentCompilationException(UNSUPPORTED_L4);
         }
     }
 
@@ -589,18 +1161,23 @@
                 case L0MODIFICATION:
                     updateBuilder(builder, (L0ModificationInstruction) instruction);
                     break;
+
                 case L1MODIFICATION:
                     updateBuilder(builder, (L1ModificationInstruction) instruction);
                     break;
+
                 case L2MODIFICATION:
                     updateBuilder(builder, (L2ModificationInstruction) instruction);
                     break;
+
                 case L3MODIFICATION:
                     updateBuilder(builder, (L3ModificationInstruction) instruction);
                     break;
+
                 case L4MODIFICATION:
                     updateBuilder(builder, (L4ModificationInstruction) instruction);
                     break;
+
                 case NOACTION:
                 case OUTPUT:
                 case GROUP:
@@ -611,11 +1188,57 @@
                 case EXTENSION: // TODO is extension no-op or unsupported?
                     // Nothing to do
                     break;
+
                 default:
-                    throw new IntentCompilationException("Unknown instruction type");
+                    throw new IntentCompilationException(UNSUPPORTED_INSTRUCTION);
             }
         });
 
     }
 
+    /**
+     * The method generates a selector starting from
+     * the encapsulation information (type and label to match).
+     *
+     * @param selectorBuilder the builder to update
+     * @param type the type of encapsulation
+     * @param identifier the label to match
+     */
+    private void updateSelectorFromEncapsulation(TrafficSelector.Builder selectorBuilder,
+                                                 EncapsulationType type,
+                                                 Identifier<?> identifier) {
+        switch (type) {
+            case MPLS:
+                MplsLabel label = (MplsLabel) identifier;
+                selectorBuilder.matchMplsLabel(label);
+                selectorBuilder.matchEthType(Ethernet.MPLS_UNICAST);
+                break;
+
+            case VLAN:
+                VlanId id = (VlanId) identifier;
+                selectorBuilder.matchVlanId(id);
+                break;
+
+            default:
+                throw new IntentCompilationException(UNKNOWN_ENCAPSULATION);
+        }
+    }
+
+    /**
+     * Helper function to define the match on the ethertype.
+     * If the selector define an ethertype we will use it,
+     * otherwise IPv4 will be used by default.
+     *
+     * @param selector the traffic selector
+     * @return the ethertype we should match
+     */
+    private EthType getEthType(TrafficSelector selector) {
+        Criterion c = selector.getCriterion(Criterion.Type.ETH_TYPE);
+        if (c != null && c instanceof EthTypeCriterion) {
+            EthTypeCriterion ethertype = (EthTypeCriterion) c;
+            return ethertype.ethType();
+        }
+        return EthType.EtherType.IPV4.ethType();
+    }
+
 }
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompiler.java
index 1f22429..e464e99 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompiler.java
@@ -16,16 +16,17 @@
 package org.onosproject.net.intent.impl.compiler;
 
 import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.util.Identifier;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
+import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.DefaultFlowRule;
@@ -34,12 +35,17 @@
 import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentCompiler;
 import org.onosproject.net.intent.LinkCollectionIntent;
+import org.onosproject.net.intent.constraint.EncapsulationConstraint;
+import org.onosproject.net.resource.ResourceService;
+import org.onosproject.net.resource.impl.LabelAllocator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 
 /**
@@ -59,12 +65,18 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected CoreService coreService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ResourceService resourceService;
+
     private ApplicationId appId;
 
     @Activate
     public void activate() {
         appId = coreService.registerApplication("org.onosproject.net.intent");
         registrator.registerCompiler(LinkCollectionIntent.class, this, false);
+        if (labelAllocator == null) {
+            labelAllocator = new LabelAllocator(resourceService);
+        }
     }
 
     @Deactivate
@@ -77,36 +89,55 @@
 
         SetMultimap<DeviceId, PortNumber> inputPorts = HashMultimap.create();
         SetMultimap<DeviceId, PortNumber> outputPorts = HashMultimap.create();
+        Map<ConnectPoint, Identifier<?>> labels = ImmutableMap.of();
+
+        Optional<EncapsulationConstraint> encapConstraint = this.getIntentEncapConstraint(intent);
 
         computePorts(intent, inputPorts, outputPorts);
 
+        if (encapConstraint.isPresent()) {
+            labels = labelAllocator.assignLabelToPorts(intent.links(),
+                                                       intent.id(),
+                                                       encapConstraint.get().encapType());
+        }
+
         List<FlowRule> rules = new ArrayList<>();
         for (DeviceId deviceId: outputPorts.keySet()) {
-            rules.addAll(createRules(intent, deviceId, inputPorts.get(deviceId), outputPorts.get(deviceId)));
+            rules.addAll(createRules(
+                    intent,
+                    deviceId,
+                    inputPorts.get(deviceId),
+                    outputPorts.get(deviceId),
+                    labels)
+            );
         }
         return Collections.singletonList(new FlowRuleIntent(appId, rules, intent.resources()));
     }
 
     @Override
-    protected List<FlowRule> createRules(LinkCollectionIntent intent, DeviceId deviceId,
-                                       Set<PortNumber> inPorts, Set<PortNumber> outPorts) {
-
-        Set<PortNumber> ingressPorts = Sets.newHashSet();
-        Set<PortNumber> egressPorts = Sets.newHashSet();
-
-        computePorts(intent, deviceId, ingressPorts, egressPorts);
+    protected List<FlowRule> createRules(LinkCollectionIntent intent,
+                                         DeviceId deviceId,
+                                         Set<PortNumber> inPorts,
+                                         Set<PortNumber> outPorts,
+                                         Map<ConnectPoint, Identifier<?>> labels) {
 
         List<FlowRule> rules = new ArrayList<>(inPorts.size());
-        Set<PortNumber> copyIngressPorts = ImmutableSet.copyOf(ingressPorts);
-        Set<PortNumber> copyEgressPorts = ImmutableSet.copyOf(egressPorts);
+        /*
+         * Looking for the encapsulation constraint
+         */
+        Optional<EncapsulationConstraint> encapConstraint = this.getIntentEncapConstraint(intent);
 
         inPorts.forEach(inport -> {
-                ForwardingInstructions instructions = this.createForwardingInstructions(intent,
-                                                                                        inport,
-                                                                                        deviceId,
-                                                                                        outPorts,
-                                                                                        copyIngressPorts,
-                                                                                        copyEgressPorts);
+
+                ForwardingInstructions instructions = this.createForwardingInstruction(
+                        encapConstraint,
+                        intent,
+                        inport,
+                        outPorts,
+                        deviceId,
+                        labels
+                );
+
                 FlowRule rule = DefaultFlowRule.builder()
                         .forDevice(deviceId)
                         .withSelector(instructions.selector())
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentFlowObjectiveCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentFlowObjectiveCompiler.java
index 0d6ad0a..0a15097 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentFlowObjectiveCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentFlowObjectiveCompiler.java
@@ -16,16 +16,17 @@
 package org.onosproject.net.intent.impl.compiler;
 
 import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.util.Identifier;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
+import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.flowobjective.DefaultForwardingObjective;
@@ -38,10 +39,15 @@
 import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentCompiler;
 import org.onosproject.net.intent.LinkCollectionIntent;
+import org.onosproject.net.intent.constraint.EncapsulationConstraint;
+import org.onosproject.net.resource.ResourceService;
+import org.onosproject.net.resource.impl.LabelAllocator;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 
 /**
@@ -61,12 +67,19 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected FlowObjectiveService flowObjectiveService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ResourceService resourceService;
+
     private ApplicationId appId;
 
     @Activate
     public void activate() {
         appId = coreService.registerApplication("org.onosproject.net.intent");
         registrator.registerCompiler(LinkCollectionIntent.class, this, true);
+        if (labelAllocator == null) {
+            labelAllocator = new LabelAllocator(resourceService);
+        }
+
     }
 
     @Deactivate
@@ -79,9 +92,18 @@
 
         SetMultimap<DeviceId, PortNumber> inputPorts = HashMultimap.create();
         SetMultimap<DeviceId, PortNumber> outputPorts = HashMultimap.create();
+        Map<ConnectPoint, Identifier<?>> labels = ImmutableMap.of();
+
+        Optional<EncapsulationConstraint> encapConstraint = this.getIntentEncapConstraint(intent);
 
         computePorts(intent, inputPorts, outputPorts);
 
+        if (encapConstraint.isPresent()) {
+            labels = labelAllocator.assignLabelToPorts(intent.links(),
+                                                       intent.id(),
+                                                       encapConstraint.get().encapType());
+        }
+
         List<Objective> objectives = new ArrayList<>();
         List<DeviceId> devices = new ArrayList<>();
         for (DeviceId deviceId: outputPorts.keys()) {
@@ -89,7 +111,8 @@
                     createRules(intent,
                                 deviceId,
                                 inputPorts.get(deviceId),
-                                outputPorts.get(deviceId));
+                                outputPorts.get(deviceId),
+                                labels);
             deviceObjectives.forEach(objective -> {
                 objectives.add(objective);
                 devices.add(deviceId);
@@ -100,25 +123,29 @@
     }
 
     @Override
-    protected List<Objective> createRules(LinkCollectionIntent intent, DeviceId deviceId,
-                                       Set<PortNumber> inPorts, Set<PortNumber> outPorts) {
-
-        Set<PortNumber> ingressPorts = Sets.newHashSet();
-        Set<PortNumber> egressPorts = Sets.newHashSet();
-
-        computePorts(intent, deviceId, ingressPorts, egressPorts);
+    protected List<Objective> createRules(LinkCollectionIntent intent,
+                                          DeviceId deviceId,
+                                          Set<PortNumber> inPorts,
+                                          Set<PortNumber> outPorts,
+                                          Map<ConnectPoint, Identifier<?>> labels) {
 
         List<Objective> objectives = new ArrayList<>(inPorts.size());
-        Set<PortNumber> copyIngressPorts = ImmutableSet.copyOf(ingressPorts);
-        Set<PortNumber> copyEgressPorts = ImmutableSet.copyOf(egressPorts);
+
+        /*
+         * Looking for the encapsulation constraint
+         */
+        Optional<EncapsulationConstraint> encapConstraint = this.getIntentEncapConstraint(intent);
 
         inPorts.forEach(inport -> {
-            ForwardingInstructions instructions = this.createForwardingInstructions(intent,
-                                                                                    inport,
-                                                                                    deviceId,
-                                                                                    outPorts,
-                                                                                    copyIngressPorts,
-                                                                                    copyEgressPorts);
+
+            ForwardingInstructions instructions = this.createForwardingInstruction(
+                    encapConstraint,
+                    intent,
+                    inport,
+                    outPorts,
+                    deviceId,
+                    labels
+            );
 
             NextObjective nextObjective = DefaultNextObjective.builder()
                     .withId(flowObjectiveService.allocateNextId())
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
new file mode 100644
index 0000000..9a8324c
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.IntentExtensionService;
+import org.onosproject.net.intent.LinkCollectionIntent;
+import org.onosproject.net.intent.MockIdGenerator;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.onosproject.net.NetTestTools.*;
+import static org.onosproject.net.NetTestTools.macDstTreatment;
+
+/**
+ * Abstract class to hold the common variables and pieces
+ * of code.
+ */
+class AbstractLinkCollectionTest {
+
+    static final String LABEL_SELECTION = "FIRST_FIT";
+    static final String LABEL = "1";
+
+    final ApplicationId appId = new TestApplicationId("test");
+
+    final ConnectPoint d2p0 = connectPoint("s2", 0);
+    final ConnectPoint d2p1 = connectPoint("s2", 1);
+    ConnectPoint d2p10 = connectPoint("s2", 10);
+
+    final ConnectPoint d3p0 = connectPoint("s3", 0);
+    final ConnectPoint d3p1 = connectPoint("s3", 1);
+    final ConnectPoint d3p10 = connectPoint("s3", 10);
+
+    final DeviceId of1Id = DeviceId.deviceId("of:of1");
+    final DeviceId of2Id = DeviceId.deviceId("of:of2");
+    final DeviceId of3Id = DeviceId.deviceId("of:of3");
+    final DeviceId of4Id = DeviceId.deviceId("of:of4");
+
+    final ConnectPoint of1p1 = connectPoint("of1", 1);
+    final ConnectPoint of1p2 = connectPoint("of1", 2);
+    final ConnectPoint of2p1 = connectPoint("of2", 1);
+    final ConnectPoint of2p2 = connectPoint("of2", 2);
+    final ConnectPoint of2p3 = connectPoint("of2", 3);
+    final ConnectPoint of3p1 = connectPoint("of3", 1);
+    final ConnectPoint of3p2 = connectPoint("of3", 2);
+    final ConnectPoint of4p1 = connectPoint("of4", 1);
+    final ConnectPoint of4p2 = connectPoint("of4", 2);
+
+    final ConnectPoint d1p0 = connectPoint("s1", 0);
+    final ConnectPoint d1p1 = connectPoint("s1", 1);
+    final ConnectPoint d1p10 = connectPoint("s1", 10);
+    final ConnectPoint d1p11 = connectPoint("s1", 11);
+
+    final Set<Link> links = ImmutableSet.of(
+            link(d1p1, d2p0),
+            link(d2p1, d3p1),
+            link(d1p1, d3p1)
+    );
+
+    final Set<Link> linksForMp2Sp = ImmutableSet.of(
+            link(d1p0, d2p0),
+            link(d2p1, d3p0)
+    );
+
+
+
+    final Set<Link> linksForSp2Mp = ImmutableSet.of(
+            link(d3p0, d2p1),
+            link(d2p0, d1p0)
+    );
+
+    final TrafficTreatment treatment = emptyTreatment();
+
+    final TrafficSelector selector = emptySelector();
+    final TrafficSelector vlan69Selector = vlanSelector("69");
+    final TrafficSelector vlan100Selector = vlanSelector("100");
+    final TrafficSelector vlan200Selector = vlanSelector("200");
+    final TrafficSelector vlan300Selector = vlanSelector("300");
+    final TrafficSelector mpls69Selector = mplsSelector("69");
+    final TrafficSelector mpls80Selector = mplsSelector("80");
+    final TrafficSelector mpls100Selector = mplsSelector("100");
+    final TrafficSelector mpls200Selector = mplsSelector("200");
+    final TrafficSelector ipPrefixSelector = ipPrefixDstSelector("192.168.100.0/24");
+    final TrafficTreatment ethDstTreatment = macDstTreatment("C0:FF:EE:C0:FF:EE");
+
+    final List<Constraint> constraintsForVlan = vlanConstraint();
+    final List<Constraint> constraintsForMPLS = mplsConstraint();
+
+    CoreService coreService;
+    IntentExtensionService intentExtensionService;
+    IntentConfigurableRegistrator registrator;
+    IdGenerator idGenerator = new MockIdGenerator();
+
+    LinkCollectionIntent intent;
+
+    LinkCollectionIntentCompiler sut;
+
+    List<FlowRule> getFlowRulesByDevice(DeviceId deviceId, Collection<FlowRule> flowRules) {
+        return flowRules.stream()
+                .filter(fr -> fr.deviceId().equals(deviceId))
+                .collect(Collectors.toList());
+    }
+
+}
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
new file mode 100644
index 0000000..588880a
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionEncapIntentCompilerTest.java
@@ -0,0 +1,1354 @@
+/*
+ * 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.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.PortCriterion;
+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.onlab.packet.EthType.EtherType.IPV4;
+import static org.onosproject.net.NetTestTools.*;
+import static org.onosproject.net.flow.criteria.Criterion.Type.*;
+import static org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
+
+/**
+ * This set of tests are meant to test the encapsulation
+ * in the LinkCollectionIntent.
+ */
+public class LinkCollectionEncapIntentCompilerTest 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();
+
+        replay(coreService, intentExtensionService);
+    }
+
+    @After
+    public void tearDown() {
+        Intent.unbindIdGenerator(idGenerator);
+    }
+
+    /**
+     * We test the proper compilation of mp2Sp1 with the VLAN
+     * encapsulation, trivial selector.
+     */
+    @Test
+    public void testVlanEncapsulationForMp() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(treatment)
+                .constraints(constraintsForVlan)
+                .links(linksForMp2Sp)
+                .filteredIngressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10),
+                        new FilteredConnectPoint(d1p11),
+                        new FilteredConnectPoint(d2p10)
+                ))
+                .filteredEgressPoints(ImmutableSet.of(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(5));
+
+        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(intent.selector())
+                        .matchInPort(d1p10.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .pushVlan()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d1p0.port())
+                        .build()
+        ));
+
+        ruleS1 = rulesS1.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d1p11.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder(intent.selector())
+                        .matchInPort(d1p11.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .pushVlan()
+                        .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(2));
+        FlowRule ruleS2 = rulesS2.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d2p10.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS2.selector(), is(
+                DefaultTrafficSelector
+                        .builder(intent.selector())
+                        .matchInPort(d2p10.port())
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .pushVlan()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d2p1.port())
+                        .build()
+        ));
+
+        ruleS2 = rulesS2.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d2p0.port());
+                })
+                .findFirst()
+                .get();
+        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()
+                        .setOutput(d3p10.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+    }
+
+    /**
+     * We test the proper compilation of sp2mp with the MPLS
+     * encapsulation and trivial selector.
+     */
+    @Test
+    public void testMplsEncapsulationForSp() {
+
+        intent = LinkCollectionIntent.builder()
+                .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();
+
+        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> 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(d3p10.port())
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .pushMpls()
+                        .setMpls(MplsLabel.mplsLabel((LABEL)))
+                        .setOutput(d3p0.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(d2p1.port())
+                        .matchMplsLabel(MplsLabel.mplsLabel((LABEL)))
+                        .matchEthType(Ethernet.MPLS_UNICAST)
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
+                        .setOutput(d2p0.port())
+                        .popMpls(IPV4.ethType())
+                        .setOutput(d2p10.port())
+                        .build()
+        ));
+
+        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()
+                        .matchInPort(d1p0.port())
+                        .matchMplsLabel(MplsLabel.mplsLabel((LABEL)))
+                        .matchEthType(Ethernet.MPLS_UNICAST)
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popMpls(IPV4.ethType())
+                        .setOutput(d1p10.port())
+                        .popMpls(IPV4.ethType())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of mp2sp with the MPLS
+     * encapsulation and filtered selector.
+     */
+    @Test
+    public void testMplsEncapsulationFilteredForMp() {
+
+        intent = LinkCollectionIntent.builder()
+                .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();
+
+        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(5));
+
+        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(vlan100Selector)
+                        .matchInPort(d1p10.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
+                        .setOutput(d1p0.port())
+                        .build()
+        ));
+
+        ruleS1 = rulesS1.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d1p11.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder(vlan200Selector)
+                        .matchInPort(d1p11.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(2));
+        FlowRule ruleS2 = rulesS2.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d2p10.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS2.selector(), is(
+                DefaultTrafficSelector
+                        .builder(vlan300Selector)
+                        .matchInPort(d2p10.port())
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
+                        .setOutput(d2p1.port())
+                        .build()
+        ));
+
+        ruleS2 = rulesS2.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d2p0.port());
+                })
+                .findFirst()
+                .get();
+        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()
+                        .popMpls(IPV4.ethType())
+                        .pushVlan()
+                        .setVlanId(((VlanIdCriterion) vlan69Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d3p10.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of sp2mp with the VLAN
+     * encapsulation and filtered selector.
+     */
+    @Test
+    public void testVlanEncapsulationFilteredForSp() {
+
+        intent = LinkCollectionIntent.builder()
+                .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();
+
+        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> 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(mpls69Selector)
+                        .matchInPort(d3p10.port())
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popMpls(IPV4.ethType())
+                        .pushVlan()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d3p0.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(d2p1.port())
+                        .matchVlanId(VlanId.vlanId(LABEL))
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d2p0.port())
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(((MplsCriterion) mpls80Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d2p10.port())
+                        .build()
+        ));
+
+        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()
+                        .matchInPort(d1p0.port())
+                        .matchVlanId(VlanId.vlanId(LABEL))
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p10.port())
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of mp2sp with the VLAN
+     * encapsulation, filtered selectors, intent selector and intent treatment.
+     */
+    @Test
+    public void testVlanEncapsulationNonTrivialForMp() {
+
+        intent = LinkCollectionIntent.builder()
+                .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();
+
+        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(5));
+
+        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) mpls80Selector.getCriterion(MPLS_LABEL)).label())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popMpls(IPV4.ethType())
+                        .pushVlan()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d1p0.port())
+                        .build()
+        ));
+
+        ruleS1 = rulesS1.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d1p11.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder(ipPrefixSelector)
+                        .matchInPort(d1p11.port())
+                        .matchMplsLabel(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popMpls(IPV4.ethType())
+                        .pushVlan()
+                        .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(2));
+        FlowRule ruleS2 = rulesS2.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d2p10.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS2.selector(), is(
+                DefaultTrafficSelector
+                        .builder(ipPrefixSelector)
+                        .matchInPort(d2p10.port())
+                        .matchMplsLabel(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popMpls(IPV4.ethType())
+                        .pushVlan()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d2p1.port())
+                        .build()
+        ));
+
+        ruleS2 = rulesS2.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d2p0.port());
+                })
+                .findFirst()
+                .get();
+        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(ethDstTreatment)
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(((MplsCriterion) mpls69Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d3p10.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of sp2mp with the MPLS
+     * encapsulation, filtered selector, intent selector, and
+     * intent treatment.
+     */
+    @Test
+    public void testMplsEncapsulationNonTrivialForSp() {
+
+        intent = LinkCollectionIntent.builder()
+                .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();
+
+        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> 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(ipPrefixSelector)
+                        .matchInPort(d3p10.port())
+                        .matchVlanId(((VlanIdCriterion) vlan69Selector.getCriterion(VLAN_VID)).vlanId())
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
+                        .setOutput(d3p0.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(d2p1.port())
+                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+                        .matchEthType(Ethernet.MPLS_UNICAST)
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
+                        .setOutput(d2p0.port())
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                           .allInstructions()
+                                           .stream()
+                                           .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                           .findFirst().get()).mac())
+                        .popMpls(IPV4.ethType())
+                        .pushVlan()
+                        .setVlanId(((VlanIdCriterion) vlan300Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d2p10.port())
+                        .build()
+        ));
+
+        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()
+                        .matchInPort(d1p0.port())
+                        .matchMplsLabel(MplsLabel.mplsLabel(LABEL))
+                        .matchEthType(Ethernet.MPLS_UNICAST)
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                .allInstructions()
+                                .stream()
+                                .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                .findFirst().get()).mac())
+                        .popMpls(IPV4.ethType())
+                        .pushVlan()
+                        .setVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d1p10.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(d1p11.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of mp2sp with the MPLS
+     * encapsulation and filtered selectors of different type.
+     */
+    @Test
+    public void testMplsEncapsulationDifferentFilterForMp() {
+
+        intent = LinkCollectionIntent.builder()
+                .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();
+
+        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(5));
+
+        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(vlan100Selector)
+                        .matchInPort(d1p10.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
+                        .setOutput(d1p0.port())
+                        .build()
+        ));
+
+        ruleS1 = rulesS1.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d1p11.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS1.selector(), is(
+                DefaultTrafficSelector
+                        .builder(mpls200Selector)
+                        .matchInPort(d1p11.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .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(2));
+        FlowRule ruleS2 = rulesS2.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d2p10.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS2.selector(), is(
+                DefaultTrafficSelector
+                        .builder(vlan200Selector)
+                        .matchInPort(d2p10.port())
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
+                        .setOutput(d2p1.port())
+                        .build()
+        ));
+
+        ruleS2 = rulesS2.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d2p0.port());
+                })
+                .findFirst()
+                .get();
+        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) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d3p10.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of sp2mp with the VLAN
+     * encapsulation and filtered selectors of different type.
+     */
+    @Test
+    public void testVlanEncapsulationDifferentFilter() {
+
+        intent = LinkCollectionIntent.builder()
+                .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();
+
+        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> 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(vlan200Selector)
+                        .matchInPort(d3p10.port())
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d3p0.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(d2p1.port())
+                        .matchVlanId(VlanId.vlanId(LABEL))
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setVlanId(VlanId.vlanId(LABEL))
+                        .setOutput(d2p0.port())
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d2p10.port())
+                        .build()
+        ));
+
+        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()
+                        .matchInPort(d1p0.port())
+                        .matchVlanId(VlanId.vlanId(LABEL))
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p10.port())
+                        .setVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of p2p with the VLAN
+     * encapsulation and 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 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();
+
+    }
+
+}
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 e3b662a..87103aa 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
@@ -16,20 +16,16 @@
 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.IpPrefix;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
-import org.onosproject.TestApplicationId;
 import org.onosproject.cfg.ComponentConfigAdapter;
-import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
-import org.onosproject.core.IdGenerator;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultLink;
-import org.onosproject.net.DeviceId;
 import org.onosproject.net.FilteredConnectPoint;
 import org.onosproject.net.Link;
 import org.onosproject.net.PortNumber;
@@ -38,11 +34,13 @@
 import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.MplsCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+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.intent.MockIdGenerator;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -58,75 +56,15 @@
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.is;
+import static org.onlab.packet.EthType.EtherType.IPV4;
 import static org.onosproject.net.Link.Type.DIRECT;
 import static org.onosproject.net.NetTestTools.*;
+import static org.onosproject.net.flow.criteria.Criterion.Type.IN_PORT;
+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.*;
 
-public class LinkCollectionIntentCompilerTest {
-
-    private final ApplicationId appId = new TestApplicationId("test");
-
-    private final ConnectPoint d1p1 = connectPoint("s1", 1);
-    private final ConnectPoint d2p0 = connectPoint("s2", 0);
-    private final ConnectPoint d2p1 = connectPoint("s2", 1);
-    private final ConnectPoint d3p1 = connectPoint("s3", 1);
-    private final ConnectPoint d3p0 = connectPoint("s3", 10);
-    private final ConnectPoint d1p0 = connectPoint("s1", 10);
-
-    private final DeviceId of1Id = DeviceId.deviceId("of:of1");
-    private final DeviceId of2Id = DeviceId.deviceId("of:of2");
-    private final DeviceId of3Id = DeviceId.deviceId("of:of3");
-    private final DeviceId of4Id = DeviceId.deviceId("of:of4");
-
-    private final ConnectPoint of1p1 = connectPoint("of1", 1);
-    private final ConnectPoint of1p2 = connectPoint("of1", 2);
-    private final ConnectPoint of2p1 = connectPoint("of2", 1);
-    private final ConnectPoint of2p2 = connectPoint("of2", 2);
-    private final ConnectPoint of2p3 = connectPoint("of2", 3);
-    private final ConnectPoint of3p1 = connectPoint("of3", 1);
-    private final ConnectPoint of3p2 = connectPoint("of3", 2);
-    private final ConnectPoint of4p1 = connectPoint("of4", 1);
-    private final ConnectPoint of4p2 = connectPoint("of4", 2);
-
-    private final Set<Link> links = ImmutableSet.of(
-            DefaultLink.builder().providerId(PID).src(d1p1).dst(d2p0).type(DIRECT).build(),
-            DefaultLink.builder().providerId(PID).src(d2p1).dst(d3p1).type(DIRECT).build(),
-            DefaultLink.builder().providerId(PID).src(d1p1).dst(d3p1).type(DIRECT).build());
-
-    private final TrafficSelector selector = DefaultTrafficSelector.builder().build();
-    private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
-
-    private final TrafficSelector vlan100Selector = DefaultTrafficSelector.builder()
-            .matchVlanId(VlanId.vlanId("100"))
-            .build();
-
-    private final TrafficSelector vlan200Selector = DefaultTrafficSelector.builder()
-            .matchVlanId(VlanId.vlanId("200"))
-            .build();
-
-    private final TrafficSelector ipPrefixSelector = DefaultTrafficSelector.builder()
-            .matchIPDst(IpPrefix.valueOf("192.168.100.0/24"))
-            .build();
-
-    private final TrafficTreatment ethDstTreatment = DefaultTrafficTreatment.builder()
-            .setEthDst(MacAddress.valueOf("C0:FF:EE:C0:FF:EE"))
-            .build();
-
-    private CoreService coreService;
-    private IntentExtensionService intentExtensionService;
-    private IntentConfigurableRegistrator registrator;
-    private IdGenerator idGenerator = new MockIdGenerator();
-
-    private LinkCollectionIntent intent;
-
-    private LinkCollectionIntentCompiler sut;
-
-
-
-    private List<FlowRule> getFlowRulesByDevice(DeviceId deviceId, Collection<FlowRule> flowRules) {
-        return flowRules.stream()
-                .filter(fr -> fr.deviceId().equals(deviceId))
-                .collect(Collectors.toList());
-    }
+public class LinkCollectionIntentCompilerTest extends AbstractLinkCollectionTest {
 
     @Before
     public void setUp() {
@@ -181,7 +119,7 @@
 
         // if not found, get() raises an exception
         FlowRule rule1 = rules.stream()
-                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .filter(rule -> rule.deviceId().equals(d1p10.deviceId()))
                 .findFirst()
                 .get();
         assertThat(rule1.selector(), is(
@@ -226,7 +164,7 @@
      *             `-1 of4 2-
      */
     @Test
-    public void testFilteredConnectPoint1() {
+    public void testFilteredConnectPointForSp() {
         sut.activate();
         Set<Link> testLinks = ImmutableSet.of(
                 DefaultLink.builder().providerId(PID).src(of1p2).dst(of2p1).type(DIRECT).build(),
@@ -346,7 +284,7 @@
      * -1 of3 2---/
      */
     @Test
-    public void testFilteredConnectPoint2() {
+    public void testFilteredConnectPointForMp() {
         sut.activate();
         Set<Link> testlinks = ImmutableSet.of(
                 DefaultLink.builder().providerId(PID).src(of1p2).dst(of2p1).type(DIRECT).build(),
@@ -467,7 +405,7 @@
      *             `-1 of4 2-
      */
     @Test
-    public void nonTrivialTranslation1() {
+    public void nonTrivialTranslationForSp() {
         sut.activate();
         Set<Link> testLinks = ImmutableSet.of(
                 DefaultLink.builder().providerId(PID).src(of1p2).dst(of2p1).type(DIRECT).build(),
@@ -587,7 +525,7 @@
      * -1 of3 2---/
      */
     @Test
-    public void nonTrivialTranslation2() {
+    public void nonTrivialTranslationForMp() {
         sut.activate();
         Set<Link> testlinks = ImmutableSet.of(
                 DefaultLink.builder().providerId(PID).src(of1p2).dst(of2p1).type(DIRECT).build(),
@@ -701,4 +639,442 @@
 
         sut.deactivate();
     }
+
+    /**
+     * We test the proper compilation of mp2sp with
+     * trivial selector, trivial treatment and 1 hop.
+     */
+    @Test
+    public void singleHopTestForMp() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(treatment)
+                .links(ImmutableSet.of())
+                .filteredIngressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10),
+                        new FilteredConnectPoint(d1p11)
+                ))
+                .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p0)))
+                .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(2));
+
+        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.is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d1p10.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setOutput(d1p0.port())
+                        .build()
+        ));
+
+        ruleS1 = rulesS1.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d1p11.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS1.selector(), Is.is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d1p11.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setOutput(d1p0.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of sp2mp with
+     * trivial selector, trivial treatment and 1 hop.
+     */
+    @Test
+    public void singleHopTestForSp() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(treatment)
+                .applyTreatmentOnEgress(true)
+                .links(ImmutableSet.of())
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10),
+                        new FilteredConnectPoint(d1p11)
+                ))
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p0)))
+                .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(1));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(1));
+        FlowRule 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.is(
+                DefaultTrafficSelector
+                        .builder()
+                        .matchInPort(d1p0.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setOutput(d1p10.port())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of mp2sp with
+     * trivial selector, trivial treatment, filtered
+     * points and 1 hop.
+     */
+    @Test
+    public void singleHopTestFilteredForMp() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(treatment)
+                .links(ImmutableSet.of())
+                .filteredIngressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10, vlan100Selector),
+                        new FilteredConnectPoint(d1p11, mpls69Selector)
+                ))
+                .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p0, vlan200Selector)))
+                .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(2));
+
+        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.is(
+                DefaultTrafficSelector
+                        .builder(vlan100Selector)
+                        .matchInPort(d1p10.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d1p0.port())
+                        .build()
+        ));
+
+        ruleS1 = rulesS1.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d1p11.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS1.selector(), Is.is(
+                DefaultTrafficSelector
+                        .builder(mpls69Selector)
+                        .matchInPort(d1p11.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .popMpls(IPV4.ethType())
+                        .pushVlan()
+                        .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d1p0.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of sp2mp with
+     * trivial selector, trivial treatment and 1 hop.
+     */
+    @Test
+    public void singleHopTestFilteredForSp() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(treatment)
+                .applyTreatmentOnEgress(true)
+                .links(ImmutableSet.of())
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10, vlan100Selector),
+                        new FilteredConnectPoint(d1p11, mpls80Selector)
+                ))
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p0, vlan200Selector)))
+                .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(1));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(1));
+        FlowRule 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.is(
+                DefaultTrafficSelector
+                        .builder(vlan200Selector)
+                        .matchInPort(d1p0.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d1p10.port())
+                        .popVlan()
+                        .pushMpls()
+                        .setMpls(((MplsCriterion) mpls80Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of mp2sp with
+     * selector, treatment, filtered
+     * points and 1 hop.
+     */
+    @Test
+    public void singleHopNonTrivialForMp() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(ipPrefixSelector)
+                .treatment(ethDstTreatment)
+                .links(ImmutableSet.of())
+                .filteredIngressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10, vlan100Selector),
+                        new FilteredConnectPoint(d1p11, mpls100Selector)
+                ))
+                .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p0, vlan200Selector)))
+                .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(2));
+
+        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.is(
+                DefaultTrafficSelector
+                        .builder(ipPrefixSelector)
+                        .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+                        .matchInPort(d1p10.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                .allInstructions()
+                                .stream()
+                                .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                .findFirst().get()).mac())
+                        .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d1p0.port())
+                        .build()
+        ));
+
+        ruleS1 = rulesS1.stream()
+                .filter(rule -> {
+                    PortCriterion inPort = (PortCriterion) rule.selector().getCriterion(IN_PORT);
+                    return inPort.port().equals(d1p11.port());
+                })
+                .findFirst()
+                .get();
+        assertThat(ruleS1.selector(), Is.is(
+                DefaultTrafficSelector
+                        .builder(ipPrefixSelector)
+                        .matchMplsLabel(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+                        .matchInPort(d1p11.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .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(d1p0.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of sp2mp with
+     * selector, treatment and 1 hop.
+     */
+    @Test
+    public void singleHopNonTrivialForSp() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(ipPrefixSelector)
+                .treatment(ethDstTreatment)
+                .applyTreatmentOnEgress(true)
+                .links(ImmutableSet.of())
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10, vlan100Selector),
+                        new FilteredConnectPoint(d1p11, mpls200Selector)
+                ))
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p0, vlan200Selector)))
+                .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(1));
+
+        Collection<FlowRule> rulesS1 = rules.stream()
+                .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
+                .collect(Collectors.toSet());
+        assertThat(rulesS1, hasSize(1));
+        FlowRule 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.is(
+                DefaultTrafficSelector
+                        .builder(ipPrefixSelector)
+                        .matchVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+                        .matchInPort(d1p0.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), Is.is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                .allInstructions()
+                                .stream()
+                                .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                .findFirst().get()).mac())
+                        .setVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d1p10.port())
+                        .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()
+        ));
+
+        sut.deactivate();
+
+    }
+
 }
