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 842c86d..d6227a7 100644
--- a/core/api/src/test/java/org/onosproject/net/NetTestTools.java
+++ b/core/api/src/test/java/org/onosproject/net/NetTestTools.java
@@ -258,4 +258,17 @@
         );
     }
 
+    /**
+     * Builds a treatment which contains the dec ttl
+     * actions.
+     *
+     * @return the treatment
+     */
+    public static TrafficTreatment decTtlTreatment() {
+        return DefaultTrafficTreatment.builder()
+                .decMplsTtl()
+                .decNwTtl()
+                .build();
+    }
+
 }
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 38be5e4..40f7f77 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
@@ -67,6 +67,18 @@
             label = "Defines the label selection algorithm - RANDOM or FIRST_FIT")
     private String labelSelection = DEFAULT_LABEL_SELECTION;
 
+    private static final boolean DEFAULT_FLOW_OPTIMIZATION = false;
+    @Property(name = "useFlowOptimization",
+            boolValue = DEFAULT_FLOW_OPTIMIZATION,
+            label = "Indicates whether or not to optimize the flows in the link collection compiler")
+    private boolean useFlowOptimization = DEFAULT_FLOW_OPTIMIZATION;
+
+    private static final boolean DEFAULT_COPY_TTL = false;
+    @Property(name = "useCopyTtl",
+            boolValue = DEFAULT_COPY_TTL,
+            label = "Indicates whether or not to use copy ttl in the link collection compiler")
+    private boolean useCopyTtl = DEFAULT_COPY_TTL;
+
     private final Map<Class<Intent>, IntentCompiler<Intent>> flowRuleBased = Maps.newConcurrentMap();
     private final Map<Class<Intent>, IntentCompiler<Intent>> flowObjectiveBased = Maps.newConcurrentMap();
 
@@ -87,6 +99,8 @@
         if (context == null) {
             log.info("Settings: useFlowObjectives={}", useFlowObjectives);
             log.info("Settings: labelSelection={}", labelSelection);
+            log.info("Settings: useFlowOptimization={}", useFlowOptimization);
+            log.info("Settings: useCopyTtl={}", useCopyTtl);
             return;
         }
 
@@ -117,6 +131,34 @@
             changeLabelSelections();
             log.info("Settings: labelSelection={}", labelSelection);
         }
+
+        boolean newFlowOptimization;
+        try {
+            String s = Tools.get(context.getProperties(), "useFlowOptimization");
+            newFlowOptimization = isNullOrEmpty(s) ? useFlowOptimization : Boolean.parseBoolean(s.trim());
+        } catch (ClassCastException e) {
+            newFlowOptimization = useFlowOptimization;
+        }
+
+        if (useFlowOptimization != newFlowOptimization) {
+            useFlowOptimization = newFlowOptimization;
+            changeFlowOptimization();
+            log.info("Settings: useFlowOptimization={}", useFlowOptimization);
+        }
+
+        boolean newCopyTtl;
+        try {
+            String s = Tools.get(context.getProperties(), "useCopyTtl");
+            newCopyTtl = isNullOrEmpty(s) ? useCopyTtl : Boolean.parseBoolean(s.trim());
+        } catch (ClassCastException e) {
+            newCopyTtl = useCopyTtl;
+        }
+
+        if (useCopyTtl != newCopyTtl) {
+            useCopyTtl = newCopyTtl;
+            changeCopyTtl();
+            log.info("Settings: useCopyTtl={}", useCopyTtl);
+        }
     }
 
     /**
@@ -173,4 +215,12 @@
         LinkCollectionCompiler.labelAllocator.setLabelSelection(labelSelection);
     }
 
+    private void changeFlowOptimization() {
+        LinkCollectionCompiler.optimize = useFlowOptimization;
+    }
+
+    private void changeCopyTtl() {
+        LinkCollectionCompiler.copyTtl = useCopyTtl;
+    }
+
 }
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 d5df116..2176a20 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,6 +16,7 @@
 
 package org.onosproject.net.intent.impl.compiler;
 
+import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.SetMultimap;
 import com.google.common.collect.Sets;
@@ -29,9 +30,9 @@
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.FilteredConnectPoint;
 import org.onosproject.net.Link;
 import org.onosproject.net.PortNumber;
-import org.onosproject.net.FilteredConnectPoint;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
@@ -47,17 +48,17 @@
 import org.onosproject.net.flow.instructions.L1ModificationInstruction;
 import org.onosproject.net.flow.instructions.L2ModificationInstruction;
 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsBosInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
-import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
-import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsBosInstruction;
-import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
 import org.onosproject.net.flow.instructions.L3ModificationInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpEthInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpIPInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpOpInstruction;
 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
-import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpIPInstruction;
-import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpEthInstruction;
-import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpOpInstruction;
 import org.onosproject.net.flow.instructions.L4ModificationInstruction;
 import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction;
 import org.onosproject.net.intent.IntentCompilationException;
@@ -69,10 +70,9 @@
 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;
+import static org.onosproject.net.flow.criteria.Criterion.Type.*;
 
 /**
  * Shared APIs and implementations for Link Collection compilers.
@@ -85,6 +85,18 @@
     static LabelAllocator labelAllocator;
 
     /**
+     * Influence compiler behavior. If true the compiler
+     * try to optimize the chain of the actions.
+     */
+    static boolean optimize;
+
+    /**
+     * Influence compiler behavior. If true the compiler
+     * try to optimize the copy ttl actions.
+     */
+    static boolean copyTtl;
+
+    /**
      * The allowed tag criterions.
      */
     private static final Set<Criterion.Type> TAG_CRITERION_TYPES =
@@ -248,6 +260,151 @@
     }
 
     /**
+     * Helper method to generate the egress actions.
+     *
+     * @param treatmentBuilder the treatment builder to update
+     * @param egressPoints the egress points
+     * @param initialState the initial state of the transition
+     */
+    private void generateEgressActions(TrafficTreatment.Builder treatmentBuilder,
+                                       List<FilteredConnectPoint> egressPoints,
+                                       TrafficSelector initialState,
+                                       LinkCollectionIntent intent) {
+
+        TrafficSelector prevState = initialState;
+        for (FilteredConnectPoint egressPoint : egressPoints) {
+            /*
+             * If we are at the egress, we have to transit to the final
+             * state. First 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(prevState,
+                                        egressPoint.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(egressPoint.connectPoint().port());
+            if (optimize) {
+                /*
+                 * We update the previous state. In this way instead of
+                 * transiting from FIP->FEP we do FEP->FEP and so on.
+                 */
+                prevState = egressPoint.trafficSelector();
+            }
+        }
+
+    }
+
+    /**
+     * Helper method to order the egress ports according to a
+     * specified criteria. The idea is to generate first the actions
+     * for the egress ports which are similar to the specified criteria
+     * then the others. In this way we can mitigate the problems related
+     * to the chain of actions and we can optimize also the number of
+     * actions.
+     *
+     * @param orderCriteria the ordering criteria
+     * @param pointsToOrder the egress points to order
+     * @return a list of port ordered
+     */
+    private List<FilteredConnectPoint> orderedEgressPoints(TrafficSelector orderCriteria,
+                                        List<FilteredConnectPoint> pointsToOrder) {
+        /*
+         * We are interested only to the labels. The idea is to order
+         * by the tags.
+         *
+         */
+        Criterion vlanIdCriterion = orderCriteria.getCriterion(VLAN_VID);
+        Criterion mplsLabelCriterion = orderCriteria.getCriterion(MPLS_LABEL);
+        /*
+         * We collect all the untagged points.
+         *
+         */
+        List<FilteredConnectPoint> untaggedEgressPoints = pointsToOrder
+                .stream()
+                .filter(pointToOrder -> {
+                    TrafficSelector selector = pointToOrder.trafficSelector();
+                    return selector.getCriterion(VLAN_VID) == null &&
+                            selector.getCriterion(MPLS_LABEL) == null;
+                }).collect(Collectors.toList());
+        /*
+         * We collect all the vlan points.
+         */
+        List<FilteredConnectPoint> vlanEgressPoints = pointsToOrder
+                .stream()
+                .filter(pointToOrder -> {
+                    TrafficSelector selector = pointToOrder.trafficSelector();
+                    return selector.getCriterion(VLAN_VID) != null &&
+                            selector.getCriterion(MPLS_LABEL) == null;
+                }).collect(Collectors.toList());
+        /*
+         * We collect all the mpls points.
+         */
+        List<FilteredConnectPoint> mplsEgressPoints = pointsToOrder
+                .stream()
+                .filter(pointToOrder -> {
+                    TrafficSelector selector = pointToOrder.trafficSelector();
+                    return selector.getCriterion(VLAN_VID) == null &&
+                            selector.getCriterion(MPLS_LABEL) != null;
+                }).collect(Collectors.toList());
+        /*
+         * We create the final list of ports.
+         */
+        List<FilteredConnectPoint> orderedList = Lists.newArrayList();
+        /*
+         * The ordering criteria is vlan id. First we add the vlan
+         * ports. Then the others.
+         */
+        if (vlanIdCriterion != null && mplsLabelCriterion == null) {
+            orderedList.addAll(vlanEgressPoints);
+            orderedList.addAll(untaggedEgressPoints);
+            orderedList.addAll(mplsEgressPoints);
+            return orderedList;
+        }
+        /*
+         * The ordering criteria is mpls label. First we add the mpls
+         * ports. Then the others.
+         */
+        if (vlanIdCriterion == null && mplsLabelCriterion != null) {
+            orderedList.addAll(mplsEgressPoints);
+            orderedList.addAll(untaggedEgressPoints);
+            orderedList.addAll(vlanEgressPoints);
+            return orderedList;
+        }
+        /*
+         * The ordering criteria is untagged. First we add the untagged
+         * ports. Then the others.
+         */
+        if (vlanIdCriterion == null && mplsLabelCriterion == null) {
+            orderedList.addAll(untaggedEgressPoints);
+            orderedList.addAll(vlanEgressPoints);
+            orderedList.addAll(mplsEgressPoints);
+            return orderedList;
+        }
+        /*
+         * Unhandled scenario.
+         */
+        orderedList.addAll(vlanEgressPoints);
+        orderedList.addAll(mplsEgressPoints);
+        orderedList.addAll(untaggedEgressPoints);
+        return orderedList;
+    }
+
+    /**
      * Manages the Intents with a single ingress point (p2p, sp2mp)
      * creating properly the selector builder and the treatment builder.
      *
@@ -285,42 +442,32 @@
                 .forEach(selectorBuilder::add);
         /*
          * In this scenario, potentially we can have several output
-         * ports.
+         * ports. First we have to insert in the treatment the actions
+         * for the core.
          */
+        List<FilteredConnectPoint> egressPoints = Lists.newArrayList();
         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);
+            if (!filteredEgressPoint.isPresent()) {
+                treatmentBuilder.setOutput(outPort);
+            } else {
+                egressPoints.add(filteredEgressPoint.get());
             }
-            /*
-             * Finally we set the output action.
-             */
-            treatmentBuilder.setOutput(outPort);
         }
+        /*
+         * The idea is to order the egress points. Before we deal
+         * with the egress points which looks like similar to the ingress
+         * point then the others.
+         */
+        TrafficSelector prevState = filteredIngressPoint.get().trafficSelector();
+        if (optimize) {
+            egressPoints = orderedEgressPoints(prevState, egressPoints);
+        }
+        /*
+         * Then we deal with the egress points.
+         */
+        generateEgressActions(treatmentBuilder, egressPoints, prevState, intent);
     }
 
     /**
@@ -605,9 +752,11 @@
         );
         /*
          * We need to order the actions. First the actions
-         * related to the not-egress points.
+         * related to the not-egress points. At the same time we collect
+         * also the egress points.
          */
-        outPorts.forEach(outPort -> {
+        List<FilteredConnectPoint> egressPoints = Lists.newArrayList();
+        for (PortNumber outPort : outPorts) {
             Optional<FilteredConnectPoint> filteredEgressPoint =
                     getFilteredConnectPointFromIntent(deviceId, outPort, intent);
             if (!filteredEgressPoint.isPresent()) {
@@ -651,45 +800,25 @@
                  * Finally we set the output action.
                  */
                 treatmentBuilder.setOutput(outPort);
+            } else {
+                egressPoints.add(filteredEgressPoint.get());
             }
-
-        });
+        }
+        /*
+         * The idea is to order the egress points. Before we deal
+         * with the egress points which looks like similar to the
+         * selector derived from the encpsulation constraint then
+         * the others.
+         */
+        TrafficSelector prevState = selectorBuilder.build();
+        if (optimize) {
+            egressPoints = orderedEgressPoints(prevState, egressPoints);
+        }
         /*
          * In this case, we have to transit to the final
          * state.
          */
-        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);
-            }
-        });
-
+        generateEgressActions(treatmentBuilder, egressPoints, prevState, intent);
     }
 
     /**
@@ -891,6 +1020,9 @@
                     break;
 
                 case MPLS_LABEL:
+                    if (copyTtl) {
+                        builder.copyTtlIn();
+                    }
                     builder.popMpls(ethType);
                     break;
 
@@ -909,6 +1041,9 @@
 
                 case MPLS_LABEL:
                     builder.pushMpls();
+                    if (copyTtl) {
+                        builder.copyTtlOut();
+                    }
                     break;
 
                 default:
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 e464e99..d93764b 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
@@ -30,9 +30,16 @@
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction;
 import org.onosproject.net.intent.FlowRuleIntent;
 import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentCompilationException;
 import org.onosproject.net.intent.IntentCompiler;
 import org.onosproject.net.intent.LinkCollectionIntent;
 import org.onosproject.net.intent.constraint.EncapsulationConstraint;
@@ -48,6 +55,8 @@
 import java.util.Optional;
 import java.util.Set;
 
+import static org.onosproject.net.flow.instructions.Instruction.Type.NOACTION;
+
 /**
  * Compiler to produce flow rules from link collections.
  */
@@ -56,6 +65,9 @@
         extends LinkCollectionCompiler<FlowRule>
         implements IntentCompiler<LinkCollectionIntent> {
 
+    private static final String UNKNOWN_INSTRUCTION = "Unknown instruction type";
+    private static final String UNSUPPORTED_INSTRUCTION = "Unsupported %s instruction";
+
     private static Logger log = LoggerFactory.getLogger(LinkCollectionIntentCompiler.class);
 
 
@@ -138,6 +150,11 @@
                         labels
                 );
 
+                if (optimize) {
+                    TrafficTreatment compactedTreatment = compactActions(instructions.treatment());
+                    instructions = new ForwardingInstructions(compactedTreatment, instructions.selector());
+                }
+
                 FlowRule rule = DefaultFlowRule.builder()
                         .forDevice(deviceId)
                         .withSelector(instructions.selector())
@@ -152,4 +169,204 @@
 
         return rules;
     }
+
+    /**
+     * This method tries to optimize the chain of actions.
+     *
+     * @param oldTreatment the list of instructions to optimize
+     * @return the optimized set of actions
+     */
+    private TrafficTreatment compactActions(TrafficTreatment oldTreatment) {
+
+        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+        Instruction instruction;
+        Instruction newInstruction;
+
+        for (int index = 0; index < oldTreatment.allInstructions().size(); index++) {
+            instruction = oldTreatment.allInstructions().get(index);
+            /*
+             * if the action is not optimizable. We simply add
+             * to the builder.
+             */
+            if (checkInstruction(instruction)) {
+                treatmentBuilder.add(instruction);
+                continue;
+            }
+            /*
+             * We try to run an optimization;
+             */
+            newInstruction = optimizeInstruction(index, instruction, oldTreatment.allInstructions());
+            if (!newInstruction.type().equals(NOACTION)) {
+                treatmentBuilder.add(newInstruction);
+            }
+        }
+
+        return treatmentBuilder.build();
+    }
+
+    /**
+     * Verifies if the given L2 instruction can be optimized.
+     *
+     * @param l2instruction the l2 instruction to verify
+     * @return true if the instruction cannot be optimized. False otherwise
+     */
+    private boolean checkL2Instructions(L2ModificationInstruction l2instruction) {
+        switch (l2instruction.subtype()) {
+            /*
+             * These actions can be performed safely.
+             */
+            case ETH_SRC:
+            case ETH_DST:
+            case VLAN_ID:
+            case VLAN_PCP:
+            case MPLS_LABEL:
+            case MPLS_BOS:
+            case TUNNEL_ID:
+            case VLAN_PUSH:
+            case VLAN_POP:
+            case MPLS_PUSH:
+            case MPLS_POP:
+                return true;
+            /*
+             * We should avoid dec mpls ttl multiple
+             * times.
+             */
+            case DEC_MPLS_TTL:
+                return false;
+
+            default:
+                throw new IntentCompilationException(String.format(UNSUPPORTED_INSTRUCTION, "L2"));
+        }
+
+    }
+
+    /**
+     * Verifies if the given L3 instruction can be optimized.
+     *
+     * @param l3instruction the l3 instruction to verify
+     * @return true if the instruction cannot be optimized. False otherwise
+     */
+    private boolean checkL3Instructions(L3ModificationInstruction l3instruction) {
+        switch (l3instruction.subtype()) {
+            /*
+             * These actions can be performed several times.
+             */
+            case IPV4_SRC:
+            case IPV4_DST:
+            case IPV6_SRC:
+            case IPV6_DST:
+            case IPV6_FLABEL:
+            case ARP_SPA:
+            case ARP_SHA:
+            case ARP_OP:
+            case TTL_OUT:
+            case TTL_IN:
+                return true;
+            /*
+             * This action should be executed one time;
+             */
+            case DEC_TTL:
+                return false;
+            default:
+                throw new IntentCompilationException(String.format(UNSUPPORTED_INSTRUCTION, "L3"));
+        }
+    }
+
+    /**
+     * Helper method to handle the optimization of the ttl instructions.
+     *
+     * @param index the index of the instruction
+     * @param instruction the instruction to optimize
+     * @param instructions the list of instructions to optimize
+     * @return no action if the action can be removed. The same instruction
+     *         if we have to perform it
+     */
+    private Instruction optimizeTtlInstructions(int index, Instruction instruction, List<Instruction> instructions) {
+        /**
+         * Here we handle the optimization of decrement mpls ttl. The optimization
+         * is to come back to the start of the list looking for the same
+         * action. If we find the same action, we can optimize.
+         */
+        Instruction currentInstruction;
+        for (int i = index - 1; i >= 0; i--) {
+            currentInstruction = instructions.get(i);
+            if (currentInstruction.equals(instruction)) {
+                return Instructions.createNoAction();
+
+            }
+        }
+        return instruction;
+    }
+
+    /**
+     * Helper method to handle the optimization of the instructions.
+     *
+     * @param index the index of the instruction
+     * @param instruction the instruction to optimize
+     * @param instructions the list of instructions to optimize
+     * @return no action if the action can be removed. The same instruction
+     *         if we have to perform it
+     */
+    private Instruction optimizeInstruction(int index, Instruction instruction, List<Instruction> instructions) {
+
+        switch (instruction.type()) {
+            /*
+             * Here we have the chance to optimize the dec mpls ttl action.
+             */
+            case L2MODIFICATION:
+            /*
+             * Here we have the chance to optimize the ttl related actions.
+             */
+            case L3MODIFICATION:
+                return optimizeTtlInstructions(index, instruction, instructions);
+
+            default:
+                throw new IntentCompilationException(UNKNOWN_INSTRUCTION);
+
+        }
+
+    }
+
+    /**
+     * Helper method to verify if the instruction can be optimized.
+     *
+     * @param instruction the instruction to verify
+     * @return true if the action can be optimized. False otherwise.
+     */
+    private boolean checkInstruction(Instruction instruction) {
+
+        switch (instruction.type()) {
+            /*
+             * The following instructions are not supported.
+             */
+            case L0MODIFICATION:
+            case L1MODIFICATION:
+            case L4MODIFICATION:
+            case NOACTION:
+            case OUTPUT:
+            case GROUP:
+            case QUEUE:
+            case TABLE:
+            case METER:
+            case METADATA:
+            case EXTENSION:
+                return true;
+            /*
+             * Here we have the chance to optimize actions like dec mpls ttl.
+             */
+            case L2MODIFICATION:
+                return checkL2Instructions((L2ModificationInstruction) instruction);
+            /*
+             * Here we have the chance to optimize the ttl related actions.
+             */
+            case L3MODIFICATION:
+                return checkL3Instructions((L3ModificationInstruction) instruction);
+
+            default:
+                throw new IntentCompilationException(UNKNOWN_INSTRUCTION);
+
+        }
+
+    }
+
 }
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java
index 9a8324c..f7389e7 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java
@@ -53,7 +53,7 @@
 
     final ConnectPoint d2p0 = connectPoint("s2", 0);
     final ConnectPoint d2p1 = connectPoint("s2", 1);
-    ConnectPoint d2p10 = connectPoint("s2", 10);
+    final ConnectPoint d2p10 = connectPoint("s2", 10);
 
     final ConnectPoint d3p0 = connectPoint("s3", 0);
     final ConnectPoint d3p1 = connectPoint("s3", 1);
@@ -78,6 +78,7 @@
     final ConnectPoint d1p1 = connectPoint("s1", 1);
     final ConnectPoint d1p10 = connectPoint("s1", 10);
     final ConnectPoint d1p11 = connectPoint("s1", 11);
+    final ConnectPoint d1p12 = connectPoint("s1", 12);
 
     final Set<Link> links = ImmutableSet.of(
             link(d1p1, d2p0),
@@ -98,6 +99,8 @@
     );
 
     final TrafficTreatment treatment = emptyTreatment();
+    final TrafficTreatment ethDstTreatment = macDstTreatment("C0:FF:EE:C0:FF:EE");
+    final TrafficTreatment decTllTreatment = decTtlTreatment();
 
     final TrafficSelector selector = emptySelector();
     final TrafficSelector vlan69Selector = vlanSelector("69");
@@ -109,7 +112,6 @@
     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();
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionEncapIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionEncapIntentCompilerTest.java
index 588880a..295a998 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionEncapIntentCompilerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionEncapIntentCompilerTest.java
@@ -82,6 +82,9 @@
         sut.registrator = registrator;
         sut.resourceService = new MockResourceService();
 
+        LinkCollectionCompiler.optimize = false;
+        LinkCollectionCompiler.copyTtl = false;
+
         replay(coreService, intentExtensionService);
     }
 
@@ -290,7 +293,7 @@
                 DefaultTrafficTreatment
                         .builder()
                         .pushMpls()
-                        .setMpls(MplsLabel.mplsLabel((LABEL)))
+                        .setMpls(MplsLabel.mplsLabel(LABEL))
                         .setOutput(d3p0.port())
                         .build()
         ));
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 87103aa..cfbddea 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
@@ -96,8 +96,10 @@
 
         sut.registrator = registrator;
 
-        replay(coreService, intentExtensionService);
+        LinkCollectionCompiler.optimize = false;
+        LinkCollectionCompiler.copyTtl = false;
 
+        replay(coreService, intentExtensionService);
 
     }
 
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionOptimizationTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionOptimizationTest.java
new file mode 100644
index 0000000..4b58fba
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionOptimizationTest.java
@@ -0,0 +1,1060 @@
+/*
+ * 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.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.*;
+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 LinkCollectionOptimizationTest 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();
+
+        /*
+         * We activate the optimizations.
+         */
+        LinkCollectionCompiler.optimize = true;
+        LinkCollectionCompiler.copyTtl = true;
+
+        replay(coreService, intentExtensionService);
+    }
+
+    @After
+    public void tearDown() {
+        Intent.unbindIdGenerator(idGenerator);
+    }
+
+    /**
+     * We test the proper optimization of sp2mp with dec tll
+     * and dec mpls ttl.
+     */
+    @Test
+    public void testDecTtlOptimization() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(decTllTreatment)
+                .links(linksForSp2Mp)
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10)))
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10),
+                        new FilteredConnectPoint(d1p11),
+                        new FilteredConnectPoint(d2p10)
+                ))
+                .applyTreatmentOnEgress(true)
+                .build();
+
+        sut.activate();
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> 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()
+                        .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())
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setOutput(d2p0.port())
+                        .decMplsTtl()
+                        .decNwTtl()
+                        .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())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .decMplsTtl()
+                        .decNwTtl()
+                        .setOutput(d1p10.port())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper optimization of sp2mp with VLAN
+     * ingress point and different egress points: 1) it is
+     * a simple ingress point; 2) it is a vlan ingress point;
+     * 3) It is a simple ingress point. 1) and 2) share the same
+     * egress switch. The outcomes of the test are the re-ordering
+     * of the actions and the proper optimization of the chain.
+     */
+    @Test
+    public void testVlanOrder() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(treatment)
+                .links(linksForSp2Mp)
+                .applyTreatmentOnEgress(true)
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, vlan100Selector)))
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10),
+                        new FilteredConnectPoint(d1p11, vlan200Selector),
+                        new FilteredConnectPoint(d2p10)
+                ))
+                .build();
+
+        sut.activate();
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> 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(vlan100Selector)
+                        .matchInPort(d3p10.port())
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .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(vlan100Selector)
+                        .matchInPort(d2p1.port())
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setOutput(d2p0.port())
+                        .popVlan()
+                        .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(vlan100Selector)
+                        .matchInPort(d1p0.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d1p11.port())
+                        .popVlan()
+                        .setOutput(d1p10.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper optimization of sp2mp with MPLS
+     * ingress point and different egress points: 1) it is
+     * a vlan ingress point; 2) it is a mpls ingress point;
+     * 3) It is a simple ingress point. 1) and 2) share the same
+     * egress switch. The outcomes of the test are the re-ordering
+     * of the actions and the proper optimization of the chain.
+     */
+    @Test
+    public void testMplsOrder() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(treatment)
+                .links(linksForSp2Mp)
+                .applyTreatmentOnEgress(true)
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls100Selector)))
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10, vlan100Selector),
+                        new FilteredConnectPoint(d1p11, mpls200Selector),
+                        new FilteredConnectPoint(d2p10)
+                ))
+                .build();
+
+        sut.activate();
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> 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(mpls100Selector)
+                        .matchInPort(d3p10.port())
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .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(mpls100Selector)
+                        .matchInPort(d2p1.port())
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setOutput(d2p0.port())
+                        .copyTtlIn()
+                        .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(mpls100Selector)
+                        .matchInPort(d1p0.port())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p11.port())
+                        .copyTtlIn()
+                        .popMpls(IPV4.ethType())
+                        .pushVlan()
+                        .setVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d1p10.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper optimization of sp2mp with untagged
+     * ingress point and different egress points: 1) it is
+     * a vlan ingress point; 2) it is a mpls ingress point;
+     * 3) It is a simple ingress point. 1) and 2) share the same
+     * egress switch. The outcomes of the test are the re-ordering
+     * of the actions and the proper optimization of the chain.
+     */
+    @Test
+    public void testUntaggedOrder() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(treatment)
+                .links(linksForSp2Mp)
+                .applyTreatmentOnEgress(true)
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10)))
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10, vlan100Selector),
+                        new FilteredConnectPoint(d1p11, mpls200Selector),
+                        new FilteredConnectPoint(d1p12),
+                        new FilteredConnectPoint(d2p10)
+                ))
+                .build();
+
+        sut.activate();
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> 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()
+                        .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())
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setOutput(d2p0.port())
+                        .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())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setOutput(d1p12.port())
+                        .pushVlan()
+                        .setVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d1p10.port())
+                        .popVlan()
+                        .pushMpls()
+                        .copyTtlOut()
+                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper optimization of sp2mp with VLAN ingress point,
+     * simple egress point, non trivial intent treatment and non trivial
+     * intent selector. The outcomes of the test are the proper optimization
+     * of the actions. It is expected that the actions related to the intent
+     * treatment and intent selector are not optimized. The optimization is
+     * performed only on the dec ttl actions and on the actions which create
+     * traffic slices. The rationale is that in the intent treatment we expect
+     * actions like set something so it is fine to perform them several times.
+     */
+    @Test
+    public void testPoPVlanOptimization() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(ipPrefixSelector)
+                .treatment(ethDstTreatment)
+                .links(linksForSp2Mp)
+                .applyTreatmentOnEgress(true)
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, vlan100Selector)))
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10),
+                        new FilteredConnectPoint(d1p11),
+                        new FilteredConnectPoint(d1p12),
+                        new FilteredConnectPoint(d2p10)
+                ))
+                .build();
+
+        sut.activate();
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> 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)
+                        .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+                        .matchInPort(d3p10.port())
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .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(ipPrefixSelector)
+                        .matchInPort(d2p1.port())
+                        .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+                        .build()
+        ));
+        assertThat(ruleS2.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setOutput(d2p0.port())
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                .allInstructions()
+                                .stream()
+                                .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                .findFirst().get()).mac())
+                        .popVlan()
+                        .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(ipPrefixSelector)
+                        .matchInPort(d1p0.port())
+                        .matchVlanId(((VlanIdCriterion) vlan100Selector.getCriterion(VLAN_VID)).vlanId())
+                        .build()
+        ));
+        assertThat(ruleS1.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                .allInstructions()
+                                .stream()
+                                .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                .findFirst().get()).mac())
+                        .popVlan()
+                        .setOutput(d1p12.port())
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                .allInstructions()
+                                .stream()
+                                .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                .findFirst().get()).mac())
+                        .setOutput(d1p10.port())
+                        .setEthDst(((ModEtherInstruction) ethDstTreatment
+                                .allInstructions()
+                                .stream()
+                                .filter(instruction -> instruction instanceof ModEtherInstruction)
+                                .findFirst().get()).mac())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper optimization of sp2mp with the VLAN
+     * encapsulation and trivial selector.
+     */
+    @Test
+    public void testOptimizationMplsEncapTrivialSelectors() {
+
+        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()
+                        .copyTtlOut()
+                        .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())
+                        .copyTtlIn()
+                        .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()
+                        .copyTtlIn()
+                        .popMpls(IPV4.ethType())
+                        .setOutput(d1p10.port())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper optimization of sp2mp with the VLAN
+     * encapsulation, filtered selectors.
+     */
+    @Test
+    public void testOptimizationVlanEncapMplsSelectors() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(treatment)
+                .constraints(constraintsForVlan)
+                .links(linksForSp2Mp)
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, mpls80Selector)))
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10, mpls100Selector),
+                        new FilteredConnectPoint(d1p11, mpls200Selector),
+                        new FilteredConnectPoint(d2p10, mpls69Selector)
+                ))
+                .build();
+
+        sut.activate();
+        /*
+         * We use the FIRST_FIT to simplify tests.
+         */
+        LinkCollectionCompiler.labelAllocator.setLabelSelection(LABEL_SELECTION);
+
+        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
+        assertThat(compiled, hasSize(1));
+
+        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
+        assertThat(rules, hasSize(3));
+
+        Collection<FlowRule> 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(mpls80Selector)
+                        .matchInPort(d3p10.port())
+                        .build()
+        ));
+        assertThat(ruleS3.treatment(), is(
+                DefaultTrafficTreatment
+                        .builder()
+                        .copyTtlIn()
+                        .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()
+                        .copyTtlOut()
+                        .setMpls(((MplsCriterion) mpls69Selector.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()
+                        .copyTtlOut()
+                        .setMpls(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p10.port())
+                        .setMpls(((MplsCriterion) mpls200Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper optimization of sp2mp with the MPLS
+     * encapsulation, filtered selectors, intent selector, and
+     * intent treatment.
+     */
+    @Test
+    public void testOptimizationMplsEncapNonTrivial() {
+
+        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()
+                        .copyTtlOut()
+                        .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())
+                        .copyTtlIn()
+                        .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())
+                        .copyTtlIn()
+                        .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())
+                        .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d1p11.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+    /**
+     * We test the proper compilation of sp2mp with the VLAN
+     * encapsulation and filtered selectors of different type.
+     */
+    @Test
+    public void testOptimizationVlanEncapDifferentSelectors() {
+
+        intent = LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .selector(selector)
+                .treatment(treatment)
+                .constraints(constraintsForVlan)
+                .links(linksForSp2Mp)
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p10, vlan69Selector)))
+                .filteredEgressPoints(ImmutableSet.of(
+                        new FilteredConnectPoint(d1p10, mpls100Selector),
+                        new FilteredConnectPoint(d1p11, vlan200Selector),
+                        new FilteredConnectPoint(d1p12),
+                        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(vlan69Selector)
+                        .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()
+                        .copyTtlOut()
+                        .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()
+                        .setVlanId(((VlanIdCriterion) vlan200Selector.getCriterion(VLAN_VID)).vlanId())
+                        .setOutput(d1p11.port())
+                        .popVlan()
+                        .setOutput(d1p12.port())
+                        .pushMpls()
+                        .copyTtlOut()
+                        .setMpls(((MplsCriterion) mpls100Selector.getCriterion(MPLS_LABEL)).label())
+                        .setOutput(d1p10.port())
+                        .build()
+        ));
+
+        sut.deactivate();
+
+    }
+
+}
