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);
+    }
 
 }
