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 e873fa8..d1b44ca 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
@@ -69,6 +69,12 @@
             label = "Defines the label selection algorithm - RANDOM or FIRST_FIT")
     private String labelSelection = DEFAULT_LABEL_SELECTION;
 
+    private static final String DEFAULT_OPT_LABEL_SELECTION = "NONE";
+    @Property(name = "optLabelSelection",
+            value = DEFAULT_OPT_LABEL_SELECTION,
+            label = "Defines the optimization for label selection algorithm - NONE, NO_SWAP, MIN_SWAP")
+    private String optLabelSelection = DEFAULT_OPT_LABEL_SELECTION;
+
     private static final boolean DEFAULT_FLOW_OPTIMIZATION = false;
     @Property(name = "optimizeInstructions",
             boolValue = DEFAULT_FLOW_OPTIMIZATION,
@@ -117,6 +123,7 @@
             log.info("Settings: labelSelection={}", labelSelection);
             log.info("Settings: useFlowOptimization={}", optimizeInstructions);
             log.info("Settings: useCopyTtl={}", useCopyTtl);
+            log.info("Settings: optLabelSelection={}", optLabelSelection);
 
             // FIXME: temporary code for switching old compiler to new compiler
             log.info("Settings: defaultFlowObjectiveCompiler={}", defaultFlowObjectiveCompiler);
@@ -160,12 +167,28 @@
             newLabelSelection = labelSelection;
         }
 
-        if (!labelSelection.equals(newLabelSelection) && LabelAllocator.isInEnum(newLabelSelection)) {
+        if (!labelSelection.equals(newLabelSelection) && LabelAllocator.isInSelEnum(newLabelSelection)) {
             labelSelection = newLabelSelection;
             changeLabelSelections();
             log.info("Settings: labelSelection={}", labelSelection);
         }
 
+        String newOptLabelSelection;
+        try {
+            // The optimization behavior provided by the user
+            String optLabelSelected = Tools.get(context.getProperties(), "optLabelSelection");
+            // Parse the content of the string
+            newOptLabelSelection = isNullOrEmpty(optLabelSelected) ? optLabelSelection : optLabelSelected.trim();
+        } catch (ClassCastException e) {
+            newOptLabelSelection = optLabelSelection;
+        }
+
+        if (!optLabelSelection.equals(newOptLabelSelection) && LabelAllocator.isInOptEnum(newOptLabelSelection)) {
+            optLabelSelection = newOptLabelSelection;
+            changeOptLabelSelections();
+            log.info("Settings: optLabelSelection={}", optLabelSelection);
+        }
+
         boolean newFlowOptimization;
         try {
             String s = Tools.get(context.getProperties(), "useFlowOptimization");
@@ -265,6 +288,10 @@
         LinkCollectionCompiler.labelAllocator.setLabelSelection(labelSelection);
     }
 
+    private void changeOptLabelSelections() {
+        LinkCollectionCompiler.labelAllocator.setOptLabelSelection(optLabelSelection);
+    }
+
     private void changeFlowOptimization() {
         LinkCollectionCompiler.optimizeInstructions = optimizeInstructions;
     }
diff --git a/core/net/src/main/java/org/onosproject/net/resource/impl/LabelAllocator.java b/core/net/src/main/java/org/onosproject/net/resource/impl/LabelAllocator.java
index 34c8285..bc41fb1 100644
--- a/core/net/src/main/java/org/onosproject/net/resource/impl/LabelAllocator.java
+++ b/core/net/src/main/java/org/onosproject/net/resource/impl/LabelAllocator.java
@@ -34,10 +34,13 @@
 import org.onosproject.net.resource.ResourceConsumer;
 import org.onosproject.net.resource.ResourceService;
 import org.onosproject.net.resource.Resources;
+import org.slf4j.Logger;
 
 import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
 
 import java.util.Collections;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -50,7 +53,12 @@
  */
 public final class LabelAllocator {
 
-    private enum Behavior {
+    private final Logger log = getLogger(getClass());
+
+    /**
+     * Defines possible behaviors for the selection of the labels.
+     */
+    private enum SelectionBehavior {
         /**
          * Random selection.
          */
@@ -61,30 +69,67 @@
         FIRST_FIT
     }
 
-    private static final Behavior[] BEHAVIORS = Behavior.values();
+    /**
+     * Defines possible optimizations for the selection of the labels.
+     */
+    enum OptimizationBehavior {
+        /**
+         * Allocator does not try to optimize, it defines a new candidates
+         * set at each hop and select label according to the selection strategy.
+         */
+        NONE,
+        /**
+         * Allocator enforces same label along the path, it builds a common
+         * set of candidate and select a common label according to the selection
+         * strategy.
+         */
+        NO_SWAP,
+        /**
+         * Allocator try to minimize the swapping of labels along the path. If
+         * it is possible try to reuse the label of the previous hop.
+         */
+        MIN_SWAP
+    }
 
     private ResourceService resourceService;
     private LabelSelection labelSelection;
+    private OptimizationBehavior optLabelSelection;
 
     /**
-     * Creates a new label allocator. Random is the
-     * default behavior.
+     * Creates a new label allocator. Random is the default selection behavior.
+     * None is the default optimization behavior
      *
      * @param rs the resource service
      */
     public LabelAllocator(ResourceService rs) {
         this.resourceService = checkNotNull(rs);
-        this.labelSelection = this.getLabelSelection(Behavior.RANDOM);
+        this.labelSelection = this.getLabelSelection(SelectionBehavior.RANDOM);
+        this.optLabelSelection = OptimizationBehavior.NONE;
     }
 
     /**
-     * Checks if a given string is a valid Behavior.
+     * Checks if a given string is a valid Selection Behavior.
      *
      * @param value the string to check
-     * @return true if value is a valid Behavior, false otherwise
+     * @return true if value is a valid Selection Behavior, false otherwise
      */
-    public static boolean isInEnum(String value) {
-        for (Behavior b : BEHAVIORS) {
+    public static boolean isInSelEnum(String value) {
+        for (SelectionBehavior b : SelectionBehavior.values()) {
+            if (b.name().equals(value)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Checks if a given string is a valid Optimization Behavior.
+     *
+     * @param value the string to check
+     * @return true if value is a valid Optimization Behavior, false otherwise
+     */
+    public static boolean isInOptEnum(String value) {
+        for (OptimizationBehavior b : OptimizationBehavior.values()) {
             if (b.name().equals(value)) {
                 return true;
             }
@@ -98,40 +143,60 @@
      * @param type the behavior type
      */
     public void setLabelSelection(String type) {
-        if (isInEnum(type)) {
+        if (isInSelEnum(type)) {
             this.labelSelection = this.getLabelSelection(type);
         }
     }
 
     /**
-     * Retrieves the label selection behavior.
+     * Retrieves the selection behavior.
      *
-     * @return the label selection behavior in use
+     * @return the selection behavior in use
      */
     public LabelSelection getLabelSelection() {
         return this.labelSelection;
     }
 
     /**
+     * Changes the optimization behavior.
+     *
+     * @param type the optimization type
+     */
+    public void setOptLabelSelection(String type) {
+        if (isInOptEnum(type)) {
+            this.optLabelSelection = OptimizationBehavior.valueOf(type);
+        }
+    }
+
+    /**
+     * Retrieves the optimization behavior.
+     *
+     * @return the optimization behavior in use
+     */
+    public OptimizationBehavior getOptLabelSelection() {
+        return this.optLabelSelection;
+    }
+
+    /**
      * Returns the label selection behavior, given a behavior type.
      *
      * @param type the behavior type
      * @return the label selection behavior in use
      */
     private LabelSelection getLabelSelection(String type) {
-        Behavior behavior = Behavior.valueOf(type);
+        SelectionBehavior behavior = SelectionBehavior.valueOf(type);
         return this.getLabelSelection(behavior);
     }
 
     /**
-     * Creates a new LabelSelection. Random is
-     * the default label selection behavior.
+     * Creates a new LabelSelection. Random is the default
+     * label selection behavior.
      *
      * @param type the behavior type
      * @return the object implementing the behavior
      */
-    private LabelSelection getLabelSelection(Behavior type) {
-        LabelSelection selection = null;
+    private LabelSelection getLabelSelection(SelectionBehavior type) {
+        LabelSelection selection;
         switch (type) {
             case FIRST_FIT:
                 selection = new FirstFitSelection();
@@ -144,6 +209,96 @@
         return selection;
     }
 
+    // Given a link and a encapsulation type, returns a set of candidates
+    private Set<Identifier<?>> getCandidates(LinkKey link, EncapsulationType type) {
+        // Available ids on src port
+        Set<Identifier<?>> availableIDsatSrc = getAvailableIDs(link.src(), type);
+        // Available ids on dst port
+        Set<Identifier<?>> availableIDsatDst = getAvailableIDs(link.dst(), type);
+        // Create the candidate set doing an intersection of the previous sets
+        return Sets.intersection(availableIDsatSrc, availableIDsatDst);
+    }
+
+    // Implements NONE behavior
+    private Map<LinkKey, Identifier<?>> noOptimizeBehavior(Set<LinkKey> links, EncapsulationType type) {
+        // Init step
+        Map<LinkKey, Identifier<?>> ids = Maps.newHashMap();
+        Set<Identifier<?>> candidates;
+        Identifier<?> selected;
+        // Iterates for each link selecting a label in the candidate set
+        for (LinkKey link : links) {
+            // Get candidates set for the current link
+            candidates = getCandidates(link, type);
+            // Select a label for the current link
+            selected = labelSelection.select(candidates);
+            // If candidates is empty, selected is null
+            if (selected == null) {
+                log.warn("No labels for {}", link);
+                return Collections.emptyMap();
+            }
+            // Selected is associated to link
+            ids.put(link, selected);
+        }
+        return ids;
+    }
+
+    // Implements NO_SWAP behavior
+    private Map<LinkKey, Identifier<?>> noSwapBehavior(Set<LinkKey> links, EncapsulationType type) {
+        // Init steps
+        Map<LinkKey, Identifier<?>> ids = Maps.newHashMap();
+        Identifier<?> selected;
+        Set<Identifier<?>> candidates = null;
+        Set<Identifier<?>> linkCandidates;
+        // Iterates for each link building the candidate set
+        for (LinkKey link : links) {
+            // Get candidates set for the current link
+            linkCandidates = getCandidates(link, type);
+            // Warm up
+            if (candidates == null) {
+                candidates = linkCandidates;
+            // Build step by step the intersection
+            } else {
+                candidates = Sets.intersection(candidates, linkCandidates);
+            }
+        }
+        // Pick a label according to the defined strategy
+        selected = labelSelection.select(candidates);
+        if (selected == null) {
+            // If there are no candidates, exit. This will throw a compile exception
+            log.warn("No common label for path");
+            return Collections.emptyMap();
+        }
+        // For each link create an entry
+        links.forEach(linkKey -> ids.put(linkKey, selected));
+        return ids;
+    }
+
+    // Implements MIN_SWAP behavior
+    private Map<LinkKey, Identifier<?>> minSwapBehavior(Set<LinkKey> links, EncapsulationType type) {
+        // Init step
+        Map<LinkKey, Identifier<?>> ids = Maps.newHashMap();
+        Set<Identifier<?>> candidates;
+        Identifier<?> selected = null;
+        // Iterates for each link selecting a label in the candidate set
+        for (LinkKey link : links) {
+            // Get candidates set for the current link
+            candidates = getCandidates(link, type);
+            // If we are in the first link or selected is not available
+            if (selected == null || !candidates.contains(selected)) {
+                // Select a label for the current link
+                selected = labelSelection.select(candidates);
+                // If candidates is empty, selected is null
+                if (selected == null) {
+                    log.warn("No labels for {}", link);
+                    return Collections.emptyMap();
+                }
+            }
+            // Selected is associated to link
+            ids.put(link, selected);
+        }
+        return ids;
+    }
+
     /**
      * Looks for available Ids.
      *
@@ -152,21 +307,24 @@
      * @return the mappings between key and id
      */
     private Map<LinkKey, Identifier<?>> findAvailableIDs(Set<LinkKey> links, EncapsulationType type) {
-
-        Map<LinkKey, Identifier<?>> ids = Maps.newHashMap();
-        for (LinkKey link : links) {
-            Set<Identifier<?>> availableIDsatSrc = getAvailableIDs(link.src(), type);
-            Set<Identifier<?>> availableIDsatDst = getAvailableIDs(link.dst(), type);
-            Set<Identifier<?>> common = Sets.intersection(availableIDsatSrc, availableIDsatDst);
-            if (common.isEmpty()) {
-                continue;
-            }
-            Identifier<?> selected = labelSelection.select(common);
-            if (selected == null) {
-                continue;
-            }
-            ids.put(link, selected);
+        // Init step
+        Map<LinkKey, Identifier<?>> ids;
+        // Performs label selection according to the defined optimization behavior
+        switch (optLabelSelection) {
+            // No swapping of the labels
+            case NO_SWAP:
+                ids = noSwapBehavior(links, type);
+                break;
+            // Swapping is minimized
+            case MIN_SWAP:
+                ids = minSwapBehavior(links, type);
+                break;
+            // No optimizations are in place
+            case NONE:
+            default:
+                ids = noOptimizeBehavior(links, type);
         }
+        // Done exit
         return ids;
     }
 
@@ -214,9 +372,10 @@
     public Map<LinkKey, Identifier<?>> assignLabelToLinks(Set<Link> links,
                                                           ResourceConsumer resourceConsumer,
                                                           EncapsulationType type) {
+        // To preserve order of the links. This is important for MIN_SWAP behavior
         Set<LinkKey> linkRequest = links.stream()
                 .map(LinkKey::linkKey)
-                .collect(Collectors.toSet());
+                .collect(Collectors.toCollection(LinkedHashSet::new));
 
         Map<LinkKey, Identifier<?>> availableIds = findAvailableIDs(linkRequest, type);
         if (availableIds.isEmpty()) {
@@ -319,7 +478,7 @@
 
         /**
          * Selects an identifier from a given set of values using
-         * the first fir selection algorithm.
+         * the first fit selection algorithm.
          *
          * @param values the values to select from
          * @return the selected identifier if values are present, null otherwise.
diff --git a/core/net/src/test/java/org/onosproject/net/resource/impl/LabelAllocatorTest.java b/core/net/src/test/java/org/onosproject/net/resource/impl/LabelAllocatorTest.java
index e069473..fe54a66 100644
--- a/core/net/src/test/java/org/onosproject/net/resource/impl/LabelAllocatorTest.java
+++ b/core/net/src/test/java/org/onosproject/net/resource/impl/LabelAllocatorTest.java
@@ -36,6 +36,7 @@
 import org.onosproject.net.resource.impl.LabelAllocator.LabelSelection;
 import org.onosproject.net.resource.impl.LabelAllocator.RandomSelection;
 
+
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
@@ -43,6 +44,7 @@
 import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
 import static org.onosproject.net.Link.Type.DIRECT;
@@ -62,17 +64,36 @@
     private final ConnectPoint d1p1 = connectPoint("s1", 1);
     private final ConnectPoint d2p0 = connectPoint("s2", 0);
     private final ConnectPoint d2p1 = connectPoint("s2", 1);
+    private final ConnectPoint d3p0 = connectPoint("s3", 0);
+    private final ConnectPoint d3p1 = connectPoint("s3", 1);
+    private final ConnectPoint d4p0 = connectPoint("s4", 0);
+    private final ConnectPoint d4p1 = connectPoint("s4", 1);
 
     private final List<Link> links = Arrays.asList(
             createEdgeLink(d1p0, true),
-            DefaultLink.builder().providerId(PID).src(d1p1).dst(d2p1).type(DIRECT).build(),
+            DefaultLink.builder().providerId(PID).src(d1p1).dst(d3p1).type(DIRECT).build(),
+            DefaultLink.builder().providerId(PID).src(d3p0).dst(d2p1).type(DIRECT).build(),
             createEdgeLink(d2p0, false)
     );
 
+    private final List<Link> links2 = Arrays.asList(
+            createEdgeLink(d1p0, true),
+            DefaultLink.builder().providerId(PID).src(d1p1).dst(d3p1).type(DIRECT).build(),
+            DefaultLink.builder().providerId(PID).src(d3p0).dst(d4p1).type(DIRECT).build(),
+            DefaultLink.builder().providerId(PID).src(d4p0).dst(d2p1).type(DIRECT).build(),
+            createEdgeLink(d2p0, false)
+    );
+
+    // Selection behavior
     private final String firstFit = "FIRST_FIT";
     private final String random = "RANDOM";
     private final String wrong = "BLAHBLAHBLAH";
 
+    // Optimization behavior
+    private final String none = "NONE";
+    private final String noswap = "NO_SWAP";
+    private final String minswap = "MIN_SWAP";
+
     @Before
     public void setUp() {
         this.resourceService = new MockResourceService();
@@ -88,7 +109,7 @@
      * To test changes to the selection behavior.
      */
     @Test
-    public void testChangeBehavior() {
+    public void testChangeSelBehavior() {
         // It has to be an instance of LabelSelection
         assertThat(this.allocator.getLabelSelection(), instanceOf(LabelSelection.class));
         // By default we have Random Selection
@@ -102,174 +123,337 @@
         // We put a wrong type and we should have a Random selection
         this.allocator.setLabelSelection(wrong);
         assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
+        // We change to first_fit and we test the change
+        this.allocator.setLabelSelection("first_fit");
+        // The change does not happen
+        assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
+        this.allocator.setLabelSelection(firstFit);
+        // We change to Random and we test the change
+        this.allocator.setLabelSelection("random");
+        // The change does not happen
+        assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
     }
 
     /**
-     * To test the first fit behavior with VLAN Id. In the First step
-     * we use the default set, for the first selection the selected label
-     * has to be 1. In the Second step we change the default set and for
-     * the first fit selection the selected has to be 2.
+     * To test changes to the optimization behavior.
      */
     @Test
-    public void testFirstFitBehaviorVlan() {
+    public void testChangeOptBehavior() {
+        // It has to be an instance of NONE
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NONE);
+        // Change to MIN_SWAP
+        this.allocator.setOptLabelSelection(minswap);
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.MIN_SWAP);
+        // Change to NO_SWAP
+        this.allocator.setOptLabelSelection(noswap);
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NO_SWAP);
+        // Change to NONE
+        this.allocator.setOptLabelSelection(none);
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NONE);
+        // Change to MIN_SWAP
+        this.allocator.setOptLabelSelection("miN_swap");
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NONE);
+        this.allocator.setOptLabelSelection(minswap);
+        // Change to NO_SWAP
+        this.allocator.setOptLabelSelection("No_swap");
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.MIN_SWAP);
+        this.allocator.setOptLabelSelection(noswap);
+        // Change to NONE
+        this.allocator.setOptLabelSelection("none");
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NO_SWAP);
+    }
+
+    /**
+     * To test the first fit behavior. Using NONE optimization
+     */
+    @Test
+    public void testFirstFitBehaviorNone() {
         // We change to FirstFit and we test the change
         this.allocator.setLabelSelection(firstFit);
         assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
-        // We test the behavior for VLAN
+        // It has to be an instance of NONE
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NONE);
+        // Filter reservations
+        this.resourceService.filterAssignment = true;
+        // We change the available Ids
+        this.resourceService.availableVlanLabels = ImmutableSet.of(
+                (short) 1,
+                (short) 20,
+                (short) 100
+        );
+        // First allocation on a subset of links
         Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
-                ImmutableSet.copyOf(links.subList(1, 2)),
+                ImmutableSet.copyOf(links.subList(2, 3)),
                 IntentId.valueOf(idGenerator.getNewId()),
                 EncapsulationType.VLAN);
-        Identifier<?> id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
-        // value has to be a VlanId
+        Identifier<?> id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        // value has to be a Vlan Id
         assertThat(id, instanceOf(VlanId.class));
         // value should not be a forbidden value
         VlanId vlanId = (VlanId) id;
         assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
-        // value will be always 1
-        assertEquals(1, vlanId.toShort());
-
-        // We change the available Ids
-        this.resourceService.availableVlanLabels = ImmutableSet.of(
-                (short) 100,
-                (short) 11,
-                (short) 20,
-                (short) 2,
-                (short) 3
-        );
-        // We test again the behavior for VLAN
+        // We test the behavior for VLAN
         allocation = this.allocator.assignLabelToLinks(
-                ImmutableSet.copyOf(links.subList(1, 2)),
+                ImmutableSet.copyOf(links.subList(1, 3)),
                 IntentId.valueOf(idGenerator.getNewId()),
                 EncapsulationType.VLAN);
-        id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
-        // value has to be a VlanId
+        id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
         assertThat(id, instanceOf(VlanId.class));
-        // value should not be a forbidden value
         vlanId = (VlanId) id;
         assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
-        // value will be always 2
-        assertEquals(2, vlanId.toShort());
+        id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        assertThat(id, instanceOf(VlanId.class));
+        vlanId = (VlanId) id;
+        assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
     }
 
     /**
-     * To test the first fit behavior with MPLS label. In the First step
-     * we use the default set, for the first selection the selected label
-     * has to be 1. In the Second step we change the default set and for
-     * the first fit selection the selected has to be 100.
+     * To test the first fit behavior. Using NO_SWAP optimization
      */
     @Test
-    public void testFirstFitBehaviorMpls() {
+    public void testFirstFitBehaviorNoSwap() {
         // We change to FirstFit and we test the change
         this.allocator.setLabelSelection(firstFit);
         assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
-        // We test the behavior for MPLS
+        /// Change to NO_SWAP
+        this.allocator.setOptLabelSelection(noswap);
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NO_SWAP);
+        // Filter reservations
+        this.resourceService.filterAssignment = true;
+        // We change the available Ids
+        this.resourceService.availableMplsLabels = ImmutableSet.of(
+                1,
+                100,
+                1000
+        );
+        // First allocation on a subset of links
         Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
-                ImmutableSet.copyOf(links.subList(1, 2)),
+                ImmutableSet.copyOf(links.subList(2, 3)),
                 IntentId.valueOf(idGenerator.getNewId()),
                 EncapsulationType.MPLS);
-        Identifier<?> id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
-        // value has to be a Mplslabel
+        Identifier<?> id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        // value has to be a MPLS label
         assertThat(id, instanceOf(MplsLabel.class));
         // value should not be a forbidden value
         MplsLabel mplsLabel = (MplsLabel) id;
         assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
-        // value will be always 1
-        assertEquals(1, mplsLabel.toInt());
-
-        // We change the available Ids
-        this.resourceService.availableMplsLabels = ImmutableSet.of(
-                100,
-                200,
-                1000
-        );
-        // We test again the behavior for MPLS
+        // We test the behavior for MPLS
         allocation = this.allocator.assignLabelToLinks(
-                ImmutableSet.copyOf(links.subList(1, 2)),
+                ImmutableSet.copyOf(links.subList(1, 3)),
                 IntentId.valueOf(idGenerator.getNewId()),
                 EncapsulationType.MPLS);
-        id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
-        // value has to be a Mplslabel
+        id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
         assertThat(id, instanceOf(MplsLabel.class));
-        // value should not be a forbidden value
         mplsLabel = (MplsLabel) id;
         assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
-        // value will be always 100
-        assertEquals(100, mplsLabel.toInt());
+        id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        assertThat(id, instanceOf(MplsLabel.class));
+        mplsLabel = (MplsLabel) id;
+        assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
     }
 
     /**
-     * To test the random behavior with VLAN Id. We make two selection,
-     * we test that these two selection are different.
+     * To test the first fit behavior. Using MIN_SWAP optimization
      */
     @Test
-    public void testRandomBehaviorVlan() {
-        // Verify the random behavior
-        assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
-        // We test the behavior for VLAN
+    public void testFirstFitBehaviorMinSwap() {
+        // We change to FirstFit and we test the change
+        this.allocator.setLabelSelection(firstFit);
+        assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
+        /// Change to MIN_SWAP
+        this.allocator.setOptLabelSelection(minswap);
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.MIN_SWAP);
+        // Filter reservations
+        this.resourceService.filterAssignment = true;
+        // We change the available Ids
+        this.resourceService.availableVlanLabels = ImmutableSet.of(
+                (short) 2,
+                (short) 20,
+                (short) 200
+        );
+        // First allocation on a subset of links
         Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
-                ImmutableSet.copyOf(links.subList(1, 2)),
+                ImmutableSet.copyOf(links2.subList(2, 3)),
                 IntentId.valueOf(idGenerator.getNewId()),
                 EncapsulationType.VLAN);
-        Identifier<?> id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
-        // value has to be a VlanId
-        assertThat(id, instanceOf(VlanId.class));
-        // value should not be a forbidden value
-        Short value = Short.parseShort(id.toString());
-        VlanId prevVlanId = VlanId.vlanId(value);
-        assertTrue(VlanId.NO_VID <= prevVlanId.toShort() && prevVlanId.toShort() <= VlanId.MAX_VLAN);
-
-        allocation = this.allocator.assignLabelToLinks(
-                ImmutableSet.copyOf(links.subList(1, 2)),
-                IntentId.valueOf(idGenerator.getNewId()),
-                EncapsulationType.VLAN);
-         id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
-        // value has to be a VlanId
+        Identifier<?> id = allocation.get(LinkKey.linkKey(d3p0, d4p1));
+        // value has to be a VLAN id
         assertThat(id, instanceOf(VlanId.class));
         // value should not be a forbidden value
         VlanId vlanId = (VlanId) id;
-        assertTrue(VlanId.NO_VID <= vlanId.toShort() && vlanId.toShort() <= VlanId.MAX_VLAN);
-
+        assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
+        // We test the behavior for VLAN
+        allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links2.subList(1, 4)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.VLAN);
+        id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+        assertThat(id, instanceOf(VlanId.class));
+        vlanId = (VlanId) id;
+        assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
+        id = allocation.get(LinkKey.linkKey(d3p0, d4p1));
+        assertThat(id, instanceOf(VlanId.class));
+        vlanId = (VlanId) id;
+        assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
+        id = allocation.get(LinkKey.linkKey(d4p0, d2p1));
+        assertThat(id, instanceOf(VlanId.class));
+        vlanId = (VlanId) id;
+        assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
     }
 
     /**
-     * To test random behavior with MPLS label. We make two selection,
-     * we test that these two selection are different.
+     * To test random behavior. Using NONE optimization
      */
     @Test
-    public void testRandomBehaviorMpls() {
-        // Verify the random behavior
+    public void testRandomBehaviorNone() {
+        // By default Random is the selection behavior used
         assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
-        // We test the behavior for MPLS
+        // It has to be an instance of NONE
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NONE);
+        // Filter reservations
+        this.resourceService.filterAssignment = true;
+        // We change the available Ids
+        this.resourceService.availableMplsLabels = ImmutableSet.of(
+                1,
+                2,
+                3,
+                4,
+                5,
+                6
+        );
+        // First allocation on a subset of links
         Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
-                ImmutableSet.copyOf(links.subList(1, 2)),
+                ImmutableSet.copyOf(links.subList(2, 3)),
                 IntentId.valueOf(idGenerator.getNewId()),
                 EncapsulationType.MPLS);
-        Identifier<?> id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
-        // value has to be a Mplslabel
+        Identifier<?> id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        // value has to be a MPLS label
         assertThat(id, instanceOf(MplsLabel.class));
         // value should not be a forbidden value
-        MplsLabel prevMplsId = (MplsLabel) id;
-        assertTrue(0 <= prevMplsId.toInt() && prevMplsId.toInt() <= MplsLabel.MAX_MPLS);
-
+        MplsLabel mplsLabel = (MplsLabel) id;
+        assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
+        // We test the behavior for MPLS
         allocation = this.allocator.assignLabelToLinks(
-                ImmutableSet.copyOf(links.subList(1, 2)),
+                ImmutableSet.copyOf(links.subList(1, 3)),
                 IntentId.valueOf(idGenerator.getNewId()),
                 EncapsulationType.MPLS);
-        id = allocation.get(LinkKey.linkKey(d1p1, d2p1));
-        // value has to be a Mplslabel
+        id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+        assertThat(id, instanceOf(MplsLabel.class));
+        mplsLabel = (MplsLabel) id;
+        assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
+        id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        assertThat(id, instanceOf(MplsLabel.class));
+        mplsLabel = (MplsLabel) id;
+        assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
+    }
+
+    /**
+     * To test random behavior. Using NO_SWAP optimization
+     */
+    @Test
+    public void testRandomBehaviorNoSwap() {
+        // By default Random is the selection behavior used
+        assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
+        // Change to NO_SWAP
+        this.allocator.setOptLabelSelection(noswap);
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NO_SWAP);
+        // Filter reservations
+        this.resourceService.filterAssignment = true;
+        // We change the available Ids
+        this.resourceService.availableVlanLabels = ImmutableSet.of(
+                (short) 1,
+                (short) 2,
+                (short) 3,
+                (short) 4,
+                (short) 5,
+                (short) 6
+        );
+        // First allocation on a subset of links
+        Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(2, 3)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.VLAN);
+        Identifier<?> id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        // value has to be a VLAN Id
+        assertThat(id, instanceOf(VlanId.class));
+        // value should not be a forbidden value
+        VlanId vlanId = (VlanId) id;
+        assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
+        // We test the behavior for VLAN
+        allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 3)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.VLAN);
+        id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+        assertThat(id, instanceOf(VlanId.class));
+        vlanId = (VlanId) id;
+        assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
+        id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        assertThat(id, instanceOf(VlanId.class));
+        vlanId = (VlanId) id;
+        assertTrue(VlanId.NO_VID < vlanId.toShort() && vlanId.toShort() < VlanId.MAX_VLAN);
+    }
+
+    /**
+     * To test the random behavior. Using MIN_SWAP optimization
+     */
+    @Test
+    public void testRandomBehaviorMinSwap() {
+        // By default Random is the selection behavior used
+        assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
+        // Change to MIN_SWAP
+        this.allocator.setOptLabelSelection(minswap);
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.MIN_SWAP);
+        // Filter reservations
+        this.resourceService.filterAssignment = true;
+        // We change the available Ids
+        this.resourceService.availableMplsLabels = ImmutableSet.of(
+                1,
+                2,
+                3,
+                4,
+                5,
+                6,
+                7,
+                8
+        );
+        // First allocation on a subset of links
+        Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links2.subList(2, 3)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.MPLS);
+        Identifier<?> id = allocation.get(LinkKey.linkKey(d3p0, d4p1));
+        // value has to be a MPLS label
         assertThat(id, instanceOf(MplsLabel.class));
         // value should not be a forbidden value
-        MplsLabel mplsId = (MplsLabel) id;
-        assertTrue(0 <= mplsId.toInt() && mplsId.toInt() <= MplsLabel.MAX_MPLS);
+        MplsLabel mplsLabel = (MplsLabel) id;
+        assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
+        // We test the behavior for MPLS
+        allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links2.subList(1, 4)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.MPLS);
+        id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+        assertThat(id, instanceOf(MplsLabel.class));
+        mplsLabel = (MplsLabel) id;
+        assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
+        id = allocation.get(LinkKey.linkKey(d3p0, d4p1));
+        assertThat(id, instanceOf(MplsLabel.class));
+        mplsLabel = (MplsLabel) id;
+        assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
+        id = allocation.get(LinkKey.linkKey(d4p0, d2p1));
+        assertThat(id, instanceOf(MplsLabel.class));
+        mplsLabel = (MplsLabel) id;
+        assertTrue(0 < mplsLabel.toInt() && mplsLabel.toInt() < MplsLabel.MAX_MPLS);
     }
 
+
     /**
      * To test the port key based API.
      */
     @Test
     public void testPortKey() {
-        // Verify the first behavior
+        // Verify the first fit behavior
         this.allocator.setLabelSelection(firstFit);
         assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
         // We test the behavior for VLAN
@@ -286,7 +470,7 @@
         // value has to be 1
         assertEquals(1, prevVlanId.toShort());
         // verify same applies for d2p1
-        id = allocation.get(new ConnectPoint(d2p1.elementId(), d2p1.port()));
+        id = allocation.get(new ConnectPoint(d3p1.elementId(), d3p1.port()));
         assertThat(id, instanceOf(VlanId.class));
         // value should not be a forbidden value
         VlanId vlanId = (VlanId) id;
@@ -295,6 +479,232 @@
         assertEquals(prevVlanId, vlanId);
     }
 
+    /**
+     * To test the developed algorithms when there are no labels.
+     */
+    @Test
+    public void noLabelsTest() {
+        // Verify the first fit behavior with NONE optimization
+        this.allocator.setLabelSelection(firstFit);
+        assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
+        // It has to be an instance of NONE
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NONE);
+        // We change the available Ids
+        this.resourceService.availableVlanLabels = ImmutableSet.of(
+                (short) 10
+        );
+        // Enable filtering of the reservation
+        this.resourceService.filterAssignment = true;
+        // We test the behavior for VLAN
+        Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 3)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.VLAN);
+        Identifier<?> id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+        // value has to be a VlanId
+        assertThat(id, instanceOf(VlanId.class));
+        // value should not be a forbidden value
+        VlanId label = (VlanId) id;
+        assertTrue(VlanId.NO_VID < label.toShort() && label.toShort() < VlanId.MAX_VLAN);
+        // Next hop
+        id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        assertThat(id, instanceOf(VlanId.class));
+        label = (VlanId) id;
+        assertTrue(VlanId.NO_VID < label.toShort() && label.toShort() < VlanId.MAX_VLAN);
+        // No labels are available, reservation is not possible
+        allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 3)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.VLAN);
+        id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+        // value has to be null
+        assertNull(id);
+        id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        // value has to be null
+        assertNull(id);
 
+        // Verify the random behavior with NONE_SWAP optimization
+        this.allocator.setLabelSelection(random);
+        assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
+        // Change to NO_SWAP
+        this.allocator.setOptLabelSelection(noswap);
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NO_SWAP);
+        // We change the available Ids
+        this.resourceService.availableMplsLabels = ImmutableSet.of(
+                2000
+        );
+        // Enable filtering of the reservation
+        this.resourceService.filterAssignment = true;
+        // We test the behavior for MPLS
+        allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 3)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.MPLS);
+        id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+        // value has to be a Mplslabel
+        assertThat(id, instanceOf(MplsLabel.class));
+        // value should not be a forbidden value
+        MplsLabel mplsLabel = (MplsLabel) id;
+        assertTrue(0 <= mplsLabel.toInt() && mplsLabel.toInt() <= MplsLabel.MAX_MPLS);
+        id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        assertThat(id, instanceOf(MplsLabel.class));
+        mplsLabel = (MplsLabel) id;
+        assertTrue(0 <= mplsLabel.toInt() && mplsLabel.toInt() <= MplsLabel.MAX_MPLS);
+        // No labels are available, reservation is not possible
+        allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 3)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.MPLS);
+        id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+        // value has to be null
+        assertNull(id);
+        id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        // value has to be null
+        assertNull(id);
+
+        // Verify the first fit behavior with MIN optimization
+        this.allocator.setLabelSelection(firstFit);
+        assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
+        // Change to MIN_SWAP
+        this.allocator.setOptLabelSelection(minswap);
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.MIN_SWAP);
+        // We change the available Ids
+        this.resourceService.availableVlanLabels = ImmutableSet.of(
+                (short) 11
+        );
+        // Enable filtering of the reservation
+        this.resourceService.filterAssignment = true;
+        // We test the behavior for VLAN
+        allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 3)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.VLAN);
+        id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+        // value has to be a VlanId
+        assertThat(id, instanceOf(VlanId.class));
+        // value should not be a forbidden value
+        label = (VlanId) id;
+        assertTrue(VlanId.NO_VID < label.toShort() && label.toShort() < VlanId.MAX_VLAN);
+        // Next hop
+        id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        assertThat(id, instanceOf(VlanId.class));
+        label = (VlanId) id;
+        assertTrue(VlanId.NO_VID < label.toShort() && label.toShort() < VlanId.MAX_VLAN);
+        // No labels are available, reservation is not possible
+        allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 3)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.VLAN);
+        id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+        // value has to be null
+        assertNull(id);
+        id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        // value has to be null
+        assertNull(id);
+    }
+
+    /**
+     * To test the developed algorithms when there are no labels on a specific link.
+     */
+    @Test
+    public void noLabelsOnLinkTest() {
+        // Verify the first fit behavior with NONE optimization
+        this.allocator.setLabelSelection(firstFit);
+        assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
+        // It has to be an instance of NONE
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NONE);
+        // We change the available Ids
+        this.resourceService.availableVlanLabels = ImmutableSet.of(
+                (short) 10
+        );
+        // Enable filtering of the reservation
+        this.resourceService.filterAssignment = true;
+        // We test the behavior for VLAN
+        Map<LinkKey, Identifier<?>> allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(2, 3)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.VLAN);
+        Identifier<?> id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        assertThat(id, instanceOf(VlanId.class));
+        VlanId label = (VlanId) id;
+        assertTrue(VlanId.NO_VID < label.toShort() && label.toShort() < VlanId.MAX_VLAN);
+        // No labels are available, reservation is not possible
+        allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 3)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.VLAN);
+        id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+        // value has to be null
+        assertNull(id);
+        id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        // value has to be null
+        assertNull(id);
+
+        // Verify the random behavior with NONE_SWAP optimization
+        this.allocator.setLabelSelection(random);
+        assertThat(this.allocator.getLabelSelection(), instanceOf(RandomSelection.class));
+        // Change to NO_SWAP
+        this.allocator.setOptLabelSelection(noswap);
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.NO_SWAP);
+        // We change the available Ids
+        this.resourceService.availableMplsLabels = ImmutableSet.of(
+                2000
+        );
+        // Enable filtering of the reservation
+        this.resourceService.filterAssignment = true;
+        // We test the behavior for MPLS
+        allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(2, 3)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.MPLS);
+        id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        assertThat(id, instanceOf(MplsLabel.class));
+        MplsLabel mplsLabel = (MplsLabel) id;
+        assertTrue(0 <= mplsLabel.toInt() && mplsLabel.toInt() <= MplsLabel.MAX_MPLS);
+        // No labels are available, reservation is not possible
+        allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 3)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.MPLS);
+        id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+        // value has to be null
+        assertNull(id);
+        id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        // value has to be null
+        assertNull(id);
+
+        // Verify the first fit behavior with MIN optimization
+        this.allocator.setLabelSelection(firstFit);
+        assertThat(this.allocator.getLabelSelection(), instanceOf(FirstFitSelection.class));
+        // Change to MIN_SWAP
+        this.allocator.setOptLabelSelection(minswap);
+        assertEquals(this.allocator.getOptLabelSelection(), LabelAllocator.OptimizationBehavior.MIN_SWAP);
+        // We change the available Ids
+        this.resourceService.availableVlanLabels = ImmutableSet.of(
+                (short) 11
+        );
+        // Enable filtering of the reservation
+        this.resourceService.filterAssignment = true;
+        // We test the behavior for VLAN
+        allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(2, 3)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.VLAN);
+        id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        assertThat(id, instanceOf(VlanId.class));
+        label = (VlanId) id;
+        assertTrue(VlanId.NO_VID < label.toShort() && label.toShort() < VlanId.MAX_VLAN);
+        // No labels are available, reservation is not possible
+        allocation = this.allocator.assignLabelToLinks(
+                ImmutableSet.copyOf(links.subList(1, 3)),
+                IntentId.valueOf(idGenerator.getNewId()),
+                EncapsulationType.VLAN);
+        id = allocation.get(LinkKey.linkKey(d1p1, d3p1));
+        // value has to be null
+        assertNull(id);
+        id = allocation.get(LinkKey.linkKey(d3p0, d2p1));
+        // value has to be null
+        assertNull(id);
+    }
 
 }
