// Path: hostservice/api/src/main/java/org/opendaylight/atrium/hostservice/api/ArpMessageAddress.java
// @Immutable
// public class ArpMessageAddress {
// 
//     private final MacAddress hwAddress;
//     private final Ipv4Address protocolAddress;
// 
//     public ArpMessageAddress(MacAddress hwAddress, Ipv4Address protocolAddress) {
//         this.hwAddress = checkNotNull(hwAddress);
//         this.protocolAddress = checkNotNull(protocolAddress);
//     }
// 
//     public MacAddress getHardwareAddress() {
//         return hwAddress;
//     }
// 
//     public Ipv4Address getProtocolAddress() {
//         return protocolAddress;
//     }
// 
// }
// 
// Path: hostservice/impl/src/main/java/org/opendaylight/atrium/hostservice/impl/ConfigWriter.java
// public class ConfigWriter {
// 
// 	public static void writeBgpConfigData(DataBroker dataBroker, Addresses arpAddresses) {
// 		WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
// 		transaction.put(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(Addresses.class).build(),
// 				arpAddresses);
// 		transaction.submit();
// 	}
// }


import java.net.URL;
import java.util.List;
import java.io.File;
import java.util.concurrent.ExecutionException;
import org.opendaylight.atrium.hostservice.api.ArpMessageAddress;
import org.opendaylight.atrium.hostservice.api.HostService;
import org.opendaylight.atrium.hostservice.impl.ArpSender;
import org.opendaylight.atrium.hostservice.impl.ConfigReader;
import org.opendaylight.atrium.hostservice.impl.ConfigWriter;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
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.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.ArpPacketListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.ArpPacketReceived;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.arp.packet.received.packet.chain.packet.ArpPacket;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.chain.grp.PacketChain;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.chain.grp.packet.chain.packet.RawPacket;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.ethernet.packet.fields.Header8021q;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.ethernet.packet.received.packet.chain.packet.EthernetPacket;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hostservice.api.rev150725.Addresses;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hostservice.api.rev150725.addresses.Address;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
				ethernetPacket = (EthernetPacket) packetChain.getPacket();
			} else if (packetChain.getPacket() instanceof ArpPacket) {
				arpPacket = (ArpPacket) packetChain.getPacket();
			}
		}
		if (rawPacket == null || ethernetPacket == null || arpPacket == null) {
			return;
		}

		// TODO: Need to handle Ipv6 address ?
		MacAddress sourceMac = ethernetPacket.getSourceMac();
		Ipv4Address sourceIp = new Ipv4Address(arpPacket.getSourceProtocolAddress());
		Ipv4Address destIp = new Ipv4Address(arpPacket.getDestinationProtocolAddress());
		MacAddress destMac = null;

		List<Header8021q> list = ethernetPacket.getHeader8021q();
		Header8021q vlan = null;

		if (list == null || list.isEmpty()) {
			log.debug("Untagged packet observed");
		} else {
			vlan = list.get(0);
			log.debug("Vlan tag for packet is " + vlan);
		}

		Address address = getMatchingAddress(new IpAddress(destIp));

		if (address != null) {
			destMac = address.getMac();

// Path: hostservice/api/src/main/java/org/opendaylight/atrium/hostservice/api/ArpMessageAddress.java
// @Immutable
// public class ArpMessageAddress {
// 
//     private final MacAddress hwAddress;
//     private final Ipv4Address protocolAddress;
// 
//     public ArpMessageAddress(MacAddress hwAddress, Ipv4Address protocolAddress) {
//         this.hwAddress = checkNotNull(hwAddress);
//         this.protocolAddress = checkNotNull(protocolAddress);
//     }
// 
//     public MacAddress getHardwareAddress() {
//         return hwAddress;
//     }
// 
//     public Ipv4Address getProtocolAddress() {
//         return protocolAddress;
//     }
// 
// }
// 
// Path: hostservice/impl/src/main/java/org/opendaylight/atrium/hostservice/impl/ConfigWriter.java
// public class ConfigWriter {
// 
// 	public static void writeBgpConfigData(DataBroker dataBroker, Addresses arpAddresses) {
// 		WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
// 		transaction.put(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(Addresses.class).build(),
// 				arpAddresses);
// 		transaction.submit();
// 	}
// }


// Path: hostservice/impl/src/main/java/org/opendaylight/atrium/hostservice/arp/ArpHandler.java
import java.net.URL;
import java.util.List;
import java.io.File;
import java.util.concurrent.ExecutionException;
import org.opendaylight.atrium.hostservice.api.ArpMessageAddress;
import org.opendaylight.atrium.hostservice.api.HostService;
import org.opendaylight.atrium.hostservice.impl.ArpSender;
import org.opendaylight.atrium.hostservice.impl.ConfigReader;
import org.opendaylight.atrium.hostservice.impl.ConfigWriter;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
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.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.ArpPacketListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.ArpPacketReceived;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.arp.rev140528.arp.packet.received.packet.chain.packet.ArpPacket;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.chain.grp.PacketChain;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.basepacket.rev140528.packet.chain.grp.packet.chain.packet.RawPacket;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.ethernet.packet.fields.Header8021q;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.ethernet.rev140528.ethernet.packet.received.packet.chain.packet.EthernetPacket;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hostservice.api.rev150725.Addresses;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hostservice.api.rev150725.addresses.Address;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

				ethernetPacket = (EthernetPacket) packetChain.getPacket();
			} else if (packetChain.getPacket() instanceof ArpPacket) {
				arpPacket = (ArpPacket) packetChain.getPacket();
			}
		}
		if (rawPacket == null || ethernetPacket == null || arpPacket == null) {
			return;
		}

		// TODO: Need to handle Ipv6 address ?
		MacAddress sourceMac = ethernetPacket.getSourceMac();
		Ipv4Address sourceIp = new Ipv4Address(arpPacket.getSourceProtocolAddress());
		Ipv4Address destIp = new Ipv4Address(arpPacket.getDestinationProtocolAddress());
		MacAddress destMac = null;

		List<Header8021q> list = ethernetPacket.getHeader8021q();
		Header8021q vlan = null;

		if (list == null || list.isEmpty()) {
			log.debug("Untagged packet observed");
		} else {
			vlan = list.get(0);
			log.debug("Vlan tag for packet is " + vlan);
		}

		Address address = getMatchingAddress(new IpAddress(destIp));

		if (address != null) {
			destMac = address.getMac();

			ArpMessageAddress senderArpMessageAddress = new ArpMessageAddress(destMac, destIp);