Do not use NotificationListener in LISP components
[lispflowmapping.git] / integrationtest / src / test / java / org / opendaylight / lispflowmapping / integrationtest / MappingServiceIntegrationTest.java
index fba316b3ec75f237aedd433fc699518f06b7e3d9..72ea2154ec7aee22f60fd5383e31b1e903418b37 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Contextream, Inc. and others.  All rights reserved.
+ * Copyright (c) 2014, 2017 Contextream, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -9,6 +9,7 @@ package org.opendaylight.lispflowmapping.integrationtest;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_A;
@@ -16,6 +17,7 @@ import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenario
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_B;
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_B_SB;
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_C;
+import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_C_NEGATIVE;
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_C_RLOC_10;
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_C_SB;
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_C_WP_100_1_SB;
@@ -26,12 +28,16 @@ import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenario
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_D_WP_100_1_SB;
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_D_WP_50_2_SB;
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_E_SB;
-import static org.ops4j.pax.exam.CoreOptions.composite;
 import static org.ops4j.pax.exam.CoreOptions.maven;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole;
 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
 
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import java.io.File;
 import java.io.IOException;
-import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
@@ -41,66 +47,37 @@ import java.net.UnknownHostException;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
-
+import java.util.Set;
 import javax.inject.Inject;
-
-//import org.codehaus.jettison.json.JSONException;
-//import org.codehaus.jettison.json.JSONObject;
-//import org.codehaus.jettison.json.JSONTokener;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
+import org.opendaylight.lispflowmapping.config.ConfigIni;
 import org.opendaylight.lispflowmapping.implementation.LispMappingService;
+import org.opendaylight.lispflowmapping.interfaces.dao.SubKeys;
+import org.opendaylight.lispflowmapping.interfaces.dao.Subscriber;
 import org.opendaylight.lispflowmapping.interfaces.lisp.IFlowMapping;
 import org.opendaylight.lispflowmapping.interfaces.mappingservice.IMappingService;
-import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier;
-import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
-import org.opendaylight.lispflowmapping.lisp.type.LispMessage;
-import org.opendaylight.lispflowmapping.lisp.serializer.MapNotifySerializer;
 import org.opendaylight.lispflowmapping.lisp.serializer.MapRegisterSerializer;
-import org.opendaylight.lispflowmapping.lisp.serializer.MapReplySerializer;
 import org.opendaylight.lispflowmapping.lisp.serializer.MapRequestSerializer;
+import org.opendaylight.lispflowmapping.lisp.type.LispMessage;
+import org.opendaylight.lispflowmapping.lisp.type.MappingData;
+import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier;
+import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
+import org.opendaylight.lispflowmapping.lisp.util.MappingRecordUtil;
+import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
 import org.opendaylight.lispflowmapping.type.sbplugin.IConfigLispSouthboundPlugin;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.Ipv4PrefixBinaryAfi;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.AddMapping;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.GotMapNotify;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.GotMapReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapNotify;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRegister;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRequest;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MappingKeepAlive;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.OdlLispProtoListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.RequestMapping;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrReplyMapping;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrRequestMapping;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.EidBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.list.EidItem;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.list.EidItemBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecordBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecordBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItem;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItemBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapregisternotification.MapRegisterBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequest.ItrRloc;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequest.ItrRlocBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequest.SourceEidBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequestnotification.MapRequestBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.rloc.container.Rloc;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.rloc.container.RlocBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.mapping.authkey.container.MappingAuthkey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.mapping.authkey.container.MappingAuthkeyBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
+import org.opendaylight.mdsal.binding.api.NotificationService.Listener;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.AfiListLcaf;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.ApplicationDataLcaf;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.ExplicitLocatorPathLcaf;
@@ -110,6 +87,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.addres
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.MacAfi;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.SimpleAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.SourceDestKeyLcaf;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.AfiList;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.ApplicationData;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.ExplicitLocatorPath;
@@ -125,14 +103,48 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.addres
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.explicit.locator.path.explicit.locator.path.Hop.LrsBits;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.explicit.locator.path.explicit.locator.path.HopBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.source.dest.key.SourceDestKeyBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.inet.binary.types.rev160303.Ipv4AddressBinary;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.Ipv4PrefixBinaryAfi;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.augmented.lisp.address.address.Ipv4PrefixBinaryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapNotify;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRegister;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRequest;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MessageType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrRequestMapping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.EidBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.list.EidItem;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.list.EidItemBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecordBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkeyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping._record.container.MappingRecord;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping._record.container.MappingRecord.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping._record.container.MappingRecordBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping._record.list.MappingRecordItem;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping._record.list.MappingRecordItemBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapregisternotification.MapRegisterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequest.ItrRloc;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequest.ItrRlocBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequest.SourceEidBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequestnotification.MapRequestBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.rloc.container.Rloc;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.rloc.container.RlocBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingOrigin;
+import org.opendaylight.yangtools.yang.common.Uint16;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.common.Uint8;
+import org.ops4j.io.FileUtils;
 import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.junit.PaxExam;
-import org.ops4j.pax.exam.util.Filter;
 import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
 import org.ops4j.pax.exam.options.MavenUrlReference;
 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
 import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.ops4j.pax.exam.util.Filter;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
@@ -149,31 +161,21 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
     private byte[] mapRegisterPacketWithoutNotify;
     String lispBindAddress = "127.0.0.1";
     static final String ourAddress = "127.0.0.2";
-    private Rloc locatorEid;
     private DatagramSocket socket;
     private byte[] mapRegisterPacketWithAuthenticationAndMapNotify;
 
     public static final String ODL = "org.opendaylight.controller";
     public static final String YANG = "org.opendaylight.yangtools";
+    private static final int MULTI_SITE_SLEEP_TIME = 2;
     private static final int MAX_NOTIFICATION_RETRYS = 20;
-    private static final MappingAuthkey NULL_AUTH_KEY = new MappingAuthkeyBuilder().setKeyType(0).build();
-
-    @Override
-    public String getModuleName() {
-        return "mappingservice-impl";
-    }
-
-    @Override
-    public String getInstanceName() {
-        return "mappingservice-default";
-    }
+    private static final MappingAuthkey NULL_AUTH_KEY = new MappingAuthkeyBuilder().setKeyType(Uint16.ZERO).build();
 
     // This is temporary, since the properties in the pom file are not picked up
     @Override
     public String getKarafDistro() {
         return maven()
                 .groupId("org.opendaylight.lispflowmapping")
-                .artifactId("distribution-karaf")
+                .artifactId("lispflowmapping-karaf")
                 .versionAsInProject()
                 .type("zip")
                 .getURL();
@@ -195,12 +197,17 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
     }
 
     @Override
-    public Option getLoggingOption() {
-        Option option = editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
-                "log4j.logger.org.opendaylight.lispflowmapping",
-                LogLevel.DEBUG.name());
-        option = composite(option, super.getLoggingOption());
-        return option;
+    protected Option[] getAdditionalOptions() {
+        return new Option[] {
+                keepRuntimeFolder(),
+                configureConsole().ignoreLocalConsole().ignoreRemoteShell(),
+                editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
+                        "log4j2.logger.lispflowmapping.name",
+                        "org.opendaylight.lispflowmapping"),
+                editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
+                        "log4j2.logger.lispflowmapping.level",
+                        LogLevel.TRACE.name())
+        };
     }
 
     @Test
@@ -213,19 +220,19 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         if (socket != null) {
             socket.close();
         }
-//        if (connection != null) {
-//            connection.disconnect();
-//        }
     }
 
     @Before
     public void before() throws Exception {
+        File paxExamDirectory = new File("target/exam/");
+        FileUtils.delete(paxExamDirectory);
+
         areWeReady();
         mapService.setLookupPolicy(IMappingService.LookupPolicy.NB_FIRST);
-        mapService.setMappingOverwrite(true);
+        mapService.setMappingMerge(false);
+        ConfigIni.getInstance().setSmrRetryCount(1);
 
-        locatorEid = LispAddressUtil.asIpv4Rloc("4.3.2.1");
-        socket = initSocket(socket, LispMessage.PORT_NUM);
+        socket = MappingServiceIntegrationTestUtil.initSocket(LispMessage.PORT_NUM);
 
         // SRC: 127.0.0.1:58560 to 127.0.0.1:4342
         // LISP(Type = 8 - Encapsulated)
@@ -239,13 +246,13 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         // Nonce: 0x3d8d2acd39c8d608
         // ITR-RLOC AFI=1 Address=192.168.136.10
         // Record 1: 153.16.254.1/32
-        mapRequestPacket = extractWSUdpByteArray(new String("0000   00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 " //
+        mapRequestPacket = extractWSUdpByteArray("0000   00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 "
                 + "0010   00 58 00 00 40 00 40 11 3c 93 7f 00 00 01 7f 00 "
                 + "0020   00 01 e4 c0 10 f6 00 44 fe 57 80 00 00 00 45 00 "
                 + "0030   00 3c d4 31 00 00 ff 11 56 f3 7f 00 00 02 99 10 "
                 + "0040   fe 01 dd b4 10 f6 00 28 ef 3a 10 00 00 01 3d 8d "
-                + "0050   2a cd 39 c8 d6 08 00 01 01 02 03 04 00 01 7f 00 00 02 00 20 " //
-                + "0060   00 01 99 10 fe 01"));
+                + "0050   2a cd 39 c8 d6 08 00 01 01 02 03 04 00 01 7f 00 00 02 00 20 "
+                + "0060   00 01 99 10 fe 01");
 
         // IP: 192.168.136.10 -> 128.223.156.35
         // UDP: 49289 -> 4342
@@ -262,14 +269,14 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         // 255/0
         //
 
-        mapRegisterPacketWithAuthenticationAndMapNotify = extractWSUdpByteArray(new String(
-                  "0000   00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
+        mapRegisterPacketWithAuthenticationAndMapNotify = extractWSUdpByteArray(
+                  "0000   00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
                 + "0010   00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
                 + "0020   9c 23 d6 40 10 f6 00 48 59 a4 38 00 01 01 00 00 "
                 + "0030   00 00 00 00 00 00 00 01 00 14 0e a4 c6 d8 a4 06 "
                 + "0040   71 7c 33 a4 5c 4a 83 1c de 74 53 03 0c ad 00 00 "
-                + "0050   00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
-                + "0060   ff 00 00 05 00 01 c0 a8 88 0a"));
+                + "0050   00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
+                + "0060   ff 00 00 05 00 01 c0 a8 88 0a");
 
         // IP: 192.168.136.10 -> 128.223.156.35
         // UDP: 49289 -> 4342
@@ -285,14 +292,14 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         // 255/0
         //
 
-        mapRegisterPacketWithNotify = extractWSUdpByteArray(new String(
-                  "0000   00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
+        mapRegisterPacketWithNotify = extractWSUdpByteArray(
+                  "0000   00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
                 + "0010   00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
                 + "0020   9c 23 d6 40 10 f6 00 48 59 a4 38 00 01 01 00 00 "
                 + "0030   00 00 00 00 00 07 00 00 00 14 0e a4 c6 d8 a4 06 "
                 + "0040   71 7c 33 a4 5c 4a 83 1c de 74 53 03 0c ad 00 00 "
-                + "0050   00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
-                + "0060   ff 00 00 05 00 01 c0 a8 88 0a"));
+                + "0050   00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
+                + "0060   ff 00 00 05 00 01 c0 a8 88 0a");
 
         // IP: 192.168.136.10 -> 128.223.156.35
         // UDP: 49289 -> 4342
@@ -308,14 +315,14 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         // 255/0
         //
 
-        mapRegisterPacketWithoutNotify = extractWSUdpByteArray(new String(
-                  "0000   00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 " //
+        mapRegisterPacketWithoutNotify = extractWSUdpByteArray(
+                  "0000   00 50 56 ee d1 4f 00 0c 29 7a ce 79 08 00 45 00 "
                 + "0010   00 5c 00 00 40 00 40 11 d4 db c0 a8 88 0a 80 df "
                 + "0020   9c 23 d6 40 10 f6 00 48 59 a4 38 00 00 01 00 00 "
                 + "0030   00 00 00 00 00 07 00 00 00 14 0e a4 c6 d8 a4 06 "
                 + "0040   71 7c 33 a4 5c 4a 83 1c de 74 53 03 0c ad 00 00 "
-                + "0050   00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 " //
-                + "0060   ff 00 00 05 00 01 c0 a8 88 0a"));
+                + "0050   00 0a 01 20 10 00 00 00 00 01 99 10 fe 01 01 64 "
+                + "0060   ff 00 00 05 00 01 c0 a8 88 0a");
     }
 
     @Inject
@@ -373,18 +380,9 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         northboundRetrieveSourceDestMapping();
     }
 */
-    @Test
-    public void testOverWriting() throws Exception {
-        //testMapRegisterDosntOverwritesOtherSubKeys(); TODO weird failure, needs debug
-
-        // TODO: remove, we don't support overwrite flag any longer and RLOCs are not saved as independent RLOC groups
-        // testMapRegisterOverwritesSameSubkey();
-        // testMapRegisterOverwritesNoSubkey();
-        // testMapRegisterDoesntOverwritesNoSubkey();
-    }
-
     @Test
     public void testTimeOuts() throws Exception {
+        timedOutMappingRecord();
         mapRequestMapRegisterAndMapRequestTestTimeout();
         //mapRequestMapRegisterAndMapRequestTestNativelyForwardTimeoutResponse();   TODO commented because it needs NB
     }
@@ -399,6 +397,7 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
     @Test
     public void testSmr() throws Exception {
         registerQueryRegisterWithSmr();
+        //testRepeatedSmr();
     }
 
     @Test
@@ -407,11 +406,1031 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         testMultiSiteScenarioB();
     }
 
+    @Test
+    public void testNbAndSbNegativePrefix() throws UnknownHostException {
+        insertMappings();
+        testGapIntersection();
+
+        insertMappings();
+        testMultipleMappings();
+    }
+
+    @Test
+    public void testExplicitSbNegativePrefixes() {
+        // https://bugs.opendaylight.org/show_bug.cgi?id=8679
+        testNegativePrefix();
+
+        // https://bugs.opendaylight.org/show_bug.cgi?id=9023
+        testPositiveMappingRemoval();
+
+        // https://bugs.opendaylight.org/show_bug.cgi?id=9037
+        testPositivePrefixOverlappingNegativePrefix_moreSpecific();
+
+        // https://bugs.opendaylight.org/show_bug.cgi?id=9116
+        testPositivePrefixOverlappingNegativePrefix_lessSpecific();
+    }
+
+    @Test
+    public void testMappingChangeCases() {
+        // Test numbers described in the below Google Sheet:
+        // https://docs.google.com/spreadsheets/d/1we3eBBilS-HoAZgtHH3jtmvq4-6lBvVX2yMgxfF48w0/edit?usp=sharing
+
+        test1nullToNB();
+        test2nullToSB();
+        test3deleteNB();
+        test4NBtoNBmoreSpecific();
+        test5NBtoNBexactMatch();
+        test6NBtoNBlessSpecific();
+        test7NBtoSBmoreSpecific();
+        test8NBtoSBexactMatch();
+        test9NBtoSBlessSpecific();
+        test10deleteSBpositive();
+        test11SBpositiveToNBmoreSpecific();
+        test12SBpositiveToNBexactMatch();
+        test13SBtoNBlessSpecific();
+        test14SBpositiveToSBmoreSpecific();
+        test15SBpositiveToSBexactMatch();
+        test16SBpositiveToSBlessSpecific();
+        test17deleteSBnegative();
+        test18SBnegativeToNBmoreSpecific();
+        test19SBnegativeToNBexactMatch();
+        test20SBnegativeToNBlessSpecific();
+        test21SBnegativeToSBmoreSpecific();
+        test22SBnegativeToSBexactMatch();
+        test23SBnegativeToSBlessSpecific();
+
+        testNbSourceDest();
+
+        testSubtree();
+    }
+
+    private void testRepeatedSmr() throws SocketTimeoutException, UnknownHostException {
+        cleanUP();
+        long timeout = ConfigIni.getInstance().getSmrTimeout();
+        ConfigIni.getInstance().setSmrRetryCount(5);
+
+        final InstanceIdType iid = new InstanceIdType(Uint32.ONE);
+        final Eid eid1 = LispAddressUtil.asIpv4Eid("1.1.1.1", 1L);
+        final Eid subscriberEid = LispAddressUtil.asIpv4Eid("2.2.2.2", 1L);
+        final int expectedSmrs1 = 2;
+        final int expectedSmrs2 = 3;
+
+        /* set auth */
+        final Eid eid = LispAddressUtil.asIpv4PrefixBinaryEid("0.0.0.0/0", iid);
+        mapService.addAuthenticationKey(eid, NULL_AUTH_KEY);
+
+        /* add subscribers */
+        final String subscriberSrcRloc1 = "127.0.0.3";
+        final String subscriberSrcRloc2 = "127.0.0.4";
+        final Set<Subscriber> subscriberSet1 = Sets.newHashSet(newSubscriber(subscriberEid, subscriberSrcRloc1),
+                newSubscriber(subscriberEid, subscriberSrcRloc2));
+        mapService.addData(MappingOrigin.Southbound, eid1, SubKeys.SUBSCRIBERS, subscriberSet1);
+
+        final SocketReader reader1 = startSocketReader(subscriberSrcRloc1, 15000);
+        final SocketReader reader2 = startSocketReader(subscriberSrcRloc2, 15000);
+        sleepForSeconds(1);
+
+        /* add mapping */
+        final MappingRecord mapping1 = new MappingRecordBuilder()
+                .setEid(eid1).setTimestamp(System.currentTimeMillis()).setRecordTtl(1440).build();
+        mapService.addMapping(MappingOrigin.Northbound, eid1, null, new MappingData(mapping1));
+
+        sleepForMilliseconds((timeout * expectedSmrs1) - (timeout / 2));
+        final List<MapRequest> requests1 = processSmrPackets(reader1, subscriberSrcRloc1, expectedSmrs1);
+        final MapReply mapReply1 = lms.handleMapRequest(
+                new MapRequestBuilder(requests1.get(0))
+                        .setSourceEid(new SourceEidBuilder().setEid(subscriberEid).build())
+                        .setItrRloc(List.of(new ItrRlocBuilder()
+                                .setRloc(LispAddressUtil.asIpv4Rloc(subscriberSrcRloc1)).build()))
+                        .setEidItem(List.of(new EidItemBuilder().setEid(eid1).build()))
+                        .setSmrInvoked(true)
+                        .setSmr(false).build());
+
+        // sleep to get 1 extra smr request
+        sleepForMilliseconds(timeout * 1);
+        final List<MapRequest> requests2 = processSmrPackets(reader2, subscriberSrcRloc2, expectedSmrs2);
+        final MapReply mapReply2 = lms.handleMapRequest(
+                new MapRequestBuilder(requests2.get(0))
+                        .setSourceEid(new SourceEidBuilder().setEid(subscriberEid).build())
+                        .setItrRloc(List.of(new ItrRlocBuilder()
+                                .setRloc(LispAddressUtil.asIpv4Rloc(subscriberSrcRloc2)).build()))
+                        .setEidItem(List.of(new EidItemBuilder().setEid(eid1).build()))
+                        .setSmrInvoked(true)
+                        .setSmr(false).build());
+
+        sleepForSeconds(3);
+        assertEquals(expectedSmrs1, requests1.size());
+        assertEquals(expectedSmrs2, requests2.size());
+        assertEquals((long) mapReply1.getNonce(), (long) requests1.get(0).getNonce());
+        assertEquals((long) mapReply2.getNonce(), (long) requests2.get(0).getNonce());
+        assertNextBufferEmpty(reader1);
+        assertNextBufferEmpty(reader2);
+
+        reader1.stopReading();
+        reader2.stopReading();
+    }
+
+    private SocketReader startSocketReader(String address, int timeout) {
+        DatagramSocket receivingSocket = null;
+
+        try {
+            receivingSocket = new DatagramSocket(new InetSocketAddress(address, LispMessage.PORT_NUM));
+        } catch (SocketException e) {
+            LOG.error("Can't initialize socket for {}", address, e);
+        }
+        return SocketReader.startReadingInStandaloneThread(receivingSocket, timeout);
+    }
+
+    private List<MapRequest> processSmrPackets(SocketReader reader, String address, int expectedSmrs) {
+        InetAddress inetAddress = null;
+        try {
+            inetAddress = InetAddress.getByName(address);
+        } catch (UnknownHostException e) {
+            LOG.error("Unknown address {}.", address, e);
+        }
+
+        final List<MapRequest> requests = new ArrayList<>();
+        byte[][] buffers = reader.getBuffers(expectedSmrs);
+        for (byte[] buf : buffers) {
+            ByteBuffer packet = ByteBuffer.wrap(buf);
+            if (MappingServiceIntegrationTestUtil.checkType(packet, MessageType.MapRequest)) {
+                MapRequest request = MapRequestSerializer.getInstance().deserialize(packet, inetAddress);
+                requests.add(request);
+            }
+        }
+        return requests;
+    }
+
+    private void assertNextBufferEmpty(SocketReader socketReader) {
+        assertTrue(MultiSiteScenario.areBuffersEmpty(socketReader.getBuffers(1)));
+    }
+
+    private static Subscriber newSubscriber(Eid srcEid, String srcRlocIp) {
+        final int timeout = 5;
+        final Rloc srcRloc = LispAddressUtil.asIpv4Rloc(srcRlocIp);
+        return new Subscriber(srcRloc, srcEid, timeout);
+    }
+
+    private void testMultipleMappings() throws UnknownHostException {
+        final InstanceIdType iid = new InstanceIdType(Uint32.ONE);
+        final String prefix1 = "1.1.127.10/32"; // prefix from the intersection of NB and SB gaps
+        final String prefix2 = "1.1.200.255/32"; // prefix with existing mapping in NB
+        final String prefix3 = "1.3.255.255/32";
+
+        final MapRequest mapRequest = new MapRequestBuilder().setSmrInvoked(false).setEidItem(Lists.newArrayList(
+                new EidItemBuilder()
+                        .setEidItemId(LispAddressStringifier
+                                .getString(LispAddressUtil.asIpv4PrefixBinaryEid(prefix1, iid)))
+                        .setEid(LispAddressUtil.asIpv4PrefixBinaryEid(prefix1, iid))
+                        .build(),
+                new EidItemBuilder()
+                        .setEidItemId(LispAddressStringifier
+                                .getString(LispAddressUtil.asIpv4PrefixBinaryEid(prefix2, iid)))
+                        .setEid(LispAddressUtil.asIpv4PrefixBinaryEid(prefix2, iid))
+                        .build(),
+                new EidItemBuilder()
+                        .setEidItemId(LispAddressStringifier
+                                .getString(LispAddressUtil.asIpv4PrefixBinaryEid(prefix3, iid)))
+                        .setEid(LispAddressUtil.asIpv4PrefixBinaryEid(prefix3, iid))
+                        .build()))
+                .build();
+        final MapReply mapReply = lms.handleMapRequest(mapRequest);
+
+        // expected result
+        final String resultPrefix1 = "1.1.64.0";
+        final Address resultNegMapping1 = new Ipv4PrefixBinaryBuilder()
+                .setIpv4AddressBinary(new Ipv4AddressBinary(InetAddress.getByName(resultPrefix1).getAddress()))
+                .setIpv4MaskLength(Uint8.valueOf(18)).build();
+
+        final String resultPrefix2 = "1.1.128.0";
+        final Address resultMapping2 = new Ipv4PrefixBinaryBuilder()
+                .setIpv4AddressBinary(new Ipv4AddressBinary(InetAddress.getByName(resultPrefix2).getAddress()))
+                .setIpv4MaskLength(Uint8.valueOf(17)).build();
+
+        final String resultPrefix3 = "1.3.0.0";
+        final Address resultNegMapping3 = new Ipv4PrefixBinaryBuilder()
+                .setIpv4AddressBinary(new Ipv4AddressBinary(InetAddress.getByName(resultPrefix3).getAddress()))
+                .setIpv4MaskLength(Uint8.valueOf(16)).build();
+
+        assertEquals(resultNegMapping1, mapReply.getMappingRecordItem().get(0).getMappingRecord().getEid()
+                .getAddress());
+        assertEquals(resultMapping2, mapReply.getMappingRecordItem().get(1).getMappingRecord().getEid()
+                .getAddress());
+        assertEquals(resultNegMapping3, mapReply.getMappingRecordItem().get(2).getMappingRecord().getEid()
+                .getAddress());
+    }
+
+    /**
+     * Tests a negative mapping from an intersection of gaps in northbound and southbound.
+     */
+    private void testGapIntersection() throws UnknownHostException {
+        // request an Eid from a gap between mappings
+        final MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "1.1.127.10/32"));
+
+        // expected negative mapping
+        final Address resultNegMapping = new Ipv4PrefixBinaryBuilder()
+                .setIpv4AddressBinary(new Ipv4AddressBinary(InetAddress.getByName("1.1.64.0").getAddress()))
+                .setIpv4MaskLength(Uint8.valueOf(18)).build();
+        assertEquals(resultNegMapping, mapReply.getMappingRecordItem().get(0).getMappingRecord().getEid()
+                .getAddress());
+    }
+
+    private void testNegativePrefix() {
+        // First, we test with one mapping in NB and one mapping in SB
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        insertNBMappings(1L, "192.0.2.0/24");
+        insertSBMappings(false, 1L, "10.0.0.0/32");
+
+        restartSocket();
+        sleepForSeconds(2);
+
+        MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "11.1.1.1/32"));
+        Eid expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "11.0.0.0/8");
+        assertEquals(expectedNegativePrefix, mapReply.getMappingRecordItem().get(0).getMappingRecord().getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mapReply.getMappingRecordItem().get(0).getMappingRecord()));
+
+        // Second, we test with two mappings in NB only
+        cleanUP();
+
+        insertNBMappings(1L, "192.167.0.0/16", "192.169.0.0/16");
+
+        restartSocket();
+        sleepForSeconds(2);
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        MappingRecord mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+    }
+
+    private void testPositiveMappingRemoval() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        insertNBMappings(1L, "192.167.0.0/16", "192.169.0.0/16");
+        insertSBMappings(false, 1L, "192.168.32.0/19");
+
+        MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/19");
+        MappingRecord mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.64.1/32"));
+        expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.64.0/18");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.128.1/32"));
+        expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.128.0/17");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+
+        MappingServiceIntegrationTestUtil.printMapCacheState(mapService);
+
+        mapService.removeMapping(MappingOrigin.Southbound, LispAddressUtil.asIpv4PrefixBinaryEid(
+                1L, "192.168.32.0/19"));
+
+        MappingServiceIntegrationTestUtil.printMapCacheState(mapService);
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.32.1/32"));
+        expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+
+        MappingServiceIntegrationTestUtil.printMapCacheState(mapService);
+    }
+
+    private void testPositivePrefixOverlappingNegativePrefix_moreSpecific() {
+        cleanUP();
+
+        insertNBMappings(1L, "192.167.0.0/16", "192.169.0.0/16");
+
+        MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        MappingRecord mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+
+        insertNBMappings(1L, "192.168.1.0/24");
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/24");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+    }
+
+    private void testPositivePrefixOverlappingNegativePrefix_lessSpecific() {
+        cleanUP();
+
+        insertNBMappings(1L, "192.167.0.0/16", "192.169.0.0/16");
+
+        MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        MappingRecord mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+
+        insertNBMappings(1L, "192.0.0.0/8");
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedPositivePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.0.0.0/8");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedPositivePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isPositiveMapping(mr));
+    }
+
+    /*
+     * Mapping change: NO old mapping, new mapping is from northbound
+     * Support status: SUPPORTED
+     * Description: If no mappings exists in either NB or SB, that means no subscriptions exist either, so
+     *              this is just a simple case of adding a new mapping, no SMR required.
+     */
+    private void test1nullToNB() {
+        cleanUP();
+
+        insertNBMappings(1L, "192.168.0.0/16");
+        MappingServiceIntegrationTestUtil.assertNoMoreSMRs(socket, mapService);
+    }
+
+    /*
+     * Mapping change: NO old mapping, new mapping is from southbound
+     * Support status: SUPPORTED
+     * Description: If no mappings exists in either NB or SB, that means no subscriptions exist either, so
+     *              this is just a simple case of adding a new mapping, no SMR required.
+     */
+    private void test2nullToSB() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        registerSBMapping(1L, "192.168.0.0/16", "10.10.10.10");
+        MappingServiceIntegrationTestUtil.assertNoMoreSMRs(socket, mapService);
+    }
+
+    /*
+     * Mapping change: deleting a mapping from northbound
+     * Support status: SUPPORTED
+     * Description: When a NB mapping is deleted, its subscribers, and the subscribers of its children are notified.
+     */
+    private void test3deleteNB() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Overlapping SB mapping, which will stay
+        insertSBMappings(false, 1L, "192.168.255.0/24");
+        // Subscribe to the overlapping SB mapping
+        lms.handleMapRequest(newMapRequest(1L, "192.168.255.1/32"));
+        // NB mapping which will be removed
+        insertNBMappings(1L, "192.168.0.0/16");
+        // The child prefix is notified of the change
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.255.0");
+        // The above SMR will result in a SMR-invoked Map-Request for 192.168.255.0/32, which in turn will result  in
+        // subscribing to the new NB mapping
+
+        // Remove NB mapping
+        removeNBMapping(1L, "192.168.0.0/16");
+        // The removed prefix and the child prefix are both notified of the change
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0", "192.168.255.0");
+    }
+
+    /*
+     * Mapping change: adding a more specific northbound mapping overlapping a less specific one
+     * Support status: PARTIALLY SUPPORTED (?)
+     * Description: Overlapping prefixes in general are not "officially" supported in NB and should not be used.
+     *              That said, adding a more specific does result in an SMR, but adding a less specific does not (see
+     *              test 6 below).
+     */
+    private void test4NBtoNBmoreSpecific() {
+        cleanUP();
+
+        // Original (less specific) NB mapping
+        insertNBMappings(1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add the more specific new overlapping mapping
+        insertNBMapping(1L, "192.168.1.0/24", "10.10.10.10");
+        // No notification is sent
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: updating a northbound mapping
+     * Support status: SUPPORTED
+     * Description: Simple case of updating an exact match NB prefix.
+     */
+    private void test5NBtoNBexactMatch() {
+        cleanUP();
+
+        // Original NB mapping
+        insertNBMappings(1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Updated NB mapping with different locator set for the same exact prefix
+        insertNBMapping(1L, "192.168.0.0/16", "10.10.10.10");
+        // Notification is sent for the prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a less specific northbound mapping overlapping a more specific one
+     * Support status: NOT SUPPORTED
+     * Description: Overlapping prefixes in general are not "officially" supported in NB and should not be used.
+     *              That said, adding a more specific does result in an SMR (see test 4 above), but adding a less
+     *              specific does not.
+     */
+    private void test6NBtoNBlessSpecific() {
+        cleanUP();
+
+        // Original (more specific) NB mapping
+        insertNBMappings(1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add the less specific new overlapping mapping
+        insertNBMapping(1L, "192.0.0.0/8", "10.10.10.10");
+        // No notification is sent
+        MappingServiceIntegrationTestUtil.assertNoMoreSMRs(socket, mapService);
+    }
+
+    /*
+     * Mapping change: adding a more specific southbound mapping overlapping a less specific northbound mapping
+     * Support status: SUPPORTED
+     * Description: This is not an issue for NB_FIRST, since there is no change in the resolved mappings for the
+     *              prefix range covered by the existing NB mapping. For NB_AND_SB it does make a difference, and that
+     *              case is supported.
+     */
+    private void test7NBtoSBmoreSpecific() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+        mapService.setLookupPolicy(IMappingService.LookupPolicy.NB_AND_SB);
+
+        // Original (less specific) NB mapping
+        insertNBMapping(1L, "192.168.0.0/16", "172.16.0.1", "10.10.10.10");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add the more specific new overlapping SB mapping
+        registerSBMapping(1L, "192.168.1.0/24", "10.10.10.10");
+        // Notification is sent for the original prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a southbound mapping matching a northbound mapping
+     * Support status: SUPPORTED
+     * Description: When a SB mapping is added that has an existing exact match NB counterpart the subscribers of the
+     *              prefix are notified. This is not strictly necessary for the NB_FIRST policy, but it is still useful
+     *              for the NB_AND_SB policy.
+     */
+    private void test8NBtoSBexactMatch() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+        mapService.setLookupPolicy(IMappingService.LookupPolicy.NB_AND_SB);
+
+        // Original NB mapping
+        insertNBMapping(1L, "192.168.0.0/16", "172.16.0.1", "10.10.10.10");
+        // Subscribe, by sending a Map-Request
+        MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add a mapping with the same EID but different locator set in SB
+        registerSBMapping(1L, "192.168.0.0/16", "10.10.10.10");
+        // Notification is sent for the prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a less specific southbound mapping overlapping a more specific northbound mapping
+     * Support status: PARTIALLY SUPPORTED (?)
+     * Description: When a less specific SB mapping is added no SMR is sent, but for the NB mapping subscribers there
+     *              is no actual change in the mapping. Part of the southbound prefix is not covered by the existing NB,
+     *              and queries for that part will resolve to the full SB prefix, shadowing the NB prefix. This is a
+     *              general problem with overlapping prefixes, but this particular combination is pretty bad.
+     */
+    private void test9NBtoSBlessSpecific() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Original (more specific) NB mapping
+        insertNBMappings(1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add the less specific new overlapping SB mapping
+        registerSBMapping(1L, "192.0.0.0/8", "10.10.10.10");
+        // No notification is sent
+        MappingServiceIntegrationTestUtil.assertNoMoreSMRs(socket, mapService);
+    }
+
+    /*
+     * Mapping change: deleting a positive mapping from southbound
+     * Support status: SUPPORTED
+     * Description: When a positive SB mapping is deleted, its subscribers, and the subscribers of its children are
+     *              notified.
+     */
+    private void test10deleteSBpositive() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Overlapping SB mapping, which will stay
+        insertSBMappings(false, 1L, "192.168.255.0/24");
+        // Subscribe to the overlapping SB mapping
+        lms.handleMapRequest(newMapRequest(1L, "192.168.255.1/32"));
+        // Overlapping negative mapping
+        insertSBMappings(true, 1L, "192.168.127.0/24");
+        // Subscribe to the overlapping negative SB mapping
+        lms.handleMapRequest(newMapRequest(1L, "192.168.127.1/32"));
+        // Positive SB mapping which will be removed
+        insertSBMappings(false, 1L, "192.168.0.0/16");
+        // The child prefix is notified of the change
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.127.0", "192.168.255.0");
+        // The above SMR will result in a SMR-invoked Map-Request for 192.168.255.0/32 and 192.168.255.0/32, which in
+        // turn will result  in subscribing to the new SB mapping
+
+        // Remove positive SB mapping
+        removeSBMapping(1L, "192.168.0.0/16");
+        // The removed prefix and the child prefix are both notified of the change
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0", "192.168.255.0");
+    }
+
+    /*
+     * Mapping change: adding a more specific northbound mapping overlapping a less specific southbound mapping
+     * Support status: PARTIALLY SUPPORTED (?)
+     * Description: This mapping change is detected and an SMR is sent, but the EID prefix in it is for the base address
+     *              of the old prefix. When xTRs query for that, they won't actually install the new mapping. This is
+     *              one of those cases where saving the original request causing the subscription would help the xTR get
+     *              the correct mapping. Additionally, similar to case 9 above, this combination will shadow the NB
+     *              mapping for new requests into the non-overlapping part.
+     */
+    private void test11SBpositiveToNBmoreSpecific() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Original (less specific) SB mapping
+        insertSBMappings(false, 1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add the more specific new overlapping NB mapping
+        insertNBMappings(1L, "192.168.1.0/24");
+        // Notification is sent for the original prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a northbound mapping matching a southbound mapping
+     * Support status: SUPPORTED
+     * Description: When a NB mapping is added that has an existing exact match SB counterpart, the subscribers of the
+     *              prefix are notified.
+     */
+    private void test12SBpositiveToNBexactMatch() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Original SB mapping
+        insertSBMappings(false, 1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add a mapping with the same EID but different locator set in NB
+        insertNBMappings(1L, "192.168.0.0/16");
+        // Notification is sent for the prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a less specific northbound mapping overlapping a more specific southbound mapping
+     * Support status: PARTIALLY SUPPORTED (?)
+     * Description: No SMR is sent, but the NB mapping takes precedence for new requests.
+     */
+    private void test13SBtoNBlessSpecific() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Original (more specific) SB mapping
+        insertNBMappings(1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add the less specific new overlapping SB mapping
+        registerSBMapping(1L, "192.0.0.0/8", "10.10.10.10");
+        // No notification is sent
+        MappingServiceIntegrationTestUtil.assertNoMoreSMRs(socket, mapService);
+    }
+
+    /*
+     * Mapping change: adding a more specific southbound mapping overlapping a less specific one
+     * Support status: SUPPORTED
+     * Description: When a more specific SB mapping is added, the subscribers of the overlapping less specific existing
+     *              SB mapping are notified.
+     */
+    private void test14SBpositiveToSBmoreSpecific() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        insertSBMappings(false, 1L, "192.168.0.0/16");
+
+        MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedPositivePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        MappingRecord mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedPositivePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isPositiveMapping(mr));
+
+        registerSBMapping(1L, "192.168.254.0/24", "10.10.10.10");
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        expectedPositivePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedPositivePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isPositiveMapping(mr));
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.254.1/32"));
+        expectedPositivePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.254.0/24");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedPositivePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isPositiveMapping(mr));
+    }
+
+    /*
+     * Mapping change: updating a southbound mapping
+     * Support status: SUPPORTED
+     * Description: Simple case of updating an exact match SB prefix.
+     */
+    private void test15SBpositiveToSBexactMatch() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Original SB mapping
+        insertSBMappings(false, 1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Updated SB mapping with different locator set for the same exact prefix
+        registerSBMapping(1L, "192.168.0.0/16", "10.10.10.10");
+        // Notification is sent for the prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a less specific southbound mapping overlapping a more specific one
+     * Support status: SUPPORTED
+     * Description: When a less specific SB mapping is added, all child prefixes with subscribers are notified.
+     */
+    private void test16SBpositiveToSBlessSpecific() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Original (more specific) SB mapping
+        insertSBMappings(false, 1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add the less specific new overlapping SB mapping
+        registerSBMapping(1L, "192.0.0.0/8", "10.10.10.10");
+        // Notification is sent for the original prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: deleting a negative mapping from southbound
+     * Support status: SUPPORTED
+     * Description: When a negative SB mapping is deleted, its subscribers are notified.
+     */
+    private void test17deleteSBnegative() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // First we add two negative mappings to NB with a hole between them
+        insertNBMappings(1L, "192.167.0.0/16", "192.169.0.0/16");
+        // We query for the hole, adding a negative SB mapping for 192.168.0.0/16 with a subscriber in the process
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Remove positive SB mapping
+        removeSBMapping(1L, "192.168.0.0/16");
+        // Notification is sent for the prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a more specific northbound mapping overlapping a less specific negative southbound mapping
+     * Support status: SUPPORTED
+     * Description: When a more specific NB mapping is added, the overlapping negative prefix is deleted, its
+     *              subscribers notified, and then more specific negatives are created when requested.
+     */
+    private void test18SBnegativeToNBmoreSpecific() {
+        cleanUP();
+
+        // First we add two negative mappings to NB with a hole between them
+        insertNBMappings(1L, "192.167.0.0/16", "192.169.0.0/16");
+        // We query for the hole, adding a negative SB mapping for 192.168.0.0/16 with a subscriber in the process
+        MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        MappingRecord mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+
+        // Add the more specific new overlapping NB mapping
+        insertNBMappings(1L, "192.168.1.0/24");
+        // Notification is sent for the original prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+
+        // The original negative should now be broken up
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/24");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.64.1/32"));
+        expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.64.0/18");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.1.1/32"));
+        Eid expectedPositivePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.1.0/24");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedPositivePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isPositiveMapping(mr));
+    }
+
+    /*
+     * Mapping change: adding a northbound mapping matching a negative southbound mapping
+     * Support status: SUPPORTED
+     * Description: When a NB mapping is added that has an existing exact match negative SB counterpart,
+     *              the subscribers of the prefix are notified, and the negative is deleted.
+     */
+    private void test19SBnegativeToNBexactMatch() {
+        cleanUP();
+
+        // First we add two negative mappings to NB with a hole between them
+        insertNBMappings(1L, "192.167.0.0/16", "192.169.0.0/16");
+        // We query for the hole, adding a negative SB mapping for 192.168.0.0/16 with a subscriber in the process
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        insertNBMappings(1L, "192.168.0.0/16");
+        // Notification is sent for the prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0", "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a less specific northbound mapping overlapping a more specific negative southbound mapping
+     * Support status: PARTIALLY SUPPORTED (?)
+     * Description: When a less specific NB mapping covering a more specific negative SB mapping is added, the negative
+     *              is deleted and its subscribers notified. Depending on the particular xTR map-cache implementation,
+     *              the negative prefix may or may not stay cached (hence partially supported).
+     */
+    private void test20SBnegativeToNBlessSpecific() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Add a negative mapping
+        insertSBMappings(true, 1L, "192.168.0.0/16");
+        // Subscribe for the mapping
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add less specific northbound mapping
+        insertNBMappings(1L, "192.0.0.0/8");
+        // Notification is sent for the negative prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a more specific southbound mapping overlapping a less specific negative mapping
+     * Support status: SUPPORTED
+     * Description: When a more specific SB mapping is added, the subscribers of the overlapping less specific existing
+     *              negative SB mapping are notified, the negative is deleted, and then more specific negatives are
+     *              created when requested.
+     */
+    private void test21SBnegativeToSBmoreSpecific() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // First we add two negative mappings to NB with a hole between them
+        insertNBMappings(1L, "192.167.0.0/16", "192.169.0.0/16");
+        // We query for the hole, adding a negative SB mapping for 192.168.0.0/16 with a subscriber in the process
+        MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        MappingRecord mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+
+        // Add the more specific new overlapping SB mapping
+        registerSBMapping(1L, "192.168.254.0/24", "10.10.10.10");
+        // Notification is sent for the original prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L,"192.168.0.0");
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/17");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.254.1/32"));
+        Eid expectedPositivePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.254.0/24");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedPositivePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isPositiveMapping(mr));
+    }
+
+    /*
+     * Mapping change: updating a negative southbound mapping with a positive one
+     * Support status: SUPPORTED
+     * Description: Simple case of updating an exact match SB prefix.
+     */
+    private void test22SBnegativeToSBexactMatch() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // First we add two negative mappings to NB with a hole between them
+        insertNBMappings(1L, "192.167.0.0/16", "192.169.0.0/16");
+        // We query for the hole, adding a negative SB mapping for 192.168.0.0/16 with a subscriber in the process
+        MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        MappingRecord mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+        // Updated SB mapping with different locator set for the same exact prefix
+        registerSBMapping(1L, "192.168.0.0/16", "10.10.10.10");
+        // Notification is sent for the prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedPositivePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedPositivePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isPositiveMapping(mr));
+    }
+
+    /*
+     * Mapping change: adding a less specific southbound mapping overlapping a more specific negative mapping
+     * Support status: SUPPORTED
+     * Description: When a less specific SB mapping is added, all child prefixes with subscribers are notified. In this
+     *              case, the overlapping more specific negative is removed.
+     */
+    private void test23SBnegativeToSBlessSpecific() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Add a negative mapping
+        insertSBMappings(true, 1L, "192.168.0.0/16");
+        // Subscribe for the mapping
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add less specific southbound mapping
+        registerSBMapping(1L, "192.0.0.0/8", "10.10.10.10");
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    private void testNbSourceDest() {
+        cleanUP();
+
+        insertNBMappingSourceDest(1L, "192.0.2.0/24", "192.168.0.0/16",
+                MappingServiceIntegrationTestUtil.DEFAULT_IPV4_RLOC_STRING);
+
+        MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedPositivePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        MappingRecord mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedPositivePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isPositiveMapping(mr));
+
+        insertNBMapping(1L, "192.168.0.0/16", "10.10.10.10");
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    private void testSubtree() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        insertSBMappings(false, 1L, "10.0.0.0/8",
+                "10.0.0.0/16", "10.2.0.0/16", "10.255.0.0/16");
+        Eid queryPrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "10.0.0.0/9");
+        Set<Eid> subtreePrefixes = mapService.getSubtree(MappingOrigin.Southbound, queryPrefix);
+        LOG.debug("Subtree prefix set for EID {}: {}", LispAddressStringifier.getString(queryPrefix),
+                LispAddressStringifier.getString(subtreePrefixes));
+        Set<Eid> expectedSubtreePrefixes = new HashSet<>();
+        expectedSubtreePrefixes.add(LispAddressUtil.asIpv4PrefixBinaryEid(1L, "10.0.0.0/16"));
+        expectedSubtreePrefixes.add(LispAddressUtil.asIpv4PrefixBinaryEid(1L, "10.2.0.0/16"));
+        assertEquals(expectedSubtreePrefixes, subtreePrefixes);
+    }
+
+    private void insertMappings() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+        mapService.setLookupPolicy(IMappingService.LookupPolicy.NB_AND_SB);
+
+        insertNBMappings(1L, "1.2.0.0/16", "1.1.128.0/17");
+        insertSBMappings(false, 1L, "1.1.32.0/19", "1.0.0.0/8");
+
+        restartSocket();
+        sleepForSeconds(2);
+    }
+
+    private void insertNBMappings(long iid, String ... prefixes) {
+        LOG.debug("Adding Northbound mappings in VNI {} for prefixes: {}", iid, prefixes);
+        final InstanceIdType iiType = new InstanceIdType(Uint32.valueOf(iid));
+        for (String prefix : prefixes) {
+            MappingRecord record = newMappingRecord(prefix, iiType);
+            mapService.addMapping(MappingOrigin.Northbound, record.getEid(), null, new MappingData(record));
+        }
+        sleepForMilliseconds(100);
+        MappingServiceIntegrationTestUtil.printMapCacheState(mapService);
+    }
+
+    private void removeNBMapping(long iid, String prefix) {
+        LOG.debug("Removing Northbound mapping in VNI {} for prefix {}", iid, prefix);
+        Eid eid = LispAddressUtil.asIpv4PrefixBinaryEid(iid, prefix);
+        mapService.removeMapping(MappingOrigin.Northbound, eid);
+    }
+
+    private void insertNBMapping(long iid, String prefix, String ... locators) {
+        LOG.debug("Adding Northbound mapping in VNI {} for prefix {}, locators {}", iid, prefix, locators);
+        Eid eid = LispAddressUtil.asIpv4PrefixBinaryEid(iid, prefix);
+        List<Rloc> rlocs = new ArrayList<>();
+        for (String locator : locators) {
+            rlocs.add(LispAddressUtil.asIpv4Rloc(locator));
+        }
+        insertNBMapping(eid, rlocs);
+    }
+
+    private void insertNBMappingSourceDest(long iid, String src, String dst, String locator) {
+        String srcAddress = MaskUtil.getPrefixAddress(src);
+        String dstAddress = MaskUtil.getPrefixAddress(dst);
+        int srcMask = Integer.parseInt(MaskUtil.getPrefixMask(src));
+        int dstMask = Integer.parseInt(MaskUtil.getPrefixMask(dst));
+        LOG.debug("Adding Northbound mapping in VNI {} for prefix {}|{}, locator {}", iid, src, dst, locator);
+        Eid eid = LispAddressUtil.asSrcDstEid(srcAddress, dstAddress, srcMask, dstMask, iid);
+        List<Rloc> rlocs = Arrays.asList(LispAddressUtil.asIpv4Rloc(locator));
+        insertNBMapping(eid, rlocs);
+    }
+
+    private void insertNBMapping(Eid eid, List<Rloc> rlocs) {
+        MappingRecord record = MappingServiceIntegrationTestUtil.getDefaultMappingRecordBuilder(eid, rlocs).build();
+        mapService.addMapping(MappingOrigin.Northbound, record.getEid(), null, new MappingData(record));
+        sleepForMilliseconds(100);
+        MappingServiceIntegrationTestUtil.printMapCacheState(mapService);
+    }
+
+    private void allowNullAuthenticationForAllIPv4(long iid) {
+        final InstanceIdType iiType = new InstanceIdType(Uint32.valueOf(iid));
+        Eid allIPs = LispAddressUtil.asIpv4PrefixBinaryEid("0.0.0.0/0", iiType);
+        mapService.addAuthenticationKey(allIPs, NULL_AUTH_KEY);
+    }
+
+    private void insertSBMappings(boolean negative, long iid, String... prefixes) {
+        LOG.debug("Adding Southbound mappings in VNI {} for prefixes: {}", iid, prefixes);
+        final InstanceIdType iiType = new InstanceIdType(Uint32.valueOf(iid));
+
+        for (String prefix : prefixes) {
+            MappingRecord record;
+            if (negative) {
+                record = newMappingRecordNegative(prefix, iiType);
+            } else {
+                record = newMappingRecord(prefix, iiType);
+            }
+            mapService.addMapping(MappingOrigin.Southbound, record.getEid(), null,
+                    new MappingData(record, System.currentTimeMillis()));
+        }
+        MappingServiceIntegrationTestUtil.printMapCacheState(mapService);
+    }
+
+    private void registerSBMapping(long iid, String prefix, String locator) {
+        LOG.debug("Registering Southbound mapping in VNI {} for prefix {}, locator {}" +
+                " via simulated Map-Register a.k.a. handleMapRegister()", iid, prefix, locator);
+
+        Eid eid = LispAddressUtil.asIpv4PrefixBinaryEid(iid, prefix);
+        Rloc rloc = LispAddressUtil.asIpv4Rloc(locator);
+        MapRegister mr = MappingServiceIntegrationTestUtil.getDefaultMapRegisterBuilder(eid, rloc).build();
+        lms.handleMapRegister(mr);
+        sleepForMilliseconds(100);
+        MappingServiceIntegrationTestUtil.printMapCacheState(mapService);
+    }
+
+    private void removeSBMapping(long iid, String prefix) {
+        LOG.debug("Removing Southbound mapping in VNI {} for prefix {}", iid, prefix);
+        Eid eid = LispAddressUtil.asIpv4PrefixBinaryEid(iid, prefix);
+        mapService.removeMapping(MappingOrigin.Southbound, eid);
+    }
+
+    private MappingRecord newMappingRecord(String prefix, InstanceIdType iid) {
+        final Eid prefixBinary = LispAddressUtil.asIpv4PrefixBinaryEid(prefix, iid);
+        return MappingServiceIntegrationTestUtil.getDefaultMappingRecordBuilder(prefixBinary).build();
+    }
+
+    private MappingRecord newMappingRecordNegative(String prefix, InstanceIdType iid) {
+        final Eid prefixBinary = LispAddressUtil.asIpv4PrefixBinaryEid(prefix, iid);
+        return MappingServiceIntegrationTestUtil.getDefaultMappingRecordBuilder(prefixBinary, (List<Rloc>) null)
+                .setAction(Action.NativelyForward).build();
+    }
+
+    private MapRequest newMapRequest(long iid, String prefix) {
+        final Eid prefixBinary = LispAddressUtil.asIpv4PrefixBinaryEid(prefix, new InstanceIdType(Uint32.valueOf(iid)));
+        return MappingServiceIntegrationTestUtil.getDefaultMapRequestBuilder(prefixBinary).build();
+    }
+
     /**
      * TEST SCENARIO A
      */
     public void testMultiSiteScenarioA() throws IOException {
         cleanUP();
+        ConfigIni.getInstance().setSmrRetryCount(1);
+        ConfigIni.getInstance().setSmrTimeout(30000L);
 
         final MultiSiteScenario multiSiteScenario = new MultiSiteScenario(mapService, lms);
         multiSiteScenario.setCommonAuthentication();
@@ -422,107 +1441,118 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         //TEST CASE 1
         multiSiteScenario.storeSouthboundMappings(false, SITE_A, SITE_B, SITE_C, SITE_D4, SITE_D5);
         multiSiteScenario.storeNorthMappingSrcDst(SITE_B, SITE_C);
-        multiSiteScenario.storeNorthMappingNegative(SITE_C, Action.Drop);
-        sleepForSeconds(2);
+        multiSiteScenario.storeNorthMappingNegative(SITE_C_NEGATIVE, Action.Drop);
+        sleepForSeconds(MULTI_SITE_SLEEP_TIME);
         multiSiteScenario.assertPingWorks(SITE_A, 5, SITE_B, 4);
         multiSiteScenario.assertPingWorks(SITE_B, 5, SITE_C, 4);
         multiSiteScenario.assertPingFails(SITE_A, 1, SITE_C, 4);
 
         //TEST CASE 2
-        //following action should trigger generatting of SMR messages:
+        //following action should trigger generating of SMR messages:
         // 1) 192.0.2.5/32
         // 2) 192.0.1.1/32
         multiSiteScenario.storeNorthMappingSrcDst(SITE_A, SITE_C);
-        sleepForSeconds(2);
+        sleepForSeconds(MULTI_SITE_SLEEP_TIME);
         multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_B.getHost(5), SITE_A.getHost(1));
         multiSiteScenario.assertPingWorks(SITE_A, 5, SITE_C, 4);
         multiSiteScenario.assertPingWorks(SITE_B, 5, SITE_C, 4);
         multiSiteScenario.assertPingFails(SITE_D4, 5, SITE_C, 4);
 
         //TEST CASE 3
-        // following action should trigger generatting of SMR messages:
+        // following action should trigger generating of SMR messages:
         // 1) 192.0.2.5/32
         // 2) 192.0.1.1/32
         // 3) 192.0.1.5/32
         // 4) 192.0.4.5/32
         multiSiteScenario.deleteNorthMappingNegative(SITE_C);
-        sleepForSeconds(2);
+        sleepForSeconds(MULTI_SITE_SLEEP_TIME);
         multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_B.getHost(5), SITE_A.getHost(1), SITE_A
                         .getHost(5),
                 SITE_D4.getHost(5));
         multiSiteScenario.assertPingWorks(SITE_D4, 5, SITE_C, 4);
 
         //TEST CASE 4
-        // following action should trigger generatting of SMR messages:
-        // 1) 192.0.4.5/32
+        // following action should trigger generating of SMR messages:
+        // 1) 192.0.2.5/32
+        // 2) 192.0.1.1/32
+        // 3) 192.0.1.5/32
+        // 4) 192.0.4.5/32
         multiSiteScenario.storeNorthMappingSrcDst(SITE_B, SITE_C_RLOC_10);
-        sleepForSeconds(2);
-        multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_D4.getHost(5));
+        sleepForSeconds(MULTI_SITE_SLEEP_TIME);
+        multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_B.getHost(5), SITE_A.getHost(1),
+                SITE_A.getHost(5), SITE_D4.getHost(5));
         //way of testing ping - get RLOC for mapping src-dst and compare it with awaited value doesn't test
         //that ping won't be successfull
         multiSiteScenario.assertPingFails(SITE_B, 5, SITE_C, 4);
 
         //TEST CASE 5
-        // following action should trigger generatting of SMR messages:
-        // 1) 192.0.4.5/32
-        // 2) 192.0.2.5/32
+        // following action should trigger generating of SMR messages:
+        // 1) 192.0.2.5/32
+        // 2) 192.0.1.1/32
+        // 3) 192.0.1.5/32
+        // 4) 192.0.4.5/32
         multiSiteScenario.storeNorthMappingNegative(SITE_C, Action.Drop);
-        sleepForSeconds(2);
-        multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_D4.getHost(5), SITE_B.getHost(5));
+        sleepForSeconds(MULTI_SITE_SLEEP_TIME);
+        multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_B.getHost(5), SITE_A.getHost(1),
+                SITE_A.getHost(5), SITE_D4.getHost(5));
         multiSiteScenario.assertPingFails(SITE_D4, 5, SITE_C, 4);
 
         //TEST CASE 6
         multiSiteScenario.assertPingFails(SITE_D5, 5, SITE_C, 3);
 
         //TEST CASE 7
-        multiSiteScenario.deleteNorthMapingSrcDst(SITE_A, SITE_C);
-        sleepForSeconds(2);
-        // following action should trigger generatting of SMR messages:
+        // following action should trigger generating of SMR messages:
         // 1) 192.0.4.5/32
         // 2) 192.0.2.5/32
         // 3) 192.0.5.5/32
+        // 4) 192.0.1.5/32
+        // 5) 192.0.1.1/32
+        multiSiteScenario.deleteNorthMapingSrcDst(SITE_A, SITE_C);
+        sleepForSeconds(MULTI_SITE_SLEEP_TIME);
         multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_D5.getHost(5), SITE_D4.getHost(5),
-                SITE_B.getHost(5));
+                SITE_B.getHost(5), SITE_A.getHost(1), SITE_A.getHost(5));
 
-        // following action should trigger generatting of SMR messages:
+        // following action should trigger generating of SMR messages:
         // 1) 192.0.4.5/32
         // 2) 192.0.2.5/32
         // 3) 192.0.5.5/32
+        // 4) 192.0.1.5/32
+        // 5) 192.0.1.1/32
         multiSiteScenario.storeNorthMappingSrcDst(SITE_B, SITE_C);
-        sleepForSeconds(2);
+        sleepForSeconds(MULTI_SITE_SLEEP_TIME);
         multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_D5.getHost(5), SITE_D4.getHost(5),
-                SITE_B.getHost(5));
+                SITE_B.getHost(5), SITE_A.getHost(1), SITE_A.getHost(5));
 
         multiSiteScenario.assertPingWorks(SITE_A, 5, SITE_B, 4);
         multiSiteScenario.assertPingWorks(SITE_B, 5, SITE_C, 4);
         multiSiteScenario.assertPingFails(SITE_A, 1, SITE_C, 4);
 
         //TEST CASE 8
-        // following action should trigger generatting of SMR messages:
+        // following action should trigger generating of SMR messages:
         // 1) 192.0.4.5/32
         // 2) 192.0.2.5/32
         // 3) 192.0.5.5/32
-        // 4) 192.0.1.1/32
+        // 4) 192.0.1.5/32
+        // 5) 192.0.1.1/32
         multiSiteScenario.deleteNorthMapingSrcDst(SITE_B, SITE_C);
-        sleepForSeconds(2);
+        sleepForSeconds(MULTI_SITE_SLEEP_TIME);
         multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_D5.getHost(5), SITE_D4.getHost(5),
-                SITE_B.getHost(5),
-                SITE_A.getHost(1));
+                SITE_B.getHost(5), SITE_A.getHost(1), SITE_A.getHost(5));
         multiSiteScenario.assertPingWorks(SITE_A, 5, SITE_B, 4);
         multiSiteScenario.assertPingFails(SITE_B, 5, SITE_C, 4);
         multiSiteScenario.assertPingFails(SITE_A, 1, SITE_C, 4);
 
         //TEST CASE 9
-        // following action should trigger generatting of SMR messages:
+        // following action should trigger generating of SMR messages:
         // 1) 192.0.4.5/32
         // 2) 192.0.2.5/32
         // 3) 192.0.5.5/32
-        // 4) 192.0.1.1/32
+        // 4) 192.0.1.5/32
+        // 5) 192.0.1.1/32
         multiSiteScenario.deleteNorthMappingNegative(SITE_C);
-        sleepForSeconds(2);
+        sleepForSeconds(MULTI_SITE_SLEEP_TIME);
         multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_D5.getHost(5), SITE_D4.getHost(5),
-                SITE_B.getHost(5),
-                SITE_A.getHost(1));
+                SITE_B.getHost(5), SITE_A.getHost(1), SITE_A.getHost(5));
         multiSiteScenario.assertPingWorks(SITE_A, 5, SITE_B, 4);
         multiSiteScenario.assertPingWorks(SITE_B, 5, SITE_C, 4);
         multiSiteScenario.assertPingWorks(SITE_A, 5, SITE_C, 4);
@@ -535,6 +1565,7 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
      * TEST SCENARIO B
      */
     public void testMultiSiteScenarioB() throws IOException {
+        restartSocket();
         cleanUP();
 
         final MultiSiteScenario multiSiteScenario = new MultiSiteScenario(mapService, lms);
@@ -544,7 +1575,7 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         final SocketReader socketReader = SocketReader.startReadingInStandaloneThread(socket);
 
         mapService.setLookupPolicy(IMappingService.LookupPolicy.NB_AND_SB);
-        mapService.setMappingOverwrite(false);
+        mapService.setMappingMerge(true);
 
         //TEST CASE 1
         multiSiteScenario.storeSouthboundMappings(true, SITE_A_SB, SITE_B_SB, SITE_C_WP_100_1_SB, SITE_D_WP_100_1_SB,
@@ -552,23 +1583,23 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         multiSiteScenario.storeNorthMappingIpPrefix(SITE_A_SB);
         multiSiteScenario.storeNorthMappingIpPrefix(SITE_B_SB);
         multiSiteScenario.storeNorthMappingIpPrefix(SITE_C_WP_50_2_SB, SITE_D_WP_50_2_SB);
-        sleepForSeconds(2);
+        sleepForSeconds(MULTI_SITE_SLEEP_TIME);
         multiSiteScenario.assertPingWorks(SITE_A_SB, 5, SITE_C_WP_50_2_SB, 4, SITE_D_WP_50_2_SB);
         multiSiteScenario.assertPingWorks(SITE_B_SB, 5, SITE_C_WP_50_2_SB, 4, SITE_D_WP_50_2_SB);
 
         //TEST CASE 2
-        // following action should trigger generatting of SMR messages:
+        // following action should trigger generating of SMR messages:
         // 1) 192.0.2.5/32
         // 2) 192.0.1.5/32
         multiSiteScenario.storeNorthMappingSrcDst(SITE_A_SB, SITE_C_WP_50_2_SB, SITE_D_WP_50_2_SB);
-        sleepForSeconds(2);
+        sleepForSeconds(MULTI_SITE_SLEEP_TIME);
         multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_B_SB.getHost(5), SITE_A_SB.getHost(5));
 
-        // following action should trigger generatting of SMR messages:
+        // following action should trigger generating of SMR messages:
         // 1) 192.0.2.5/32
         // 2) 192.0.1.5/32
         multiSiteScenario.storeNorthMappingNegative(SITE_C_SB, Action.Drop);
-        sleepForSeconds(2);
+        sleepForSeconds(MULTI_SITE_SLEEP_TIME);
         multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_B_SB.getHost(5), SITE_A_SB.getHost(5));
 
         multiSiteScenario.assertPingWorks(SITE_A_SB, 5, SITE_C_WP_50_2_SB, 4, SITE_D_WP_50_2_SB);
@@ -576,18 +1607,18 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
 
 
         //TEST CASE 3
-        // following action should trigger generatting of SMR messages:
+        // following action should trigger generating of SMR messages:
         // 1) 192.0.2.5/32
         // 2) 192.0.1.5/32
         multiSiteScenario.storeNorthMappingSrcDst(SITE_A_SB, SITE_C_WP_50_2_SB);
-        sleepForSeconds(2);
+        sleepForSeconds(MULTI_SITE_SLEEP_TIME);
         multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_B_SB.getHost(5), SITE_A_SB.getHost(5));
         multiSiteScenario.assertPingWorks(SITE_A_SB, 5, SITE_C_WP_50_2_SB, 4);
 
         //TEST CASE 4
         multiSiteScenario.storeNorthMappingSrcDst(SITE_B_SB, SITE_C_WP_50_2_SB, SITE_D_WP_50_2_SB);
-        sleepForSeconds(2);
-        // following action should trigger generatting of SMR messages:
+        sleepForSeconds(MULTI_SITE_SLEEP_TIME);
+        // following action should trigger generating of SMR messages:
         // 1) 192.0.2.5/32
         // 2) 192.0.1.5/32
         multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_B_SB.getHost(5), SITE_A_SB.getHost(5));
@@ -595,24 +1626,24 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
 
         //TEST CASE 5
         multiSiteScenario.deleteSouthboundMappings(SITE_D_DELETE_SB);
-        sleepForSeconds(2);
-        // following action should trigger generatting of SMR messages:
+        sleepForSeconds(MULTI_SITE_SLEEP_TIME);
+        // following action should trigger generating of SMR messages:
         // 1) 192.0.2.5/32
         // 2) 192.0.1.5/32
-        multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_B_SB.getHost(5), SITE_A_SB.getHost(5));
+        //multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_B_SB.getHost(5), SITE_A_SB.getHost(5));
 
         multiSiteScenario.assertPingWorks(SITE_B_SB, 5, SITE_C_WP_50_2_SB, 4);
 
         //TEST CASE 6
         multiSiteScenario.deleteNorthMapingSrcDst(SITE_A_SB, SITE_C_WP_50_2_SB);
-        sleepForSeconds(2);
-        // following action should trigger generatting of SMR messages:
+        sleepForSeconds(MULTI_SITE_SLEEP_TIME);
+        // following action should trigger generating of SMR messages:
         // 1) 192.0.2.5/32
         // 2) 192.0.1.5/32
         multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_B_SB.getHost(5), SITE_A_SB.getHost(5));
 
         multiSiteScenario.deleteNorthMapingSrcDst(SITE_B_SB, SITE_C_WP_50_2_SB);
-        sleepForSeconds(2);
+        sleepForSeconds(MULTI_SITE_SLEEP_TIME);
         multiSiteScenario.assertPingFails(SITE_B_SB, 5, SITE_C_WP_50_2_SB, 4);
 
         socketReader.stopReading();
@@ -629,13 +1660,12 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         if (socket != null) {
             socket.close();
         }
-        socket = initSocket(socket, 56756);
+        socket = MappingServiceIntegrationTestUtil.initSocket(56756);
 
         sendPacket(mapRequestPacket);
-        ByteBuffer readBuf = ByteBuffer.wrap(receivePacket().getData());
-        MapReply reply = MapReplySerializer.getInstance().deserialize(readBuf);
+        MapReply reply = receiveMapReply();
         assertEquals(4435248268955932168L, reply.getNonce().longValue());
-
+        restartSocket();
     }
 
     public void mapRegisterWithMapNotify() throws SocketTimeoutException {
@@ -655,8 +1685,8 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         MapReply mapReply = registerAddressAndQuery(eid);
 
         assertEquals(4, mapReply.getNonce().longValue());
-        assertEquals(locatorEid, mapReply.getMappingRecordItem().get(0).getMappingRecord().getLocatorRecord().get(0)
-                .getRloc());
+        assertEquals(MappingServiceIntegrationTestUtil.DEFAULT_IPV4_RLOC,
+                mapReply.getMappingRecordItem().get(0).getMappingRecord().getLocatorRecord().get(0).getRloc());
 
     }
 
@@ -668,7 +1698,7 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
 
         assertTrue(true);
         Eid addressFromNetwork = reply.getMappingRecordItem().get(0).getMappingRecord().getEid();
-        assertEquals(MacAfi.class, addressFromNetwork.getAddressType());
+        assertEquals(MacAfi.VALUE, addressFromNetwork.getAddressType());
         String macAddressFromReply = ((Mac) addressFromNetwork.getAddress()).getMac().getValue();
 
         assertEquals(macAddress, macAddressFromReply);
@@ -680,40 +1710,21 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         mapService.addAuthenticationKey(eid, NULL_AUTH_KEY);
         sleepForSeconds(1);
 
-        MapRequestBuilder mapRequestBuilder = new MapRequestBuilder();
-        mapRequestBuilder.setNonce((long) 4);
-        mapRequestBuilder.setSourceEid(new SourceEidBuilder().setEid(LispAddressUtil.getNoAddressEid()).build());
-        mapRequestBuilder.setEidItem(new ArrayList<EidItem>());
-        mapRequestBuilder.getEidItem().add(new EidItemBuilder().setEid(eid).build());
-        mapRequestBuilder.setItrRloc(new ArrayList<ItrRloc>());
-        mapRequestBuilder.getItrRloc().add(
-                new ItrRlocBuilder().setRloc(LispAddressUtil.asIpv4Rloc(ourAddress)).build());
-        sendMapRequest(mapRequestBuilder.build());
+        MapRequest mapRequest = MappingServiceIntegrationTestUtil.getDefaultMapRequestBuilder(eid).build();
+        sendMapRequest(mapRequest);
         MapReply mapReply = receiveMapReply();
         assertEquals(4, mapReply.getNonce().longValue());
-        assertEquals(0, mapReply.getMappingRecordItem().get(0).getMappingRecord().getLocatorRecord().size());
-        MapRegisterBuilder mapRegisterbuilder = new MapRegisterBuilder();
-        mapRegisterbuilder.setWantMapNotify(true);
-        mapRegisterbuilder.setNonce((long) 8);
-        MappingRecordBuilder etlrBuilder = new MappingRecordBuilder();
-        etlrBuilder.setEid(eid);
-        etlrBuilder.setRecordTtl(254);
-        LocatorRecordBuilder recordBuilder = new LocatorRecordBuilder();
-        recordBuilder.setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1"));
-        etlrBuilder.setLocatorRecord(new ArrayList<LocatorRecord>());
-        etlrBuilder.getLocatorRecord().add(recordBuilder.build());
-        mapRegisterbuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
-        mapRegisterbuilder.getMappingRecordItem().add(
-                new MappingRecordItemBuilder().setMappingRecord(etlrBuilder.build()).build());
-        sendMapRegister(mapRegisterbuilder.build());
+        assertEquals(0, mapReply.getMappingRecordItem().get(0).getMappingRecord().nonnullLocatorRecord().size());
+        MapRegister mapRegister = MappingServiceIntegrationTestUtil.getDefaultMapRegisterBuilder(eid).build();
+        sendMapRegister(mapRegister);
         MapNotify mapNotify = receiveMapNotify();
         assertEquals(8, mapNotify.getNonce().longValue());
         sleepForSeconds(1);
-        sendMapRequest(mapRequestBuilder.build());
+        sendMapRequest(mapRequest);
         mapReply = receiveMapReply();
         assertEquals(4, mapReply.getNonce().longValue());
-        assertEquals(recordBuilder.getRloc(), mapReply.getMappingRecordItem().get(0).getMappingRecord()
-                .getLocatorRecord().get(0).getRloc());
+        assertEquals(MappingServiceIntegrationTestUtil.DEFAULT_IPV4_RLOC,
+                mapReply.getMappingRecordItem().get(0).getMappingRecord().getLocatorRecord().get(0).getRloc());
 
     }
 
@@ -747,7 +1758,7 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
 
     public void testMapRegisterOverwritesNoSubkey() throws SocketTimeoutException {
         cleanUP();
-        mapService.setMappingOverwrite(true);
+        mapService.setMappingMerge(false);
         Eid eid = LispAddressUtil.asIpv4PrefixBinaryEid("1.2.3.4/32");
         Rloc rloc1Value = LispAddressUtil.asIpv4Rloc("4.3.2.1");
         Rloc rloc2Value = LispAddressUtil.asIpv4Rloc("4.3.2.2");
@@ -759,7 +1770,7 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
 
     public void testMapRegisterDoesntOverwritesNoSubkey() throws SocketTimeoutException {
         cleanUP();
-        mapService.setMappingOverwrite(false);
+        mapService.setMappingMerge(true);
         Eid eid = LispAddressUtil.asIpv4PrefixBinaryEid("1.2.3.4/32");
         Rloc rloc1Value = LispAddressUtil.asIpv4Rloc("4.3.2.1");
         Rloc rloc2Value = LispAddressUtil.asIpv4Rloc("4.3.2.2");
@@ -830,9 +1841,8 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         mapRegisterPacketWithoutNotify[mapRegisterPacketWithoutNotify.length - 1] += 1;
         sendPacket(mapRegisterPacketWithoutNotify);
 
-        ByteBuffer readBuf = ByteBuffer.wrap(receivePacket().getData());
-        MapRequest smr = MapRequestSerializer.getInstance().deserialize(readBuf);
-        assertTrue(smr.isSmr());
+        MapRequest smr = receiveMapRequest();
+        assertTrue(smr.getSmr());
         Eid sourceEid = smr.getSourceEid().getEid();
         assertTrue(LispAddressUtil.asIpv4Eid("153.16.254.1").equals(sourceEid));
         Eid smrEid = smr.getEidItem().get(0).getEid();
@@ -1262,18 +2272,21 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         etlr.setEid(registerEID);
         etlr.setRecordTtl(254);
         LocatorRecordBuilder record = new LocatorRecordBuilder();
+        record.setLocatorId("4.3.2.1");
         record.setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1"));
         record.setLocalLocator(false);
         record.setRlocProbed(false);
         record.setRouted(true);
-        record.setMulticastPriority((short) 0);
-        record.setMulticastWeight((short) 0);
-        record.setPriority((short) 0);
-        record.setWeight((short) 0);
+        record.setMulticastPriority(Uint8.valueOf(0));
+        record.setMulticastWeight(Uint8.valueOf(0));
+        record.setPriority(Uint8.valueOf(0));
+        record.setWeight(Uint8.valueOf(0));
         etlr.setLocatorRecord(new ArrayList<LocatorRecord>());
         etlr.getLocatorRecord().add(record.build());
         mapRegister.setMappingRecordItem(new ArrayList<MappingRecordItem>());
-        mapRegister.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(etlr.build()).build());
+        mapRegister.getMappingRecordItem().add(new MappingRecordItemBuilder()
+                .setMappingRecordItemId(LispAddressStringifier.getString(registerEID))
+                .setMappingRecord(etlr.build()).build());
         sendMapRegister(mapRegister.build());
         MapNotify mapNotify = receiveMapNotify();
         assertEquals(8, mapNotify.getNonce().longValue());
@@ -1288,20 +2301,25 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         mapRequest.setProbe(false);
         mapRequest.setSmr(false);
         mapRequest.setSmrInvoked(false);
-        mapRequest.getEidItem().add(new EidItemBuilder().setEid(matchedAddress).build());
+        mapRequest.getEidItem().add(new EidItemBuilder()
+                .setEidItemId(LispAddressStringifier.getString(matchedAddress))
+                .setEid(matchedAddress).build());
         mapRequest.setItrRloc(new ArrayList<ItrRloc>());
-        mapRequest.getItrRloc().add(
-                new ItrRlocBuilder().setRloc(LispAddressUtil.asIpv4Rloc(ourAddress)).build());
+        mapRequest.getItrRloc().add(new ItrRlocBuilder()
+                .setItrRlocId(ourAddress)
+                .setRloc(LispAddressUtil.asIpv4Rloc(ourAddress)).build());
         sendMapRequest(mapRequest.build());
         MapReply mapReply = receiveMapReply();
         assertEquals(4, mapReply.getNonce().longValue());
         assertEquals(record.getRloc(), mapReply.getMappingRecordItem().get(0).getMappingRecord().getLocatorRecord()
                 .get(0).getRloc());
         mapRequest.setEidItem(new ArrayList<EidItem>());
-        mapRequest.getEidItem().add(new EidItemBuilder().setEid(unMatchedAddress).build());
+        mapRequest.getEidItem().add(new EidItemBuilder()
+                .setEidItemId(LispAddressStringifier.getString(unMatchedAddress))
+                .setEid(unMatchedAddress).build());
         sendMapRequest(mapRequest.build());
         mapReply = receiveMapReply();
-        assertEquals(0, mapReply.getMappingRecordItem().get(0).getMappingRecord().getLocatorRecord().size());
+        assertEquals(0, mapReply.getMappingRecordItem().get(0).getMappingRecord().nonnullLocatorRecord().size());
     }
 /*
     // This registers an IP with a MapRegister, then adds a password via the
@@ -1410,33 +2428,8 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
     private void registerAddress(Eid eid) throws SocketTimeoutException {
         mapService.addAuthenticationKey(eid, NULL_AUTH_KEY);
         sleepForSeconds(1);
-        MapRegisterBuilder mapRegisterBuilder = new MapRegisterBuilder();
-        mapRegisterBuilder.setWantMapNotify(true);
-        mapRegisterBuilder.setKeyId((short) 0);
-        mapRegisterBuilder.setAuthenticationData(new byte[0]);
-        mapRegisterBuilder.setNonce((long) 8);
-        mapRegisterBuilder.setProxyMapReply(false);
-        MappingRecordBuilder etlrBuilder = new MappingRecordBuilder();
-        etlrBuilder.setEid(eid);
-        etlrBuilder.setRecordTtl(254);
-        etlrBuilder.setAction(Action.NoAction);
-        etlrBuilder.setAuthoritative(false);
-        etlrBuilder.setMapVersion((short) 0);
-        LocatorRecordBuilder recordBuilder = new LocatorRecordBuilder();
-        recordBuilder.setLocalLocator(false);
-        recordBuilder.setRlocProbed(false);
-        recordBuilder.setRouted(true);
-        recordBuilder.setMulticastPriority((short) 0);
-        recordBuilder.setMulticastWeight((short) 0);
-        recordBuilder.setPriority((short) 0);
-        recordBuilder.setWeight((short) 0);
-        recordBuilder.setRloc(locatorEid);
-        etlrBuilder.setLocatorRecord(new ArrayList<LocatorRecord>());
-        etlrBuilder.getLocatorRecord().add(recordBuilder.build());
-        mapRegisterBuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
-        mapRegisterBuilder.getMappingRecordItem().add(
-                new MappingRecordItemBuilder().setMappingRecord(etlrBuilder.build()).build());
-        sendMapRegister(mapRegisterBuilder.build());
+        MapRegister mapRegister = MappingServiceIntegrationTestUtil.getDefaultMapRegisterBuilder(eid).build();
+        sendMapRegister(mapRegister);
         MapNotify mapNotify = receiveMapNotify();
         assertEquals(8, mapNotify.getNonce().longValue());
     }
@@ -1445,7 +2438,9 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         MapRequestBuilder mapRequestBuilder = new MapRequestBuilder();
         mapRequestBuilder.setNonce((long) 4);
         mapRequestBuilder.setEidItem(new ArrayList<EidItem>());
-        mapRequestBuilder.getEidItem().add(new EidItemBuilder().setEid(eid).build());
+        mapRequestBuilder.getEidItem().add(new EidItemBuilder()
+                .setEidItemId(LispAddressStringifier.getString(eid))
+                .setEid(eid).build());
         mapRequestBuilder.setItrRloc(new ArrayList<ItrRloc>());
         if (srcEid != null) {
             mapRequestBuilder.setSourceEid(new SourceEidBuilder().setEid(LispAddressUtil.asIpv4Eid(srcEid)).build());
@@ -1454,7 +2449,9 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
                     .build());
         }
         mapRequestBuilder.getItrRloc().add(
-                new ItrRlocBuilder().setRloc(LispAddressUtil.asIpv4Rloc(ourAddress)).build());
+                new ItrRlocBuilder()
+                        .setItrRlocId(ourAddress)
+                        .setRloc(LispAddressUtil.asIpv4Rloc(ourAddress)).build());
         mapRequestBuilder.setAuthoritative(false);
         mapRequestBuilder.setMapDataPresent(false);
         mapRequestBuilder.setPitr(false);
@@ -1470,52 +2467,16 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
     private MapReply registerAddressAndQuery(Eid eid) throws SocketTimeoutException {
         mapService.addAuthenticationKey(eid, NULL_AUTH_KEY);
         sleepForSeconds(1);
-        MapRegisterBuilder mapRegisterBuilder = new MapRegisterBuilder();
-        mapRegisterBuilder.setWantMapNotify(true);
-        mapRegisterBuilder.setKeyId((short) 0);
-        mapRegisterBuilder.setAuthenticationData(new byte[0]);
-        mapRegisterBuilder.setNonce((long) 8);
-        mapRegisterBuilder.setProxyMapReply(false);
-        MappingRecordBuilder etlrBuilder = new MappingRecordBuilder();
-        etlrBuilder.setEid(eid);
-        etlrBuilder.setRecordTtl(254);
-        etlrBuilder.setAction(Action.NoAction);
-        etlrBuilder.setAuthoritative(false);
-        etlrBuilder.setMapVersion((short) 0);
-        LocatorRecordBuilder recordBuilder = new LocatorRecordBuilder();
-        recordBuilder.setLocalLocator(false);
-        recordBuilder.setRlocProbed(false);
-        recordBuilder.setRouted(true);
-        recordBuilder.setMulticastPriority((short) 0);
-        recordBuilder.setMulticastWeight((short) 0);
-        recordBuilder.setPriority((short) 0);
-        recordBuilder.setWeight((short) 0);
-        recordBuilder.setRloc(locatorEid);
-        etlrBuilder.setLocatorRecord(new ArrayList<LocatorRecord>());
-        etlrBuilder.getLocatorRecord().add(recordBuilder.build());
-        mapRegisterBuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
-        mapRegisterBuilder.getMappingRecordItem().add(new MappingRecordItemBuilder().setMappingRecord(
-                etlrBuilder.build()).build());
-        sendMapRegister(mapRegisterBuilder.build());
+        MapRegister mapRegister = MappingServiceIntegrationTestUtil.getDefaultMapRegisterBuilder(eid).build();
+        LOG.trace("Sending Map-Register via socket: {}", mapRegister);
+        sendMapRegister(mapRegister);
         MapNotify mapNotify = receiveMapNotify();
+        LOG.trace("Received Map-Notify via socket: {}", mapNotify);
         assertEquals(8, mapNotify.getNonce().longValue());
         // wait for the notifications to propagate
         sleepForSeconds(1);
-        MapRequestBuilder mapRequestBuilder = new MapRequestBuilder();
-        mapRequestBuilder.setNonce((long) 4);
-        mapRequestBuilder.setEidItem(new ArrayList<EidItem>());
-        mapRequestBuilder.getEidItem().add(new EidItemBuilder().setEid(eid).build());
-        mapRequestBuilder.setItrRloc(new ArrayList<ItrRloc>());
-        mapRequestBuilder.setSourceEid(new SourceEidBuilder().setEid(LispAddressUtil.asIpv4Eid(ourAddress)).build());
-        mapRequestBuilder.getItrRloc().add(
-                new ItrRlocBuilder().setRloc(LispAddressUtil.asIpv4Rloc(ourAddress)).build());
-        mapRequestBuilder.setAuthoritative(false);
-        mapRequestBuilder.setMapDataPresent(false);
-        mapRequestBuilder.setPitr(false);
-        mapRequestBuilder.setProbe(false);
-        mapRequestBuilder.setSmr(false);
-        mapRequestBuilder.setSmrInvoked(false);
-        sendMapRequest(mapRequestBuilder.build());
+        MapRequest mapRequest = MappingServiceIntegrationTestUtil.getDefaultMapRequestBuilder(eid).build();
+        sendMapRequest(mapRequest);
         return receiveMapReply();
     }
 
@@ -1528,11 +2489,11 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
 
         SourceDestKeyBuilder builder = new SourceDestKeyBuilder();
         builder.setSource(new SimpleAddress(new IpPrefix(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
-                .ietf.inet.types.rev100924.Ipv4Prefix(ipPrefix))));
+                .ietf.inet.types.rev130715.Ipv4Prefix(ipPrefix))));
         builder.setDest(new SimpleAddress(new MacAddress(macString)));
 
         EidBuilder eb = new EidBuilder();
-        eb.setAddressType(SourceDestKeyLcaf.class);
+        eb.setAddressType(SourceDestKeyLcaf.VALUE);
         eb.setVirtualNetworkId(null);
         eb.setAddress(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105
                 .lisp.address.address.SourceDestKeyBuilder().setSourceDestKey(builder.build()).build());
@@ -1540,7 +2501,7 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         MapReply reply = registerAddressAndQuery(eb.build());
 
         Eid fromNetwork = reply.getMappingRecordItem().get(0).getMappingRecord().getEid();
-        assertEquals(SourceDestKeyLcaf.class, fromNetwork.getAddressType());
+        assertEquals(SourceDestKeyLcaf.VALUE, fromNetwork.getAddressType());
         SourceDestKey sourceDestFromNetwork = (SourceDestKey) fromNetwork.getAddress();
 
         SimpleAddress receivedAddr1 = sourceDestFromNetwork.getSourceDestKey().getSource();
@@ -1571,7 +2532,7 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         MapReply reply = queryForAddress(srcDst, null);
 
         Eid fromNetwork = reply.getMappingRecordItem().get(0).getMappingRecord().getEid();
-        assertEquals(SourceDestKeyLcaf.class, fromNetwork.getAddressType());
+        assertEquals(SourceDestKeyLcaf.VALUE, fromNetwork.getAddressType());
         SourceDestKey sourceDestFromNetwork = (SourceDestKey) fromNetwork.getAddress();
 
         IpPrefix receivedAddr1 = sourceDestFromNetwork.getSourceDestKey().getSource().getIpPrefix();
@@ -1586,14 +2547,14 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         // srcEid/dstEid match
         reply = queryForAddress(LispAddressUtil.asIpv4PrefixBinaryEid("20.20.20.1/32"), "10.10.10.1");
         fromNetwork = reply.getMappingRecordItem().get(0).getMappingRecord().getEid();
-        assertEquals(Ipv4PrefixBinaryAfi.class, fromNetwork.getAddressType());
+        assertEquals(Ipv4PrefixBinaryAfi.VALUE, fromNetwork.getAddressType());
 
         assertEquals(LispAddressUtil.asIpv4PrefixBinaryEid(ipPrefix2), fromNetwork);
 
         // dstEid match only
         reply = queryForAddress(LispAddressUtil.asIpv4PrefixBinaryEid("20.20.20.1/32"), "1.2.3.4");
         fromNetwork = reply.getMappingRecordItem().get(0).getMappingRecord().getEid();
-        assertEquals(Ipv4PrefixBinaryAfi.class, fromNetwork.getAddressType());
+        assertEquals(Ipv4PrefixBinaryAfi.VALUE, fromNetwork.getAddressType());
 
         assertEquals(LispAddressUtil.asIpv4PrefixBinaryEid(ipPrefix2), fromNetwork);
     }
@@ -1609,7 +2570,7 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         MapReply reply = registerAddressAndQuery(kv);
 
         Eid fromNetwork = reply.getMappingRecordItem().get(0).getMappingRecord().getEid();
-        assertEquals(KeyValueAddressLcaf.class, fromNetwork.getAddressType());
+        assertEquals(KeyValueAddressLcaf.VALUE, fromNetwork.getAddressType());
         KeyValueAddress keyValueFromNetwork = (KeyValueAddress) fromNetwork.getAddress();
 
         SimpleAddress receivedAddr1 = keyValueFromNetwork.getKeyValueAddress().getKey();
@@ -1629,14 +2590,13 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         cleanUP();
         String macString = "01:02:03:04:05:06";
         String ipString = "10.20.255.30";
-        List<SimpleAddress> addresses = new ArrayList<SimpleAddress>();
-        addresses.add(new SimpleAddress(new IpAddress(new Ipv4Address(ipString))));
-        addresses.add(new SimpleAddress(new MacAddress(macString)));
         AfiListBuilder listbuilder = new AfiListBuilder();
-        listbuilder.setAddressList(addresses);
+        listbuilder.setAddressList(ImmutableSet.of(
+                new SimpleAddress(new IpAddress(new Ipv4Address(ipString))),
+                new SimpleAddress(new MacAddress(macString))));
 
         EidBuilder eb = new EidBuilder();
-        eb.setAddressType(AfiListLcaf.class);
+        eb.setAddressType(AfiListLcaf.VALUE);
         eb.setVirtualNetworkId(null);
         eb.setAddress(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105
                 .lisp.address.address.AfiListBuilder().setAfiList(listbuilder.build()).build());
@@ -1645,11 +2605,12 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
 
         Eid receivedAddress = reply.getMappingRecordItem().get(0).getMappingRecord().getEid();
 
-        assertEquals(AfiListLcaf.class, receivedAddress.getAddressType());
+        assertEquals(AfiListLcaf.VALUE, receivedAddress.getAddressType());
 
         AfiList listAddrFromNetwork = (AfiList) receivedAddress.getAddress();
-        SimpleAddress receivedAddr1 = (SimpleAddress) listAddrFromNetwork.getAfiList().getAddressList().get(0);
-        SimpleAddress receivedAddr2 = (SimpleAddress) listAddrFromNetwork.getAfiList().getAddressList().get(1);
+        Iterator<SimpleAddress> addrList = listAddrFromNetwork.getAfiList().getAddressList().iterator();
+        SimpleAddress receivedAddr1 = addrList.next();
+        SimpleAddress receivedAddr2 = addrList.next();
 
         assertNotNull(receivedAddr1.getIpAddress().getIpv4Address());
         assertNotNull(receivedAddr2.getMacAddress());
@@ -1664,15 +2625,15 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         int instanceId = 6;
 
         EidBuilder eb = new EidBuilder();
-        eb.setAddressType(Ipv4PrefixAfi.class);
-        eb.setVirtualNetworkId(new InstanceIdType((long) instanceId));
+        eb.setAddressType(Ipv4PrefixAfi.VALUE);
+        eb.setVirtualNetworkId(new InstanceIdType(Uint32.valueOf(instanceId)));
         eb.setAddress(new Ipv4PrefixBuilder().setIpv4Prefix(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns
-                .yang.ietf.inet.types.rev100924.Ipv4Prefix(ipString)).build());
+                .yang.ietf.inet.types.rev130715.Ipv4Prefix(ipString)).build());
 
         MapReply reply = registerAddressAndQuery(eb.build());
 
         Eid receivedAddress = reply.getMappingRecordItem().get(0).getMappingRecord().getEid();
-        assertEquals(Ipv4PrefixAfi.class, receivedAddress.getAddressType());
+        assertEquals(Ipv4PrefixAfi.VALUE, receivedAddress.getAddressType());
 
         assertEquals(ipString, ((Ipv4Prefix) receivedAddress.getAddress()).getIpv4Prefix().getValue());
 
@@ -1696,29 +2657,29 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         elpBuilder.getHop().add(hop2);
 
         EidBuilder eb = new EidBuilder();
-        eb.setAddressType(ExplicitLocatorPathLcaf.class);
+        eb.setAddressType(ExplicitLocatorPathLcaf.VALUE);
         eb.setVirtualNetworkId(null);
         eb.setAddress(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105
                 .lisp.address.address.ExplicitLocatorPathBuilder().setExplicitLocatorPath(elpBuilder.build()).build());
 
         MapReply reply = registerAddressAndQuery(eb.build());
 
-        assertEquals(ExplicitLocatorPathLcaf.class, reply.getMappingRecordItem().get(0).getMappingRecord().getEid()
+        assertEquals(ExplicitLocatorPathLcaf.VALUE, reply.getMappingRecordItem().get(0).getMappingRecord().getEid()
                 .getAddressType());
 
         ExplicitLocatorPath receivedAddress = (ExplicitLocatorPath) reply.getMappingRecordItem().get(0)
                 .getMappingRecord().getEid().getAddress();
 
-        Hop receivedHop1 = (Hop) receivedAddress.getExplicitLocatorPath().getHop().get(0);
-        Hop receivedHop2 = (Hop) receivedAddress.getExplicitLocatorPath().getHop().get(1);
+        Hop receivedHop1 = receivedAddress.getExplicitLocatorPath().getHop().get(0);
+        Hop receivedHop2 = receivedAddress.getExplicitLocatorPath().getHop().get(1);
 
-        assertEquals(true, receivedHop1.getLrsBits().isLookup());
-        assertEquals(false, receivedHop1.getLrsBits().isRlocProbe());
-        assertEquals(true, receivedHop1.getLrsBits().isStrict());
+        assertEquals(true, receivedHop1.getLrsBits().getLookup());
+        assertEquals(false, receivedHop1.getLrsBits().getRlocProbe());
+        assertEquals(true, receivedHop1.getLrsBits().getStrict());
 
-        assertEquals(false, receivedHop2.getLrsBits().isLookup());
-        assertEquals(true, receivedHop2.getLrsBits().isRlocProbe());
-        assertEquals(false, receivedHop2.getLrsBits().isStrict());
+        assertEquals(false, receivedHop2.getLrsBits().getLookup());
+        assertEquals(true, receivedHop2.getLrsBits().getRlocProbe());
+        assertEquals(false, receivedHop2.getLrsBits().getStrict());
 
         assertNotNull(receivedHop1.getAddress().getIpAddress().getIpv4Address());
         assertNotNull(receivedHop2.getAddress().getMacAddress());
@@ -1730,12 +2691,12 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
     public void registerAndQuery__ApplicationData() throws SocketTimeoutException {
         cleanUP();
         String ipString = "1.2.3.4";
-        short protocol = 1;
+        final Uint8 protocol = Uint8.ONE;
         int ipTOs = 2;
-        int localPortLow = 3;
-        int localPortHigh = 4;
-        int remotePortLow = 4;
-        int remotePortHigh = 5;
+        final Uint16 localPortLow = Uint16.valueOf(3);
+        final Uint16 localPortHigh = Uint16.valueOf(4);
+        final Uint16 remotePortLow = Uint16.valueOf(4);
+        final Uint16 remotePortHigh = Uint16.valueOf(5);
 
         ApplicationDataBuilder builder = new ApplicationDataBuilder();
         builder.setIpTos(ipTOs);
@@ -1747,7 +2708,7 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         builder.setAddress(new SimpleAddress(new IpAddress(new Ipv4Address(ipString))));
 
         EidBuilder eb = new EidBuilder();
-        eb.setAddressType(ApplicationDataLcaf.class);
+        eb.setAddressType(ApplicationDataLcaf.VALUE);
         eb.setVirtualNetworkId(null);
         eb.setAddress(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105
                 .lisp.address.address.ApplicationDataBuilder().setApplicationData(builder.build()).build());
@@ -1757,19 +2718,16 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
 
         Eid receivedAddress = reply.getMappingRecordItem().get(0).getMappingRecord().getEid();
 
-        assertEquals(ApplicationDataLcaf.class, receivedAddress.getAddressType());
+        assertEquals(ApplicationDataLcaf.VALUE, receivedAddress.getAddressType());
 
         ApplicationData receivedApplicationDataAddress = (ApplicationData) receivedAddress.getAddress();
-        assertEquals(protocol, receivedApplicationDataAddress.getApplicationData().getProtocol().intValue());
+        assertEquals(protocol, receivedApplicationDataAddress.getApplicationData().getProtocol());
         assertEquals(ipTOs, receivedApplicationDataAddress.getApplicationData().getIpTos().intValue());
-        assertEquals(localPortLow, receivedApplicationDataAddress.getApplicationData().getLocalPortLow().getValue()
-                .intValue());
-        assertEquals(localPortHigh, receivedApplicationDataAddress.getApplicationData().getLocalPortHigh().getValue()
-                .intValue());
-        assertEquals(remotePortLow, receivedApplicationDataAddress.getApplicationData().getRemotePortLow().getValue()
-                .intValue());
-        assertEquals(remotePortHigh, receivedApplicationDataAddress.getApplicationData().getRemotePortHigh().getValue()
-                .intValue());
+        assertEquals(localPortLow, receivedApplicationDataAddress.getApplicationData().getLocalPortLow().getValue());
+        assertEquals(localPortHigh, receivedApplicationDataAddress.getApplicationData().getLocalPortHigh().getValue());
+        assertEquals(remotePortLow, receivedApplicationDataAddress.getApplicationData().getRemotePortLow().getValue());
+        assertEquals(remotePortHigh,
+                receivedApplicationDataAddress.getApplicationData().getRemotePortHigh().getValue());
 
         SimpleAddress ipAddressReceived = receivedApplicationDataAddress.getApplicationData().getAddress();
         assertEquals(ipString, ipAddressReceived.getIpAddress().getIpv4Address().getValue());
@@ -1779,54 +2737,33 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
 
     public void mapRequestMapRegisterAndMapRequestTestTimeout() throws SocketTimeoutException {
         cleanUP();
+        ConfigIni.getInstance().setSmrRetryCount(0);
         Eid eid = LispAddressUtil.asIpv4PrefixBinaryEid("1.2.3.4/32");
         mapService.addAuthenticationKey(eid, NULL_AUTH_KEY);
         sleepForSeconds(1);
-        MapRequestBuilder mapRequestBuilder = new MapRequestBuilder();
-        mapRequestBuilder.setNonce((long) 4);
-        mapRequestBuilder.setSourceEid(new SourceEidBuilder().setEid(LispAddressUtil.getNoAddressEid()).build());
-        mapRequestBuilder.setEidItem(new ArrayList<EidItem>());
-        mapRequestBuilder.getEidItem().add(new EidItemBuilder().setEid(eid).build());
-        mapRequestBuilder.setItrRloc(new ArrayList<ItrRloc>());
-        mapRequestBuilder.getItrRloc().add(
-                new ItrRlocBuilder().setRloc(LispAddressUtil.asIpv4Rloc(ourAddress)).build());
 
-        sendMapRequest(mapRequestBuilder.build());
+        MapRequest mapRequest = MappingServiceIntegrationTestUtil.getDefaultMapRequestBuilder(eid).build();
+        sendMapRequest(mapRequest);
         MapReply mapReply = receiveMapReply();
         assertEquals(4, mapReply.getNonce().longValue());
-        assertEquals(0, mapReply.getMappingRecordItem().get(0).getMappingRecord().getLocatorRecord().size());
-
-        MapRegisterBuilder mapRegisterbuilder = new MapRegisterBuilder();
-        mapRegisterbuilder.setWantMapNotify(true);
-        mapRegisterbuilder.setNonce((long) 8);
+        assertEquals(0, mapReply.getMappingRecordItem().get(0).getMappingRecord().nonnullLocatorRecord().size());
 
-        MappingRecordBuilder etlrBuilder = new MappingRecordBuilder();
-        etlrBuilder.setEid(eid);
-        etlrBuilder.setRecordTtl(254);
-
-        LocatorRecordBuilder recordBuilder = new LocatorRecordBuilder();
-        recordBuilder.setRloc(LispAddressUtil.asIpv4Rloc("4.3.2.1"));
-        etlrBuilder.setLocatorRecord(new ArrayList<LocatorRecord>());
-        etlrBuilder.getLocatorRecord().add(recordBuilder.build());
-        mapRegisterbuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
-        mapRegisterbuilder.getMappingRecordItem().add(
-                new MappingRecordItemBuilder().setMappingRecord(etlrBuilder.build()).build());
-
-        sendMapRegister(mapRegisterbuilder.build());
+        MapRegister mapRegister = MappingServiceIntegrationTestUtil.getDefaultMapRegisterBuilder(eid).build();
+        sendMapRegister(mapRegister);
         MapNotify mapNotify = receiveMapNotify();
         assertEquals(8, mapNotify.getNonce().longValue());
         sleepForSeconds(1);
 
-        sendMapRequest(mapRequestBuilder.build());
+        sendMapRequest(mapRequest);
         mapReply = receiveMapReply();
         assertEquals(4, mapReply.getNonce().longValue());
-        assertEquals(recordBuilder.getRloc(), mapReply.getMappingRecordItem().get(0).getMappingRecord()
-                .getLocatorRecord().get(0).getRloc());
+        assertEquals(MappingServiceIntegrationTestUtil.DEFAULT_IPV4_RLOC,
+                mapReply.getMappingRecordItem().get(0).getMappingRecord().getLocatorRecord().get(0).getRloc());
 
         causeEntryToBeCleaned();
-        sendMapRequest(mapRequestBuilder.build());
+        sendMapRequest(mapRequest);
         mapReply = receiveMapReply();
-        assertEquals(0, mapReply.getMappingRecordItem().get(0).getMappingRecord().getLocatorRecord().size());
+        assertEquals(0, mapReply.getMappingRecordItem().get(0).getMappingRecord().nonnullLocatorRecord().size());
     }
 
     public void mapRequestMapRegisterAndMapRequestTestNativelyForwardTimeoutResponse() throws Exception {
@@ -1848,6 +2785,26 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
 
     }
 
+    private void timedOutMappingRecord() {
+        cleanUP();
+        mapService.setMappingMerge(true);
+        // mapping expires after 1 second
+        ConfigIni.getInstance().setRegistrationValiditySb(1000L);
+
+        final Eid eid = LispAddressUtil.asIpv4PrefixBinaryEid("1.2.3.4/32", new InstanceIdType(Uint32.TEN));
+        final MappingRecord mappingRecord = MappingServiceIntegrationTestUtil.getDefaultMappingRecordBuilder(eid)
+                .setRecordTtl(1000).build();
+
+        mapService.addAuthenticationKey(eid, NULL_AUTH_KEY);
+        mapService.addMapping(MappingOrigin.Southbound, eid, MappingServiceIntegrationTestUtil.DEFAULT_SITE_ID,
+                new MappingData(mappingRecord, System.currentTimeMillis()));
+        sleepForSeconds(2);
+
+        MappingRecord resultRecord = (MappingRecord) mapService.getMapping(MappingOrigin.Southbound, eid);
+        assertNull(resultRecord);
+        ConfigIni.getInstance().setRegistrationValiditySb(ConfigIni.getInstance().getDefaultRegistrationValiditySb());
+    }
+
     private void testTTLAfterClean(MapRequest mapRequest) throws SocketTimeoutException {
         MapReply mapReply;
         sendMapRequest(mapRequest);
@@ -1897,42 +2854,15 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
     }
 
     private MapRegister createMapRegister(Eid eid, Rloc rloc) {
-        MapRegisterBuilder mapRegisterbuilder = new MapRegisterBuilder();
-        mapRegisterbuilder.setWantMapNotify(true);
-        mapRegisterbuilder.setNonce((long) 8);
-        mapRegisterbuilder.setKeyId((short) 0);
-        MappingRecordBuilder etlrBuilder = new MappingRecordBuilder();
-        etlrBuilder.setEid(eid);
-        etlrBuilder.setRecordTtl(254);
-        etlrBuilder.setAuthoritative(false);
-        etlrBuilder.setAction(Action.NoAction);
-        LocatorRecordBuilder recordBuilder = new LocatorRecordBuilder();
-        recordBuilder.setRloc(rloc);
-        etlrBuilder.setLocatorRecord(new ArrayList<LocatorRecord>());
-        etlrBuilder.getLocatorRecord().add(recordBuilder.build());
-        mapRegisterbuilder.setMappingRecordItem(new ArrayList<MappingRecordItem>());
-        mapRegisterbuilder.getMappingRecordItem().add(
-                new MappingRecordItemBuilder().setMappingRecord(etlrBuilder.build()).build());
-        MapRegister mapRegister = mapRegisterbuilder.build();
-        return mapRegister;
+        return MappingServiceIntegrationTestUtil.getDefaultMapRegisterBuilder(eid, rloc).build();
     }
 
     private MapRegister createMapRegister(Eid eid) {
-        return createMapRegister(eid, LispAddressUtil.asIpv4Rloc("4.3.2.1"));
+        return MappingServiceIntegrationTestUtil.getDefaultMapRegisterBuilder(eid).build();
     }
 
     private MapRequest createMapRequest(Eid eid) {
-        MapRequestBuilder mapRequestBuilder = new MapRequestBuilder();
-        mapRequestBuilder.setNonce((long) 4);
-        mapRequestBuilder.setPitr(false);
-        mapRequestBuilder.setSourceEid(new SourceEidBuilder().setEid(LispAddressUtil.getNoAddressEid()).build());
-        mapRequestBuilder.setEidItem(new ArrayList<EidItem>());
-        mapRequestBuilder.getEidItem().add(new EidItemBuilder().setEid(eid).build());
-        mapRequestBuilder.setItrRloc(new ArrayList<ItrRloc>());
-        mapRequestBuilder.getItrRloc().add(
-                new ItrRlocBuilder().setRloc(LispAddressUtil.asIpv4Rloc(ourAddress)).build());
-        MapRequest mr = mapRequestBuilder.build();
-        return mr;
+        return MappingServiceIntegrationTestUtil.getDefaultMapRequestBuilder(eid).build();
     }
 
     public void testSimpleNonProxy() throws SocketTimeoutException, SocketException {
@@ -1950,12 +2880,12 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         int port = 4350;
 
         RlocBuilder rb = new RlocBuilder();
-        rb.setAddressType(ApplicationDataLcaf.class);
+        rb.setAddressType(ApplicationDataLcaf.VALUE);
         rb.setVirtualNetworkId(null);
         rb.setAddress(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105
                 .lisp.address.address.ApplicationDataBuilder()
                 .setApplicationData(new ApplicationDataBuilder().setAddress(new SimpleAddress(new IpAddress(
-                new Ipv4Address(rloc)))).setLocalPortLow(new PortNumber(port)).build()).build());
+                new Ipv4Address(rloc)))).setLocalPortLow(new PortNumber(Uint16.valueOf(port))).build()).build());
         Rloc adLcaf = rb.build();
 
         LOG.info("testNonProxyOtherPort:" + LispAddressStringifier.getString(adLcaf));
@@ -1963,36 +2893,22 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
 
     }
 
-    private class XtrRequestMappingListener implements OdlLispProtoListener {
-
-        @Override
-        public void onGotMapReply(GotMapReply notification) {
-        }
-
-        @Override
-        public void onAddMapping(AddMapping notification) {
-        }
-
-        @Override
-        public void onXtrReplyMapping(XtrReplyMapping notification) {
-        }
+    private class XtrRequestMappingListener implements Listener<XtrRequestMapping> {
+        private final String eid;
+        private final MapRequest mapRequest;
 
-        @Override
-        public void onRequestMapping(RequestMapping notification) {
+        private XtrRequestMappingListener(String eid, MapRequest mapRequest) {
+            this.eid = eid;
+            this.mapRequest = mapRequest;
         }
 
         @Override
-        public void onGotMapNotify(GotMapNotify notification) {
+        public void onNotification(XtrRequestMapping notification) {
+            assertEquals(((Ipv4Prefix) mapRequest.getEidItem().get(0).getEid().getAddress())
+                .getIpv4Prefix().getValue(), eid);
+            notificationCalled = true;
+            LOG.warn("notification arrived");
         }
-
-        @Override
-        public void onXtrRequestMapping(XtrRequestMapping notification) {
-        }
-
-        @Override
-        public void onMappingKeepAlive(MappingKeepAlive notification) {
-        }
-
     }
 
     public void testRecievingNonProxyOnXtrPort() throws SocketTimeoutException, SocketException, Throwable {
@@ -2004,26 +2920,19 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         int port = LispMessage.XTR_PORT_NUM;
 
         RlocBuilder rb = new RlocBuilder();
-        rb.setAddressType(ApplicationDataLcaf.class);
+        rb.setAddressType(ApplicationDataLcaf.VALUE);
         rb.setVirtualNetworkId(null);
         rb.setAddress(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105
                 .lisp.address.address.ApplicationDataBuilder()
                 .setApplicationData(new ApplicationDataBuilder().setAddress(new SimpleAddress(new IpAddress(
-                new Ipv4Address(rloc)))).setLocalPortLow(new PortNumber(port)).build()).build());
+                new Ipv4Address(rloc)))).setLocalPortLow(new PortNumber(Uint16.valueOf(port))).build()).build());
         Rloc adLcaf = rb.build();
 
         final MapRequest mapRequest = createNonProxyMapRequest(eid, adLcaf);
-        ((LispMappingService) lms).getNotificationService().registerNotificationListener(
-                new XtrRequestMappingListener() {
-
-            @Override
-            public void onXtrRequestMapping(XtrRequestMapping notification) {
-                assertEquals(((Ipv4Prefix) mapRequest.getEidItem().get(0).getEid().getAddress())
-                        .getIpv4Prefix().getValue(), eid);
-                notificationCalled = true;
-                LOG.warn("notification arrived");
-            }
-        });
+        final var handler = new XtrRequestMappingListener(eid, mapRequest);
+
+        ((LispMappingService) lms).getNotificationService().registerListener(XtrRequestMapping.class, handler);
+
         sendMapRequest(mapRequest, port);
         for (int i = 0; i < MAX_NOTIFICATION_RETRYS; i++) {
             if (notificationCalled) {
@@ -2044,7 +2953,8 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         MapRequest mapRequest = createNonProxyMapRequest(eid, adLcaf);
         sendMapRequest(mapRequest);
         DatagramSocket nonProxySocket = new DatagramSocket(new InetSocketAddress(rloc, port));
-        MapRequest receivedMapRequest = receiveMapRequest(nonProxySocket);
+        MapRequest receivedMapRequest = MappingServiceIntegrationTestUtil.receiveMapRequest(
+                nonProxySocket, MappingServiceIntegrationTestUtil.DEFAULT_SOCKET_TIMEOUT);
         assertEquals(mapRequest.getNonce(), receivedMapRequest.getNonce());
         assertEquals(mapRequest.getSourceEid(), receivedMapRequest.getSourceEid());
         assertEquals(mapRequest.getItrRloc(), receivedMapRequest.getItrRloc());
@@ -2066,23 +2976,6 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         return mapRequest;
     }
 
-    private void assertMapNotifyReceived() throws SocketTimeoutException {
-        receiveMapNotify();
-    }
-
-    private MapReply receiveMapReply() throws SocketTimeoutException {
-        return MapReplySerializer.getInstance().deserialize(ByteBuffer.wrap(receivePacket().getData()));
-    }
-
-    private MapRequest receiveMapRequest(DatagramSocket datagramSocket) throws SocketTimeoutException {
-        return MapRequestSerializer.getInstance().deserialize(ByteBuffer.wrap(receivePacket(
-                datagramSocket, 30000).getData()));
-    }
-
-    private MapNotify receiveMapNotify() throws SocketTimeoutException {
-        return MapNotifySerializer.getInstance().deserialize(ByteBuffer.wrap(receivePacket().getData()));
-    }
-
     private void sendMapRequest(MapRequest mapRequest) {
         sendMapRequest(mapRequest, LispMessage.PORT_NUM);
     }
@@ -2100,39 +2993,34 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
     }
 
     private void sendPacket(byte[] bytesToSend, int port) {
-        try {
-            DatagramPacket packet = new DatagramPacket(bytesToSend, bytesToSend.length);
-            initPacketAddress(packet, port);
-            LOG.trace("Sending packet to LispPlugin on socket, port {}", port);
-            socket.send(packet);
-        } catch (Throwable t) {
-            fail();
-        }
+        MappingServiceIntegrationTestUtil.sendPacket(socket, bytesToSend, port);
     }
 
-    private DatagramPacket receivePacket() throws SocketTimeoutException {
-        return receivePacket(6000);
+    private ByteBuffer receivePacket() throws SocketTimeoutException {
+        return MappingServiceIntegrationTestUtil.receivePacket(socket);    }
+
+    private ByteBuffer receivePacket(int timeout) throws SocketTimeoutException {
+        return MappingServiceIntegrationTestUtil.receivePacket(socket, timeout);
     }
 
-    private DatagramPacket receivePacket(int timeout) throws SocketTimeoutException {
-        return receivePacket(socket, timeout);
+    private void assertMapNotifyReceived() throws SocketTimeoutException {
+        MappingServiceIntegrationTestUtil.receiveMapNotify(
+                socket, MappingServiceIntegrationTestUtil.DEFAULT_SOCKET_TIMEOUT);
     }
 
-    private DatagramPacket receivePacket(DatagramSocket receivedSocket, int timeout) throws SocketTimeoutException {
-        try {
-            byte[] buffer = new byte[4096];
-            DatagramPacket receivePacket = new DatagramPacket(buffer, buffer.length);
-            LOG.trace("Waiting for packet from socket...");
-            receivedSocket.setSoTimeout(timeout);
-            receivedSocket.receive(receivePacket);
-            LOG.trace("Received packet from socket!");
-            return receivePacket;
-        } catch (SocketTimeoutException ste) {
-            throw ste;
-        } catch (Throwable t) {
-            fail();
-            return null;
-        }
+    private MapRequest receiveMapRequest() throws SocketTimeoutException {
+        return MappingServiceIntegrationTestUtil.receiveMapRequest(
+                socket, MappingServiceIntegrationTestUtil.DEFAULT_SOCKET_TIMEOUT);
+    }
+
+    private MapReply receiveMapReply() throws SocketTimeoutException {
+        return MappingServiceIntegrationTestUtil.receiveMapReply(
+                socket, MappingServiceIntegrationTestUtil.DEFAULT_SOCKET_TIMEOUT);
+    }
+
+    private MapNotify receiveMapNotify() throws SocketTimeoutException {
+        return MappingServiceIntegrationTestUtil.receiveMapNotify(
+                socket, MappingServiceIntegrationTestUtil.DEFAULT_SOCKET_TIMEOUT);
     }
 
     private void sleepForSeconds(int seconds) {
@@ -2143,19 +3031,12 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         }
     }
 
-    private void initPacketAddress(DatagramPacket packet, int port) throws UnknownHostException {
-        packet.setAddress(InetAddress.getByName(lispBindAddress));
-        packet.setPort(port);
-    }
-
-    private DatagramSocket initSocket(DatagramSocket socket, int port) {
+    private void sleepForMilliseconds(long milliseconds) {
         try {
-            socket = new DatagramSocket(new InetSocketAddress(ourAddress, port));
-        } catch (SocketException e) {
-            LOG.error("Can't initize socket for {}", ourAddress, e);
-            fail();
+            Thread.sleep(milliseconds);
+        } catch (InterruptedException e) {
+            LOG.warn("Interrupted while sleeping", e);
         }
-        return socket;
     }
 
     private byte[] extractWSUdpByteArray(String wiresharkHex) {
@@ -2244,16 +3125,18 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
     }
 
     private void cleanUP() {
-        after();
+        LOG.debug("\n\n\nCleaning up...\n\n");
         mapService.cleanCachedMappings();
+        mapService.setLookupPolicy(IMappingService.LookupPolicy.NB_FIRST);
         configLispPlugin.shouldListenOnXtrPort(false);
-        socket = initSocket(socket, LispMessage.PORT_NUM);
-
+        MappingServiceIntegrationTestUtil.drainSocket(socket);
+        LOG.debug("\n\n\n... finished cleaning up!\n\n");
     }
 
     private void restartSocket() {
         after();
-        socket = initSocket(socket, LispMessage.PORT_NUM);
+        socket = MappingServiceIntegrationTestUtil.initSocket(LispMessage.PORT_NUM);
+        MappingServiceIntegrationTestUtil.drainSocket(socket);
     }
 
 }