diff --git a/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java b/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java
index 9952e46..62613e0 100644
--- a/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java
+++ b/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java
@@ -40,6 +40,7 @@
     private final Map<Resource, ResourceConsumer> assignment = new HashMap<>();
     public Set<Short> availableVlanLabels = new HashSet<>();
     public Set<Integer> availableMplsLabels = new HashSet<>();
+    public boolean filterAssignment = false;
 
     public MockResourceService(){}
 
@@ -169,7 +170,11 @@
         resources.add(Resources.discrete(parent).resource().child(TributarySlot.of(6)));
         resources.add(Resources.discrete(parent).resource().child(TributarySlot.of(7)));
         resources.add(Resources.discrete(parent).resource().child(TributarySlot.of(8)));
-        return ImmutableSet.copyOf(resources);
+        return filterAssignment ? ImmutableSet.copyOf(
+                resources.stream().filter(
+                        resource -> assignment.get(resource) == null
+                ).collect(Collectors.toSet())
+        ) : ImmutableSet.copyOf(resources);
     }
 
     @Override
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);
+    }
 
 }
