diff --git a/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilder.java b/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilder.java
index 90052c28..7d45745 100644
--- a/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilder.java
+++ b/providers/lisp/mapping/src/main/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilder.java
@@ -19,6 +19,15 @@
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.MacAddress;
+import org.onosproject.drivers.lisp.extensions.LispGcAddress;
+import org.onosproject.drivers.lisp.extensions.LispNatAddress;
+import org.onosproject.drivers.lisp.extensions.LispSrcDstAddress;
+import org.onosproject.drivers.lisp.extensions.LispAppDataAddress;
+import org.onosproject.drivers.lisp.extensions.LispListAddress;
+import org.onosproject.drivers.lisp.extensions.LispMulticastAddress;
+import org.onosproject.drivers.lisp.extensions.LispNonceAddress;
+import org.onosproject.drivers.lisp.extensions.LispSegmentAddress;
+import org.onosproject.drivers.lisp.extensions.LispTeAddress;
 import org.onosproject.lisp.msg.protocols.LispLocator;
 import org.onosproject.lisp.msg.protocols.LispMapRecord;
 import org.onosproject.lisp.msg.types.LispAfiAddress;
@@ -27,6 +36,17 @@
 import org.onosproject.lisp.msg.types.LispIpv4Address;
 import org.onosproject.lisp.msg.types.LispIpv6Address;
 import org.onosproject.lisp.msg.types.LispMacAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispMulticastLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispNonceLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispNatLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispGeoCoordinateLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispAsLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispSegmentLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispAppDataLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispListLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispSourceDestLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispTeLcafAddress;
 import org.onosproject.mapping.DefaultMapping;
 import org.onosproject.mapping.DefaultMappingEntry;
 import org.onosproject.mapping.DefaultMappingKey;
@@ -40,6 +60,7 @@
 import org.onosproject.mapping.MappingValue;
 import org.onosproject.mapping.actions.MappingAction;
 import org.onosproject.mapping.actions.MappingActions;
+import org.onosproject.mapping.addresses.ExtensionMappingAddress;
 import org.onosproject.mapping.addresses.MappingAddress;
 import org.onosproject.mapping.addresses.MappingAddresses;
 import org.onosproject.net.DeviceId;
@@ -49,9 +70,6 @@
 import java.util.List;
 import java.util.UUID;
 
-import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.IP4;
-import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.IP6;
-
 /**
  * Mapping entry builder class.
  */
@@ -172,17 +190,16 @@
     private MappingAddress buildAddress(LispMapRecord record) {
 
         return record == null ? null :
-                getAddress(record.getEidPrefixAfi(), record.getMaskLength());
+                getAddress(record.getEidPrefixAfi());
     }
 
     /**
      * Converts LispAfiAddress into abstracted mapping address.
      *
      * @param address LispAfiAddress
-     * @param length  mask length
      * @return abstracted mapping address
      */
-    private MappingAddress getAddress(LispAfiAddress address, int length) {
+    private MappingAddress getAddress(LispAfiAddress address) {
 
         if (address == null) {
             log.warn("Address is not specified.");
@@ -191,13 +208,9 @@
 
         switch (address.getAfi()) {
             case IP4:
-                IpAddress ipv4Address = ((LispIpv4Address) address).getAddress();
-                IpPrefix ipv4Prefix = IpPrefix.valueOf(ipv4Address, length);
-                return MappingAddresses.ipv4MappingAddress(ipv4Prefix);
+                return afi2MappingAddress(address);
             case IP6:
-                IpAddress ipv6Address = ((LispIpv6Address) address).getAddress();
-                IpPrefix ipv6Prefix = IpPrefix.valueOf(ipv6Address, length);
-                return MappingAddresses.ipv6MappingAddress(ipv6Prefix);
+                return afi2MappingAddress(address);
             case AS:
                 int asNum = ((LispAsAddress) address).getASNum();
                 return MappingAddresses.asMappingAddress(String.valueOf(asNum));
@@ -209,8 +222,8 @@
                 MacAddress macAddress = ((LispMacAddress) address).getAddress();
                 return MappingAddresses.ethMappingAddress(macAddress);
             case LCAF:
-                // TODO: need to use extension address to abstract LCAF address
-                break;
+                LispLcafAddress lcafAddress = (LispLcafAddress) address;
+                return lcaf2Extension(lcafAddress);
             default:
                 log.warn("Unsupported address type {}", address.getAfi());
                 break;
@@ -220,6 +233,204 @@
     }
 
     /**
+     * Converts LCAF address to extension mapping address.
+     *
+     * @param lcaf LCAF address
+     * @return extension mapping address
+     */
+    private MappingAddress lcaf2Extension(LispLcafAddress lcaf) {
+
+        ExtensionMappingAddress ema;
+
+        switch (lcaf.getType()) {
+            case LIST:
+                LispListLcafAddress lcafListAddress = (LispListLcafAddress) lcaf;
+                MappingAddress ipv4Ma =
+                        afi2MappingAddress(lcafListAddress.getAddresses().get(0));
+                MappingAddress ipv6Ma =
+                        afi2MappingAddress(lcafListAddress.getAddresses().get(1));
+
+                ema = new LispListAddress.Builder()
+                        .withIpv4(ipv4Ma)
+                        .withIpv6(ipv6Ma)
+                        .build();
+                return MappingAddresses.extensionMappingAddressWrapper(ema, deviceId);
+
+            case SEGMENT:
+                LispSegmentLcafAddress segmentLcafAddress = (LispSegmentLcafAddress) lcaf;
+
+                ema = new LispSegmentAddress.Builder()
+                        .withInstanceId(segmentLcafAddress.getInstanceId())
+                        .withAddress(getAddress(segmentLcafAddress.getAddress()))
+                        .build();
+
+                return MappingAddresses.extensionMappingAddressWrapper(ema, deviceId);
+
+            case AS:
+                LispAsLcafAddress asLcafAddress = (LispAsLcafAddress) lcaf;
+
+                ema = new org.onosproject.drivers.lisp.extensions.LispAsAddress.Builder()
+                        .withAsNumber(asLcafAddress.getAsNumber())
+                        .withAddress(getAddress(asLcafAddress.getAddress()))
+                        .build();
+
+                return MappingAddresses.extensionMappingAddressWrapper(ema, deviceId);
+
+            case APPLICATION_DATA:
+
+                LispAppDataLcafAddress appLcafAddress = (LispAppDataLcafAddress) lcaf;
+
+                ema = new LispAppDataAddress.Builder()
+                        .withProtocol(appLcafAddress.getProtocol())
+                        .withIpTos(appLcafAddress.getIpTos())
+                        .withLocalPortLow(appLcafAddress.getLocalPortLow())
+                        .withLocalPortHigh(appLcafAddress.getLocalPortHigh())
+                        .withRemotePortLow(appLcafAddress.getRemotePortLow())
+                        .withRemotePortHigh(appLcafAddress.getRemotePortHigh())
+                        .withAddress(getAddress(appLcafAddress.getAddress()))
+                        .build();
+
+                return MappingAddresses.extensionMappingAddressWrapper(ema, deviceId);
+
+            case GEO_COORDINATE:
+
+                LispGeoCoordinateLcafAddress gcLcafAddress = (LispGeoCoordinateLcafAddress) lcaf;
+
+                ema = new LispGcAddress.Builder()
+                        .withIsNorth(gcLcafAddress.isNorth())
+                        .withLatitudeDegree(gcLcafAddress.getLatitudeDegree())
+                        .withLatitudeMinute(gcLcafAddress.getLatitudeMinute())
+                        .withLatitudeSecond(gcLcafAddress.getLatitudeSecond())
+                        .withIsEast(gcLcafAddress.isEast())
+                        .withLongitudeDegree(gcLcafAddress.getLongitudeDegree())
+                        .withLongitudeMinute(gcLcafAddress.getLongitudeMinute())
+                        .withLongitudeSecond(gcLcafAddress.getLongitudeSecond())
+                        .withAltitude(gcLcafAddress.getAltitude())
+                        .withAddress(getAddress(gcLcafAddress.getAddress()))
+                        .build();
+
+                return MappingAddresses.extensionMappingAddressWrapper(ema, deviceId);
+
+            case NAT:
+
+                LispNatLcafAddress natLcafAddress = (LispNatLcafAddress) lcaf;
+
+                List<MappingAddress> mas = Lists.newArrayList();
+
+                natLcafAddress.getRtrRlocAddresses().forEach(rtr -> mas.add(getAddress(rtr)));
+
+                ema = new LispNatAddress.Builder()
+                        .withMsUdpPortNumber(natLcafAddress.getMsUdpPortNumber())
+                        .withEtrUdpPortNumber(natLcafAddress.getEtrUdpPortNumber())
+                        .withMsRlocAddress(getAddress(natLcafAddress.getMsRlocAddress()))
+                        .withGlobalEtrRlocAddress(getAddress(natLcafAddress.getGlobalEtrRlocAddress()))
+                        .withPrivateEtrRlocAddress(getAddress(natLcafAddress.getPrivateEtrRlocAddress()))
+                        .withRtrRlocAddresses(mas)
+                        .build();
+
+                return MappingAddresses.extensionMappingAddressWrapper(ema, deviceId);
+
+            case NONCE:
+
+                LispNonceLcafAddress nonceLcafAddress = (LispNonceLcafAddress) lcaf;
+
+                ema = new LispNonceAddress.Builder()
+                        .withNonce(nonceLcafAddress.getNonce())
+                        .withAddress(getAddress(nonceLcafAddress.getAddress()))
+                        .build();
+
+                return MappingAddresses.extensionMappingAddressWrapper(ema, deviceId);
+
+            case MULTICAST:
+
+                LispMulticastLcafAddress multiLcafAddress = (LispMulticastLcafAddress) lcaf;
+
+                ema = new LispMulticastAddress.Builder()
+                        .withInstanceId(multiLcafAddress.getInstanceId())
+                        .withSrcAddress(getAddress(multiLcafAddress.getSrcAddress()))
+                        .withSrcMaskLength(multiLcafAddress.getSrcMaskLength())
+                        .withGrpAddress(getAddress(multiLcafAddress.getGrpAddress()))
+                        .withGrpMaskLength(multiLcafAddress.getGrpMaskLength())
+                        .build();
+
+                return MappingAddresses.extensionMappingAddressWrapper(ema, deviceId);
+
+            case TRAFFIC_ENGINEERING:
+
+                LispTeLcafAddress teLcafAddress = (LispTeLcafAddress) lcaf;
+
+                List<LispTeAddress.TeRecord> records = Lists.newArrayList();
+
+                teLcafAddress.getTeRecords().forEach(record -> {
+                    LispTeAddress.TeRecord teRecord =
+                            new LispTeAddress.TeRecord.Builder()
+                                    .withIsLookup(record.isLookup())
+                                    .withIsRlocProbe(record.isRlocProbe())
+                                    .withIsStrict(record.isStrict())
+                                    .withRtrRlocAddress(getAddress(record.getRtrRlocAddress()))
+                                    .build();
+                    records.add(teRecord);
+                });
+
+                ema = new LispTeAddress.Builder()
+                        .withTeRecords(records)
+                        .build();
+
+                return MappingAddresses.extensionMappingAddressWrapper(ema, deviceId);
+
+            case SECURITY:
+
+                // TODO: need to implement security type later
+                log.warn("security type will be implemented later");
+
+                return null;
+
+            case SOURCE_DEST:
+
+                LispSourceDestLcafAddress srcDstLcafAddress = (LispSourceDestLcafAddress) lcaf;
+
+
+                ema = new LispSrcDstAddress.Builder()
+                        .withSrcPrefix(getAddress(srcDstLcafAddress.getSrcPrefix()))
+                        .withSrcMaskLength(srcDstLcafAddress.getSrcMaskLength())
+                        .withDstPrefix(getAddress(srcDstLcafAddress.getDstPrefix()))
+                        .withDstMaskLength(srcDstLcafAddress.getDstMaskLength())
+                        .build();
+
+                return MappingAddresses.extensionMappingAddressWrapper(ema, deviceId);
+
+            case UNSPECIFIED:
+            case UNKNOWN:
+            default:
+                log.error("Unsupported LCAF type {}", lcaf.getType());
+                return null;
+        }
+    }
+
+    /**
+     * Converts AFI address to generalized mapping address.
+     *
+     * @param afiAddress IP typed AFI address
+     * @return generalized mapping address
+     */
+    private MappingAddress afi2MappingAddress(LispAfiAddress afiAddress) {
+        switch (afiAddress.getAfi()) {
+            case IP4:
+                IpAddress ipv4Address = ((LispIpv4Address) afiAddress).getAddress();
+                IpPrefix ipv4Prefix = IpPrefix.valueOf(ipv4Address, IPV4_PREFIX_LENGTH);
+                return MappingAddresses.ipv4MappingAddress(ipv4Prefix);
+            case IP6:
+                IpAddress ipv6Address = ((LispIpv6Address) afiAddress).getAddress();
+                IpPrefix ipv6Prefix = IpPrefix.valueOf(ipv6Address, IPV6_PREFIX_LENGTH);
+                return MappingAddresses.ipv6MappingAddress(ipv6Prefix);
+            default:
+                log.warn("Only support to convert IP address type");
+                break;
+        }
+        return null;
+    }
+
+    /**
      * Builds a collection of mapping treatments.
      *
      * @param record LISP map record
@@ -232,14 +443,8 @@
         for (LispLocator locator : locators) {
             MappingTreatment.Builder builder = DefaultMappingTreatment.builder();
             LispAfiAddress address = locator.getLocatorAfi();
-            int addressLength = 0;
-            if (address.getAfi() == IP4) {
-                addressLength = IPV4_PREFIX_LENGTH;
-            } else if (address.getAfi() == IP6) {
-                addressLength = IPV6_PREFIX_LENGTH;
-            }
 
-            final MappingAddress mappingAddress = getAddress(address, addressLength);
+            final MappingAddress mappingAddress = getAddress(address);
             if (mappingAddress != null) {
                 builder.withAddress(mappingAddress);
             }
diff --git a/providers/lisp/mapping/src/test/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilderTest.java b/providers/lisp/mapping/src/test/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilderTest.java
index c6bf5fa..b78f167 100644
--- a/providers/lisp/mapping/src/test/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilderTest.java
+++ b/providers/lisp/mapping/src/test/java/org/onosproject/provider/lisp/mapping/util/MappingEntryBuilderTest.java
@@ -20,6 +20,15 @@
 import org.junit.Test;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.drivers.lisp.extensions.LispAppDataAddress;
+import org.onosproject.drivers.lisp.extensions.LispGcAddress;
+import org.onosproject.drivers.lisp.extensions.LispListAddress;
+import org.onosproject.drivers.lisp.extensions.LispMulticastAddress;
+import org.onosproject.drivers.lisp.extensions.LispNatAddress;
+import org.onosproject.drivers.lisp.extensions.LispNonceAddress;
+import org.onosproject.drivers.lisp.extensions.LispSegmentAddress;
+import org.onosproject.drivers.lisp.extensions.LispSrcDstAddress;
 import org.onosproject.lisp.msg.protocols.DefaultLispLocator.DefaultLocatorBuilder;
 import org.onosproject.lisp.msg.protocols.DefaultLispMapNotify.DefaultNotifyBuilder;
 import org.onosproject.lisp.msg.protocols.DefaultLispMapRecord.DefaultMapRecordBuilder;
@@ -33,19 +42,58 @@
 import org.onosproject.lisp.msg.protocols.LispMapReply;
 import org.onosproject.lisp.msg.protocols.LispMapReply.ReplyBuilder;
 import org.onosproject.lisp.msg.protocols.LispMapReplyAction;
+import org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum;
+import org.onosproject.lisp.msg.types.LispAfiAddress;
+import org.onosproject.lisp.msg.types.LispAsAddress;
+import org.onosproject.lisp.msg.types.LispDistinguishedNameAddress;
 import org.onosproject.lisp.msg.types.LispIpv4Address;
+import org.onosproject.lisp.msg.types.LispIpv6Address;
+import org.onosproject.lisp.msg.types.LispMacAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispAppDataLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispAsLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum;
+import org.onosproject.lisp.msg.types.lcaf.LispGeoCoordinateLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispListLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispMulticastLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispNatLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispNonceLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispSegmentLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispSourceDestLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispTeLcafAddress;
+import org.onosproject.lisp.msg.types.lcaf.LispTeRecord;
 import org.onosproject.mapping.MappingEntry;
 import org.onosproject.mapping.MappingKey;
 import org.onosproject.mapping.MappingTreatment;
 import org.onosproject.mapping.MappingValue;
 import org.onosproject.mapping.actions.MappingAction;
+import org.onosproject.mapping.addresses.ASMappingAddress;
+import org.onosproject.mapping.addresses.DNMappingAddress;
+import org.onosproject.mapping.addresses.EthMappingAddress;
+import org.onosproject.mapping.addresses.ExtensionMappingAddressWrapper;
 import org.onosproject.mapping.addresses.IPMappingAddress;
+import org.onosproject.mapping.addresses.MappingAddress;
 import org.onosproject.net.DeviceId;
 
 import java.util.List;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.AS;
+import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.DISTINGUISHED_NAME;
+import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.IP4;
+import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.IP6;
+import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.LCAF;
+import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.MAC;
+import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.APPLICATION_DATA;
+import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.GEO_COORDINATE;
+import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.LIST;
+import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.MULTICAST;
+import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.NAT;
+import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.NONCE;
+import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.SEGMENT;
+import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.SOURCE_DEST;
+import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.UNKNOWN;
 
 /**
  * Mapping entry builder unit test.
@@ -53,61 +101,230 @@
 public class MappingEntryBuilderTest {
 
     private static final String IP_RECORD_ADDRESS = "192.168.1.1";
-    private static final String IP_LOCATOR_ADDRESS = "10.1.1.1";
-    private static final int IP_RECORD_MASK_LENGTH = 24;
+    private static final int IP_RECORD_MASK_LENGTH = 32;
     private static final int IP_LOCATOR_MASK_LENGTH = 32;
 
+    private static final LispAfiAddress IPV4_ADDRESS_1 =
+                         new LispIpv4Address(IpAddress.valueOf("1.2.3.4"));
+    private static final LispAfiAddress IPV4_ADDRESS_2 =
+                         new LispIpv4Address(IpAddress.valueOf("5.6.7.8"));
+    private static final LispAfiAddress IPV6_ADDRESS =
+                         new LispIpv6Address(IpAddress.valueOf(
+                                 "1111:2222:3333:4444:5555:6666:7777:8885"));
+    private static final LispAfiAddress MAC_ADDRESS =
+                         new LispMacAddress(MacAddress.valueOf("00:00:00:00:00:01"));
+
+    private static final IpPrefix IPV4_MAPPING_ADDRESS_1 = IpPrefix.valueOf("1.2.3.4/32");
+    private static final IpPrefix IPV4_MAPPING_ADDRESS_2 = IpPrefix.valueOf("5.6.7.8/32");
+
+    private static final IpPrefix IPV6_MAPPING_ADDRESS =
+            IpPrefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8885/128");
+    private static final MacAddress MAC_MAPPING_ADDRESS =
+                                        MacAddress.valueOf("00:00:00:00:00:01");
+
+    private static final byte UNIQUE_BYTE = (byte) 0x01;
+    private static final int UNIQUE_INT = 1;
+    private static final short UNIQUE_SHORT = 1;
+    private static final boolean UNIQUE_BOOLEAN = true;
+    private static final long UNIQUE_LONG = 1L;
+    private static final String UNIQUE_STRING = "onos";
+
     private static final String AUTH_KEY = "onos";
 
-    private static final byte UNIQUE_VALUE = (byte) 0x01;
     private static final DeviceId DEVICE_ID = DeviceId.deviceId("lisp:10.1.1.2");
 
-    private LispMapReply mapReply;
-    private LispMapNotify mapNotify;
-
     @Before
     public void setUp() {
-        ReplyBuilder replyBuilder = new DefaultReplyBuilder();
 
-        List<LispMapRecord> records = ImmutableList.of(getMapRecord());
-
-        mapReply = replyBuilder
-                        .withIsEtr(true)
-                        .withIsProbe(false)
-                        .withIsSecurity(true)
-                        .withNonce(1L)
-                        .withMapRecords(records)
-                        .build();
-
-        NotifyBuilder notifyBuilder = new DefaultNotifyBuilder();
-
-        mapNotify = notifyBuilder
-                        .withKeyId((short) 1)
-                        .withAuthKey(AUTH_KEY)
-                        .withNonce(1L)
-                        .withMapRecords(records)
-                        .build();
     }
 
     @Test
     public void testMapReplyConversion() {
+
+        ReplyBuilder replyBuilder = new DefaultReplyBuilder();
+
+        List<LispMapRecord> records = ImmutableList.of(getMapRecord(IP4, UNKNOWN));
+
+        LispMapReply mapReply = replyBuilder
+                                    .withIsEtr(true)
+                                    .withIsProbe(false)
+                                    .withIsSecurity(true)
+                                    .withNonce(UNIQUE_LONG)
+                                    .withMapRecords(records)
+                                    .build();
+
         List<LispMapRecord> replyRecords = mapReply.getMapRecords();
 
         assertThat(replyRecords.size(), is(1));
 
-        testMapRecorConversion(replyRecords.get(0));
+        testMapRecordConversion(replyRecords.get(0));
     }
 
     @Test
     public void testMapNotifyConversion() {
+
+        List<LispMapRecord> records = ImmutableList.of(getMapRecord(IP4, UNKNOWN));
+
+        NotifyBuilder notifyBuilder = new DefaultNotifyBuilder();
+
+        LispMapNotify mapNotify = notifyBuilder
+                                    .withKeyId(UNIQUE_SHORT)
+                                    .withAuthKey(AUTH_KEY)
+                                    .withNonce(UNIQUE_LONG)
+                                    .withMapRecords(records)
+                                    .build();
+
         List<LispMapRecord> notifyRecords = mapNotify.getMapRecords();
 
         assertThat(notifyRecords.size(), is(1));
 
-        testMapRecorConversion(notifyRecords.get(0));
+        testMapRecordConversion(notifyRecords.get(0));
     }
 
-    private void testMapRecorConversion(LispMapRecord record) {
+    @Test
+    public void testIpv4AddressConversion() {
+        IPMappingAddress address = (IPMappingAddress) getMappingAddressByAfiType(IP4, UNKNOWN);
+        assertThat(address.ip(), is(IPV4_MAPPING_ADDRESS_1));
+    }
+
+    @Test
+    public void testIpv6AddressConversion() {
+        IPMappingAddress address = (IPMappingAddress) getMappingAddressByAfiType(IP6, UNKNOWN);
+        assertThat(address.ip(), is(IPV6_MAPPING_ADDRESS));
+    }
+
+    @Test
+    public void testMacAddressConversion() {
+        EthMappingAddress address = (EthMappingAddress) getMappingAddressByAfiType(MAC, UNKNOWN);
+        assertThat(address.mac(), is(MAC_MAPPING_ADDRESS));
+    }
+
+    @Test
+    public void testAsAddressConversion() {
+        ASMappingAddress address = (ASMappingAddress) getMappingAddressByAfiType(AS, UNKNOWN);
+        assertThat(address.asNumber(), is(String.valueOf(UNIQUE_INT)));
+    }
+
+    @Test
+    public void testDnAddressConversion() {
+        DNMappingAddress address = (DNMappingAddress)
+                        getMappingAddressByAfiType(DISTINGUISHED_NAME, UNKNOWN);
+        assertThat(address.name(), is(UNIQUE_STRING));
+    }
+
+    @Test
+    public void testListLcafAddressConversion() {
+        LispListAddress address = (LispListAddress) ((ExtensionMappingAddressWrapper)
+                getMappingAddressByAfiType(LCAF, LIST)).extensionMappingAddress();
+        assertThat(((IPMappingAddress) address.getIpv4()).ip(), is(IPV4_MAPPING_ADDRESS_1));
+        assertThat(((IPMappingAddress) address.getIpv6()).ip(), is(IPV6_MAPPING_ADDRESS));
+    }
+
+    @Test
+    public void testSegmentLcafAddressConversion() {
+        LispSegmentAddress address = (LispSegmentAddress) ((ExtensionMappingAddressWrapper)
+                getMappingAddressByAfiType(LCAF, SEGMENT)).extensionMappingAddress();
+        assertThat(((IPMappingAddress) address.getAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
+        assertThat(address.getInstanceId(), is(UNIQUE_INT));
+    }
+
+    @Test
+    public void testAsLcafAddressConversion() {
+        org.onosproject.drivers.lisp.extensions.LispAsAddress address =
+                (org.onosproject.drivers.lisp.extensions.LispAsAddress)
+                ((ExtensionMappingAddressWrapper)
+                        getMappingAddressByAfiType(LCAF,
+                                LispCanonicalAddressFormatEnum.AS)).extensionMappingAddress();
+        assertThat(((IPMappingAddress) address.getAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
+        assertThat(address.getAsNumber(), is(UNIQUE_INT));
+    }
+
+    @Test
+    public void testAppDataLcafAddressConversion() {
+        LispAppDataAddress address = (LispAppDataAddress) ((ExtensionMappingAddressWrapper)
+                getMappingAddressByAfiType(LCAF, APPLICATION_DATA)).extensionMappingAddress();
+        assertThat(((IPMappingAddress) address.getAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
+        assertThat(address.getProtocol(), is(UNIQUE_BYTE));
+        assertThat(address.getIpTos(), is(UNIQUE_INT));
+        assertThat(address.getLocalPortLow(), is(UNIQUE_SHORT));
+        assertThat(address.getLocalPortHigh(), is(UNIQUE_SHORT));
+        assertThat(address.getRemotePortLow(), is(UNIQUE_SHORT));
+        assertThat(address.getRemotePortHigh(), is(UNIQUE_SHORT));
+    }
+
+    @Test
+    public void testGcLcafAddressConversion() {
+        LispGcAddress address = (LispGcAddress) ((ExtensionMappingAddressWrapper)
+                getMappingAddressByAfiType(LCAF, GEO_COORDINATE)).extensionMappingAddress();
+        assertThat(((IPMappingAddress) address.getAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
+        assertThat(address.isNorth(), is(UNIQUE_BOOLEAN));
+        assertThat(address.getLatitudeDegree(), is(UNIQUE_SHORT));
+        assertThat(address.getLatitudeMinute(), is(UNIQUE_BYTE));
+        assertThat(address.getLatitudeSecond(), is(UNIQUE_BYTE));
+        assertThat(address.isEast(), is(UNIQUE_BOOLEAN));
+        assertThat(address.getLongitudeDegree(), is(UNIQUE_SHORT));
+        assertThat(address.getLongitudeMinute(), is(UNIQUE_BYTE));
+        assertThat(address.getLongitudeSecond(), is(UNIQUE_BYTE));
+        assertThat(address.getAltitude(), is(UNIQUE_INT));
+    }
+
+    @Test
+    public void testNatLcafAddressConversion() {
+        LispNatAddress address = (LispNatAddress) ((ExtensionMappingAddressWrapper)
+                getMappingAddressByAfiType(LCAF, NAT)).extensionMappingAddress();
+        assertThat(((IPMappingAddress)
+                address.getPrivateEtrRlocAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
+        assertThat(((IPMappingAddress)
+                address.getGlobalEtrRlocAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
+        assertThat(((IPMappingAddress)
+                address.getMsRlocAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
+        assertThat(address.getEtrUdpPortNumber(), is(UNIQUE_SHORT));
+        assertThat(address.getMsUdpPortNumber(), is(UNIQUE_SHORT));
+        // TODO: need to compare RtrRlocAddresses
+    }
+
+    @Test
+    public void testNonceLcafAddressConversion() {
+        LispNonceAddress address = (LispNonceAddress) ((ExtensionMappingAddressWrapper)
+                getMappingAddressByAfiType(LCAF, NONCE)).extensionMappingAddress();
+        assertThat(((IPMappingAddress) address.getAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
+        assertThat(address.getNonce(), is(UNIQUE_INT));
+    }
+
+    @Test
+    public void testMulticastLcafAddressConversion() {
+        LispMulticastAddress address = (LispMulticastAddress) ((ExtensionMappingAddressWrapper)
+                getMappingAddressByAfiType(LCAF, MULTICAST)).extensionMappingAddress();
+        assertThat(((IPMappingAddress) address.getSrcAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
+        assertThat(((IPMappingAddress) address.getGrpAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
+        assertThat(address.getInstanceId(), is(UNIQUE_INT));
+        assertThat(address.getSrcMaskLength(), is(UNIQUE_BYTE));
+        assertThat(address.getGrpMaskLength(), is(UNIQUE_BYTE));
+    }
+
+    @Test
+    public void testSrcDstLcafAddressConversion() {
+        LispSrcDstAddress address = (LispSrcDstAddress) ((ExtensionMappingAddressWrapper)
+                getMappingAddressByAfiType(LCAF, SOURCE_DEST)).extensionMappingAddress();
+        assertThat(((IPMappingAddress) address.getSrcPrefix()).ip(), is(IPV4_MAPPING_ADDRESS_1));
+        assertThat(((IPMappingAddress) address.getDstPrefix()).ip(), is(IPV4_MAPPING_ADDRESS_2));
+        assertThat(address.getSrcMaskLength(), is(UNIQUE_BYTE));
+        assertThat(address.getDstMaskLength(), is(UNIQUE_BYTE));
+    }
+
+    @Test
+    public void testTeLcafAddressConversion() {
+        // TODO: need to compare TeRecord list
+    }
+
+    private MappingAddress getMappingAddressByAfiType(AddressFamilyIdentifierEnum afiType,
+                                                      LispCanonicalAddressFormatEnum lcafType) {
+        LispMapRecord record = getMapRecord(afiType, lcafType);
+        MappingEntry entry = new MappingEntryBuilder(DEVICE_ID, record).build();
+        return entry.value().treatments().get(0).address();
+    }
+
+    private void testMapRecordConversion(LispMapRecord record) {
         MappingEntry mappingEntry =
                      new MappingEntryBuilder(DEVICE_ID, record).build();
         MappingKey key = mappingEntry.key();
@@ -125,11 +342,19 @@
         MappingTreatment treatment = value.treatments().get(0);
         IPMappingAddress locatorAddress = (IPMappingAddress) treatment.address();
 
-        assertThat(locatorAddress.ip(), is(IpPrefix.valueOf(IP_LOCATOR_ADDRESS + "/" +
+        assertThat(locatorAddress.ip(), is(IpPrefix.valueOf(IPV4_ADDRESS_1 + "/" +
                 IP_LOCATOR_MASK_LENGTH)));
     }
 
-    private LispMapRecord getMapRecord() {
+    /**
+     * Obtains a MapRecord instance.
+     *
+     * @param afiType   AFI address type
+     * @param lcafType  LCAF address type
+     * @return a MapRecord instance
+     */
+    private LispMapRecord getMapRecord(AddressFamilyIdentifierEnum afiType,
+                                       LispCanonicalAddressFormatEnum lcafType) {
         MapRecordBuilder recordBuilder = new DefaultMapRecordBuilder();
 
         LispIpv4Address recordAddress =
@@ -137,14 +362,13 @@
 
         LocatorBuilder locatorBuilder = new DefaultLocatorBuilder();
 
-        LispIpv4Address locatorAddress =
-                        new LispIpv4Address(IpAddress.valueOf(IP_LOCATOR_ADDRESS));
+        LispAfiAddress locatorAddress = getAfiAddress(afiType, lcafType);
 
-        LispLocator locator1 = locatorBuilder
-                                    .withPriority(UNIQUE_VALUE)
-                                    .withWeight(UNIQUE_VALUE)
-                                    .withMulticastPriority(UNIQUE_VALUE)
-                                    .withMulticastWeight(UNIQUE_VALUE)
+        LispLocator locator = locatorBuilder
+                                    .withPriority(UNIQUE_BYTE)
+                                    .withWeight(UNIQUE_BYTE)
+                                    .withMulticastPriority(UNIQUE_BYTE)
+                                    .withMulticastWeight(UNIQUE_BYTE)
                                     .withLocalLocator(true)
                                     .withRlocProbed(false)
                                     .withRouted(true)
@@ -152,13 +376,146 @@
                                     .build();
 
         return recordBuilder
-                .withRecordTtl(100)
+                .withRecordTtl(UNIQUE_INT)
                 .withIsAuthoritative(true)
-                .withMapVersionNumber((short) 1)
+                .withMapVersionNumber(UNIQUE_SHORT)
                 .withMaskLength((byte) IP_RECORD_MASK_LENGTH)
                 .withAction(LispMapReplyAction.NativelyForward)
                 .withEidPrefixAfi(recordAddress)
-                .withLocators(ImmutableList.of(locator1))
+                .withLocators(ImmutableList.of(locator))
                 .build();
     }
+
+    /**
+     * Obtains the AFI address with respect to the AFI address type.
+     *
+     * @param afiType   AFI address type
+     * @param lcafType  LCAF address type
+     * @return AFI address instance
+     */
+    private LispAfiAddress getAfiAddress(AddressFamilyIdentifierEnum afiType,
+                                         LispCanonicalAddressFormatEnum lcafType) {
+        switch (afiType) {
+            case IP4:
+                return IPV4_ADDRESS_1;
+            case IP6:
+                return IPV6_ADDRESS;
+            case AS:
+                return new LispAsAddress(UNIQUE_INT);
+            case DISTINGUISHED_NAME:
+                return new LispDistinguishedNameAddress(UNIQUE_STRING);
+            case MAC:
+                return MAC_ADDRESS;
+            case LCAF:
+                return getLcafAddress(lcafType);
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Obtains the LCAF address with respect to the LCAF type.
+     *
+     * @param type LCAF type
+     * @return LCAF address instance
+     */
+    private LispLcafAddress getLcafAddress(LispCanonicalAddressFormatEnum type) {
+
+        List<LispAfiAddress> afiAddresses =
+                                    ImmutableList.of(IPV4_ADDRESS_1, IPV6_ADDRESS);
+
+        switch (type) {
+            case LIST:
+                return new LispListLcafAddress(afiAddresses);
+            case SEGMENT:
+                return new LispSegmentLcafAddress.SegmentAddressBuilder()
+                                    .withIdMaskLength(UNIQUE_BYTE)
+                                    .withInstanceId(UNIQUE_INT)
+                                    .withAddress(IPV4_ADDRESS_1)
+                                    .build();
+            case AS:
+                return new LispAsLcafAddress.AsAddressBuilder()
+                                    .withAsNumber(UNIQUE_INT)
+                                    .withAddress(IPV4_ADDRESS_1)
+                                    .build();
+            case APPLICATION_DATA:
+                return new LispAppDataLcafAddress.AppDataAddressBuilder()
+                                    .withProtocol(UNIQUE_BYTE)
+                                    .withIpTos(UNIQUE_SHORT)
+                                    .withLocalPortLow(UNIQUE_SHORT)
+                                    .withLocalPortHigh(UNIQUE_SHORT)
+                                    .withRemotePortLow(UNIQUE_SHORT)
+                                    .withRemotePortHigh(UNIQUE_SHORT)
+                                    .withAddress(IPV4_ADDRESS_1)
+                                    .build();
+            case GEO_COORDINATE:
+                return new LispGeoCoordinateLcafAddress.GeoCoordinateAddressBuilder()
+                                    .withIsNorth(UNIQUE_BOOLEAN)
+                                    .withLatitudeDegree(UNIQUE_SHORT)
+                                    .withLatitudeMinute(UNIQUE_BYTE)
+                                    .withLatitudeSecond(UNIQUE_BYTE)
+                                    .withIsEast(UNIQUE_BOOLEAN)
+                                    .withLongitudeDegree(UNIQUE_SHORT)
+                                    .withLongitudeMinute(UNIQUE_BYTE)
+                                    .withLongitudeSecond(UNIQUE_BYTE)
+                                    .withAltitude(UNIQUE_INT)
+                                    .withAddress(IPV4_ADDRESS_1)
+                                    .build();
+            case NAT:
+                return new LispNatLcafAddress.NatAddressBuilder()
+                                    .withLength(UNIQUE_SHORT)
+                                    .withMsUdpPortNumber(UNIQUE_SHORT)
+                                    .withEtrUdpPortNumber(UNIQUE_SHORT)
+                                    .withGlobalEtrRlocAddress(IPV4_ADDRESS_1)
+                                    .withMsRlocAddress(IPV4_ADDRESS_1)
+                                    .withPrivateEtrRlocAddress(IPV4_ADDRESS_1)
+                                    .withRtrRlocAddresses(afiAddresses)
+                                    .build();
+            case NONCE:
+                return new LispNonceLcafAddress.NonceAddressBuilder()
+                                    .withNonce(UNIQUE_INT)
+                                    .withAddress(IPV4_ADDRESS_1)
+                                    .build();
+            case MULTICAST:
+                return new LispMulticastLcafAddress.MulticastAddressBuilder()
+                                    .withInstanceId(UNIQUE_INT)
+                                    .withSrcMaskLength(UNIQUE_BYTE)
+                                    .withGrpMaskLength(UNIQUE_BYTE)
+                                    .withSrcAddress(IPV4_ADDRESS_1)
+                                    .withGrpAddress(IPV4_ADDRESS_1)
+                                    .build();
+            case TRAFFIC_ENGINEERING:
+                LispTeRecord.TeRecordBuilder recordBuilder1 = new LispTeRecord.TeRecordBuilder();
+
+                recordBuilder1.withIsLookup(UNIQUE_BOOLEAN);
+                recordBuilder1.withIsRlocProbe(UNIQUE_BOOLEAN);
+                recordBuilder1.withIsStrict(UNIQUE_BOOLEAN);
+                recordBuilder1.withRtrRlocAddress(IPV4_ADDRESS_1);
+                LispTeRecord record1 = recordBuilder1.build();
+
+                LispTeRecord.TeRecordBuilder recordBuilder2 = new LispTeRecord.TeRecordBuilder();
+
+                recordBuilder2.withIsLookup(UNIQUE_BOOLEAN);
+                recordBuilder2.withIsRlocProbe(UNIQUE_BOOLEAN);
+                recordBuilder2.withIsStrict(UNIQUE_BOOLEAN);
+                recordBuilder2.withRtrRlocAddress(IPV4_ADDRESS_2);
+                LispTeRecord record2 = recordBuilder2.build();
+
+                return new LispTeLcafAddress.TeAddressBuilder()
+                                    .withTeRecords(ImmutableList.of(record1, record2))
+                                    .build();
+            case SOURCE_DEST:
+                return new LispSourceDestLcafAddress.SourceDestAddressBuilder()
+                                    .withReserved(UNIQUE_SHORT)
+                                    .withSrcMaskLength(UNIQUE_BYTE)
+                                    .withDstMaskLength(UNIQUE_BYTE)
+                                    .withSrcPrefix(IPV4_ADDRESS_1)
+                                    .withDstPrefix(IPV4_ADDRESS_2)
+                                    .build();
+            case UNKNOWN:
+            case UNSPECIFIED:
+            default:
+                return null;
+        }
+    }
 }
