Renamed registry and packet packages

net.onrc.onos.registry.controller.* => net.onrc.onos.core.registry.*
net.onrc.onos.packet => net.onrc.onos.core.packet

Change-Id: I595e325a2c0bab709f248dde5d84ff7b6185cf8b
diff --git a/src/test/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModuleTest.java b/src/test/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModuleTest.java
index 9060a51..24aee76 100644
--- a/src/test/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModuleTest.java
+++ b/src/test/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModuleTest.java
@@ -15,13 +15,13 @@
 import net.onrc.onos.core.intent.runtime.IntentStateList;
 import net.onrc.onos.core.intent.runtime.PathCalcRuntimeModule;
 import net.onrc.onos.core.intent.runtime.PersistIntent;
+import net.onrc.onos.core.registry.IControllerRegistryService;
 import net.onrc.onos.core.topology.DeviceEvent;
 import net.onrc.onos.core.topology.INetworkGraphListener;
 import net.onrc.onos.core.topology.INetworkGraphService;
 import net.onrc.onos.core.topology.LinkEvent;
 import net.onrc.onos.core.topology.PortEvent;
 import net.onrc.onos.core.topology.SwitchEvent;
-import net.onrc.onos.registry.controller.IControllerRegistryService;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/src/test/java/net/onrc/onos/core/intent/runtime/UseCaseTest.java b/src/test/java/net/onrc/onos/core/intent/runtime/UseCaseTest.java
index b8afdf2..fe2a863 100755
--- a/src/test/java/net/onrc/onos/core/intent/runtime/UseCaseTest.java
+++ b/src/test/java/net/onrc/onos/core/intent/runtime/UseCaseTest.java
@@ -25,6 +25,7 @@
 import net.onrc.onos.core.intent.runtime.PathCalcRuntimeModule;
 import net.onrc.onos.core.intent.runtime.PersistIntent;
 import net.onrc.onos.core.intent.runtime.PlanCalcRuntime;
+import net.onrc.onos.core.registry.IControllerRegistryService;
 import net.onrc.onos.core.topology.DeviceEvent;
 import net.onrc.onos.core.topology.INetworkGraphListener;
 import net.onrc.onos.core.topology.INetworkGraphService;
@@ -32,7 +33,6 @@
 import net.onrc.onos.core.topology.NetworkGraph;
 import net.onrc.onos.core.topology.PortEvent;
 import net.onrc.onos.core.topology.SwitchEvent;
-import net.onrc.onos.registry.controller.IControllerRegistryService;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/src/test/java/net/onrc/onos/core/packet/BSNTest.java b/src/test/java/net/onrc/onos/core/packet/BSNTest.java
new file mode 100644
index 0000000..aff3285
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/packet/BSNTest.java
@@ -0,0 +1,84 @@
+/**
+*    Copyright 2011, Big Switch Networks, Inc. 
+*    Originally created by David Erickson, Stanford University
+* 
+*    Licensed under the Apache License, Version 2.0 (the "License"); you may
+*    not use this file except in compliance with the License. You may obtain
+*    a copy of the License at
+*
+*         http://www.apache.org/licenses/LICENSE-2.0
+*
+*    Unless required by applicable law or agreed to in writing, software
+*    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+*    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+*    License for the specific language governing permissions and limitations
+*    under the License.
+**/
+
+/**
+ *
+ */
+package net.onrc.onos.core.packet;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+
+import net.onrc.onos.core.packet.BSN;
+import net.onrc.onos.core.packet.BSNPROBE;
+import net.onrc.onos.core.packet.Ethernet;
+
+import org.junit.Test;
+
+/**
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ *
+ */
+public class BSNTest {       
+    protected byte[] probePkt = {
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // src mac
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x04, // dst mac
+		(byte) 0x89, 0x42, // BSN type
+        0x20, 0x00, 0x06, 0x04, 0x00, 0x01, 0x00, 0x00, // BSN header
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // controller id
+		0x00, 0x00, 0x00, 0x03, // sequence id
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // src mac
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x04, // dst mac
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, // switch dpid
+		0x00, 0x00, 0x00, 0x01 // port number
+    };
+    
+    protected Ethernet getProbePacket() {
+        return (Ethernet) new Ethernet()
+            .setSourceMACAddress("00:00:00:00:00:04")
+            .setDestinationMACAddress("00:00:00:00:00:01")
+            .setEtherType(Ethernet.TYPE_BSN)
+            .setPayload(new BSN(BSN.BSN_TYPE_PROBE)
+	            .setPayload(new BSNPROBE()
+		            .setSequenceId(3)
+		            .setSrcMac(new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x01})
+		            .setDstMac(new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x04})
+		            .setSrcSwDpid(0x06)
+		            .setSrcPortNo(0x01)
+		            )
+	            );
+    }
+
+    @Test
+    public void testSerialize() throws Exception {
+        Ethernet pkt = getProbePacket();
+        byte[] serialized = pkt.serialize();
+        assertTrue(Arrays.equals(probePkt, serialized));
+    }
+
+    @Test
+    public void testDeserialize() throws Exception {
+        Ethernet pkt = (Ethernet) new Ethernet().deserialize(probePkt, 0, probePkt.length);
+        assertTrue(Arrays.equals(probePkt, pkt.serialize()));
+
+        Ethernet expected = getProbePacket();
+        assertEquals(expected, pkt);
+    }
+}
diff --git a/src/test/java/net/onrc/onos/core/packet/DHCPTest.java b/src/test/java/net/onrc/onos/core/packet/DHCPTest.java
new file mode 100644
index 0000000..66855d1
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/packet/DHCPTest.java
@@ -0,0 +1,600 @@
+/**
+*    Copyright 2011, Big Switch Networks, Inc. 
+*    Originally created by David Erickson, Stanford University
+* 
+*    Licensed under the Apache License, Version 2.0 (the "License"); you may
+*    not use this file except in compliance with the License. You may obtain
+*    a copy of the License at
+*
+*         http://www.apache.org/licenses/LICENSE-2.0
+*
+*    Unless required by applicable law or agreed to in writing, software
+*    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+*    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+*    License for the specific language governing permissions and limitations
+*    under the License.
+**/
+
+/**
+ * 
+ */
+package net.onrc.onos.core.packet;
+
+
+
+import java.util.Arrays;
+import java.util.ListIterator;
+
+import net.onrc.onos.core.packet.DHCP;
+import net.onrc.onos.core.packet.DHCPOption;
+import net.onrc.onos.core.packet.Ethernet;
+import net.onrc.onos.core.packet.IPv4;
+import net.onrc.onos.core.packet.UDP;
+import junit.framework.TestCase;
+
+
+/**
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ *
+ */
+public class DHCPTest extends TestCase {
+    public byte[] dhcpPacket = new byte[] {
+            (byte) 0x01, (byte) 0x01,
+            (byte) 0x06, (byte) 0x00, (byte) 0x66, (byte) 0xf2, (byte) 0x8a,
+            (byte) 0x11, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x9f, (byte) 0x9f,
+            (byte) 0xfe, (byte) 0xd8, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x63,
+            (byte) 0x82, (byte) 0x53, (byte) 0x63, (byte) 0x35, (byte) 0x01,
+            (byte) 0x01, (byte) 0x37, (byte) 0x0a, (byte) 0x01, (byte) 0x1c,
+            (byte) 0x02, (byte) 0x03, (byte) 0x0f, (byte) 0x06, (byte) 0x0c,
+            (byte) 0x28, (byte) 0x29, (byte) 0x2a, (byte) 0xff, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00
+    };
+
+    public byte[] dhcpPacket2 = new byte[] { (byte) 0xff, (byte) 0xff,
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00,
+            (byte) 0xc0, (byte) 0x9f, (byte) 0x9e, (byte) 0x11, (byte) 0x84,
+            (byte) 0x08, (byte) 0x00, (byte) 0x45, (byte) 0x00, (byte) 0x02,
+            (byte) 0x40, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x00,
+            (byte) 0x14, (byte) 0x11, (byte) 0xa4, (byte) 0xaa, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0xff,
+            (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x44, (byte) 0x00,
+            (byte) 0x43, (byte) 0x02, (byte) 0x2c, (byte) 0xdd, (byte) 0x9d,
+            (byte) 0x01, (byte) 0x01, (byte) 0x06, (byte) 0x00, (byte) 0xa4,
+            (byte) 0x9e, (byte) 0x11, (byte) 0x84, (byte) 0x00, (byte) 0x40,
+            (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc0,
+            (byte) 0x9f, (byte) 0x9e, (byte) 0x11, (byte) 0x84, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x63, (byte) 0x82, (byte) 0x53, (byte) 0x63,
+            (byte) 0x35, (byte) 0x01, (byte) 0x01, (byte) 0x37, (byte) 0x18,
+            (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x05, (byte) 0x06,
+            (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0f, (byte) 0x10,
+            (byte) 0x11, (byte) 0x12, (byte) 0x2b, (byte) 0x36, (byte) 0x3c,
+            (byte) 0x43, (byte) 0x80, (byte) 0x81, (byte) 0x82, (byte) 0x83,
+            (byte) 0x84, (byte) 0x85, (byte) 0x86, (byte) 0x87, (byte) 0x39,
+            (byte) 0x02, (byte) 0x04, (byte) 0xec, (byte) 0x61, (byte) 0x11,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x5d, (byte) 0x02, (byte) 0x00,
+            (byte) 0x00, (byte) 0x5e, (byte) 0x03, (byte) 0x01, (byte) 0x02,
+            (byte) 0x01, (byte) 0x3c, (byte) 0x20, (byte) 0x50, (byte) 0x58,
+            (byte) 0x45, (byte) 0x43, (byte) 0x6c, (byte) 0x69, (byte) 0x65,
+            (byte) 0x6e, (byte) 0x74, (byte) 0x3a, (byte) 0x41, (byte) 0x72,
+            (byte) 0x63, (byte) 0x68, (byte) 0x3a, (byte) 0x30, (byte) 0x30,
+            (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x3a, (byte) 0x55,
+            (byte) 0x4e, (byte) 0x44, (byte) 0x49, (byte) 0x3a, (byte) 0x30,
+            (byte) 0x30, (byte) 0x32, (byte) 0x30, (byte) 0x30, (byte) 0x31,
+            (byte) 0xff, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00 };
+    
+    public byte[] dhcpPacket3 = new byte[] { 
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+            (byte) 0xff, (byte) 0x74, (byte) 0x44, (byte) 0x01, (byte) 0x72, 
+            (byte) 0xd8, (byte) 0x41, (byte) 0x08, (byte) 0x00, (byte) 0x45, 
+            (byte) 0x00, (byte) 0x01, (byte) 0x1f, (byte) 0x48, (byte) 0xcd, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x11, (byte) 0x6f, 
+            (byte) 0x6a, (byte) 0xc0, (byte) 0xa8, (byte) 0x00, (byte) 0xef, 
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, 
+            (byte) 0x44, (byte) 0x00, (byte) 0x43, (byte) 0x01, (byte) 0x0b, 
+            (byte) 0xb3, (byte) 0x0f, (byte) 0x01, (byte) 0x01, (byte) 0x06, 
+            (byte) 0x00, (byte) 0x82, (byte) 0x88, (byte) 0xa6, (byte) 0xc9, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x74, (byte) 0x44, (byte) 0x01, (byte) 0x72, (byte) 0xd8, 
+            (byte) 0x41, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x63, (byte) 0x82, 
+            (byte) 0x53, (byte) 0x63, (byte) 0x35, (byte) 0x01, (byte) 0x01, 
+            (byte) 0x32, (byte) 0x04, (byte) 0xc0, (byte) 0xa8, (byte) 0x0a, 
+            (byte) 0xa9, (byte) 0x39, (byte) 0x02, (byte) 0x02, (byte) 0x40, 
+            (byte) 0x37, (byte) 0x03, (byte) 0x01, (byte) 0x03, (byte) 0x06, 
+            (byte) 0xff                               
+    };
+    
+    public byte[] dhcpPacketPXE = new byte[] { (byte) 0xff, (byte) 0xff,
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00,
+            (byte) 0x19, (byte) 0xb9, (byte) 0xb0, (byte) 0x01, (byte) 0x44,
+            (byte) 0x08, (byte) 0x00, (byte) 0x45, (byte) 0x10, (byte) 0x01,
+            (byte) 0x48, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x80, (byte) 0x11, (byte) 0x2c, (byte) 0x98, (byte) 0x0a,
+            (byte) 0x00, (byte) 0x02, (byte) 0xfe, (byte) 0xff, (byte) 0xff,
+            (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x43, (byte) 0x00,
+            (byte) 0x44, (byte) 0x01, (byte) 0x34, (byte) 0xa6, (byte) 0xf0,
+            (byte) 0x02, (byte) 0x01, (byte) 0x06, (byte) 0x00, (byte) 0xa0,
+            (byte) 0x9e, (byte) 0x0c, (byte) 0x13, (byte) 0x00, (byte) 0x04,
+            (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x0a, (byte) 0x00, (byte) 0x02, (byte) 0x14,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc0,
+            (byte) 0x9f, (byte) 0x9e, (byte) 0x0c, (byte) 0x13, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x78, (byte) 0x65,
+            (byte) 0x6e, (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x76,
+            (byte) 0x65, (byte) 0x72, (byte) 0x5f, (byte) 0x35, (byte) 0x2e,
+            (byte) 0x36, (byte) 0x2f, (byte) 0x70, (byte) 0x78, (byte) 0x65,
+            (byte) 0x6c, (byte) 0x69, (byte) 0x6e, (byte) 0x75, (byte) 0x78,
+            (byte) 0x2e, (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x63, (byte) 0x82, (byte) 0x53, (byte) 0x63,
+            (byte) 0x35, (byte) 0x01, (byte) 0x02, (byte) 0x36, (byte) 0x04,
+            (byte) 0x0a, (byte) 0x00, (byte) 0x02, (byte) 0xfe, (byte) 0x33,
+            (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0xa8, (byte) 0xc0,
+            (byte) 0x01, (byte) 0x04, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+            (byte) 0x00, (byte) 0x03, (byte) 0x04, (byte) 0x0a, (byte) 0x00,
+            (byte) 0x02, (byte) 0xfe, (byte) 0x0c, (byte) 0x0d, (byte) 0x64,
+            (byte) 0x6e, (byte) 0x72, (byte) 0x63, (byte) 0x2d, (byte) 0x68,
+            (byte) 0x6f, (byte) 0x73, (byte) 0x74, (byte) 0x30, (byte) 0x30,
+            (byte) 0x32, (byte) 0x30, (byte) 0xff, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
+    };
+
+    public byte[] dhcpPacketBadOption1 = new byte[] { (byte) 0xff, (byte) 0xff,
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00,
+            (byte) 0x19, (byte) 0xb9, (byte) 0xb0, (byte) 0x01, (byte) 0x44,
+            (byte) 0x08, (byte) 0x00, (byte) 0x45, (byte) 0x10, (byte) 0x01,
+            (byte) 0x48, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x80, (byte) 0x11, (byte) 0x2c, (byte) 0x98, (byte) 0x0a,
+            (byte) 0x00, (byte) 0x02, (byte) 0xfe, (byte) 0xff, (byte) 0xff,
+            (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x44, (byte) 0x00,
+            (byte) 0x43, (byte) 0x01, (byte) 0x34, (byte) 0xa6, (byte) 0xf0,
+            (byte) 0x02, (byte) 0x01, (byte) 0x06, (byte) 0x00, (byte) 0xa0,
+            (byte) 0x9e, (byte) 0x0c, (byte) 0x13, (byte) 0x00, (byte) 0x04,
+            (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x0a, (byte) 0x00, (byte) 0x02, (byte) 0x14,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc0,
+            (byte) 0x9f, (byte) 0x9e, (byte) 0x0c, (byte) 0x13, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x78, (byte) 0x65,
+            (byte) 0x6e, (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x76,
+            (byte) 0x65, (byte) 0x72, (byte) 0x5f, (byte) 0x35, (byte) 0x2e,
+            (byte) 0x36, (byte) 0x2f, (byte) 0x70, (byte) 0x78, (byte) 0x65,
+            (byte) 0x6c, (byte) 0x69, (byte) 0x6e, (byte) 0x75, (byte) 0x78,
+            (byte) 0x2e, (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x63, (byte) 0x82, (byte) 0x53, (byte) 0x63,
+            (byte) 0x35, (byte) 0x01, (byte) 0x01, (byte) 0x36, (byte) 0x04,
+            (byte) 0x0a, (byte) 0x00, (byte) 0x02, (byte) 0xfe, (byte) 0x33,
+            (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0xa8, (byte) 0xc0,
+            (byte) 0x01, (byte) 0x04, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+            (byte) 0x00, (byte) 0x03, (byte) 0x04, (byte) 0x0a, (byte) 0x00,
+            (byte) 0x02, (byte) 0xfe, (byte) 0x0c, (byte) 0x30, (byte) 0x64,
+            (byte) 0x6e, (byte) 0x72, (byte) 0x63, (byte) 0x2d, (byte) 0x68,
+            (byte) 0x6f, (byte) 0x73, (byte) 0x74, (byte) 0x30, (byte) 0x30,
+            (byte) 0x32, (byte) 0x30, (byte) 0xff, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
+    };
+    
+    public byte[] dhcpPacketBadHeader = new byte[] { (byte) 0xff, (byte) 0xff,
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00,
+            (byte) 0x19, (byte) 0xb9, (byte) 0xb0, (byte) 0x01, (byte) 0x44,
+            (byte) 0x08, (byte) 0x00, (byte) 0x45, (byte) 0x10, (byte) 0x01,
+            (byte) 0x48, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x80, (byte) 0x11, (byte) 0x2c, (byte) 0x98, (byte) 0x0a,
+            (byte) 0x00, (byte) 0x02, (byte) 0xfe, (byte) 0xff, (byte) 0xff,
+            (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x44, (byte) 0x00,
+            (byte) 0x43, (byte) 0x01, (byte) 0x34, (byte) 0xa6, (byte) 0xf0,
+            (byte) 0x02, (byte) 0x01, (byte) 0x06, (byte) 0x00, (byte) 0xa0,
+            (byte) 0x9e, (byte) 0x0c, (byte) 0x13, (byte) 0x00, (byte) 0x04,
+            (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x0a, (byte) 0x00, (byte) 0x02, (byte) 0x14,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc0,
+            (byte) 0x9f, (byte) 0x9e, (byte) 0x0c, (byte) 0x13, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x78, (byte) 0x65,
+            (byte) 0x6e, (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x76,
+            (byte) 0x65, (byte) 0x72, (byte) 0x5f, (byte) 0x35, (byte) 0x2e,
+            (byte) 0x36, (byte) 0x2f, (byte) 0x70, (byte) 0x78, (byte) 0x65,
+            (byte) 0x6c, (byte) 0x69, (byte) 0x6e, (byte) 0x75, (byte) 0x78,
+            (byte) 0x2e, (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
+    };
+    
+    private void resetChecksumsAndLengths(IPv4 ipv4, UDP udp) {
+        ipv4.setChecksum((short)0);
+        udp.setChecksum((short)0);
+    }
+    
+    public void testSerialize() {
+        DHCP dhcp = new DHCP();
+        dhcp.deserialize(dhcpPacket, 0, dhcpPacket.length);
+        byte[] result = dhcp.serialize();
+        assertTrue(Arrays.equals(this.dhcpPacket, result));
+    }
+
+    public void testDeSerialize() {
+        Ethernet eth = new Ethernet();
+        eth.deserialize(dhcpPacket2, 0, dhcpPacket2.length);
+        assertTrue(eth.getPayload() instanceof IPv4);
+        IPv4 ipv4 = (IPv4) eth.getPayload();
+        assertTrue(ipv4.getPayload() instanceof UDP);
+        UDP udp = (UDP) ipv4.getPayload();
+        assertTrue(udp.getPayload() instanceof DHCP);
+        DHCP dhcp = (DHCP) udp.getPayload();
+        /** The invalid option in DHCP packet is dropped. Reset checksums and
+         *  length field so that the serialize() function can re-compute them
+         */
+        resetChecksumsAndLengths(ipv4, udp);
+        assertEquals(DHCP.OPCODE_REQUEST, dhcp.getOpCode());
+    }
+    
+    public void testDeSerializeReSerialize() {
+        Ethernet eth = new Ethernet();
+        eth.deserialize(dhcpPacket3, 0, dhcpPacket3.length);
+        assertTrue(eth.getPayload() instanceof IPv4);
+        IPv4 ipv4 = (IPv4) eth.getPayload();
+        assertTrue(ipv4.getPayload() instanceof UDP);
+        
+        byte[] serializedPacket = eth.serialize();
+        Ethernet eth2 = new Ethernet();
+        eth2.deserialize(serializedPacket, 0, serializedPacket.length);
+        IPv4 ipv42 = (IPv4) eth2.getPayload();
+
+        short ipchecksum = ipv42.getChecksum();
+        ipv42.setChecksum((short) 0);
+        eth2.serialize();        
+        assertEquals(ipchecksum, ipv42.getChecksum());
+    }
+
+    public void testDeSerializePXE() {
+        Ethernet eth = new Ethernet();
+        eth.deserialize(dhcpPacketPXE, 0, dhcpPacketPXE.length);
+        assertTrue(eth.getPayload() instanceof IPv4);
+        IPv4 ipv4 = (IPv4) eth.getPayload();
+        assertTrue(ipv4.getPayload() instanceof UDP);
+        UDP udp = (UDP) ipv4.getPayload();
+        assertTrue(udp.getPayload() instanceof DHCP);
+        DHCP dhcp = (DHCP) udp.getPayload();
+        /** The invalid option in DHCP packet is dropped. Reset checksums and
+         *  length field so that the serialize() function can re-compute them
+         */
+        resetChecksumsAndLengths(ipv4, udp);
+        
+        assertEquals(DHCP.OPCODE_REPLY, dhcp.getOpCode());
+        assertEquals("xenserver_5.6/pxelinux.0", dhcp.getBootFileName());
+
+        byte[] result = eth.serialize();
+        assertTrue(Arrays.equals(this.dhcpPacketPXE, result));
+    }
+    
+    public void testDeSerializeBad1() {
+        Ethernet eth = new Ethernet();
+        eth.deserialize(dhcpPacketBadOption1, 0, dhcpPacketBadOption1.length);
+        assertTrue(eth.getPayload() instanceof IPv4);
+        IPv4 ipv4 = (IPv4) eth.getPayload();
+        assertTrue(ipv4.getPayload() instanceof UDP);
+        UDP udp = (UDP) ipv4.getPayload();
+        assertTrue(udp.getPayload() instanceof DHCP);
+        DHCP dhcp = (DHCP) udp.getPayload();
+        /** The invalid option in DHCP packet is dropped. Reset checksums and
+         *  length field so that the serialize() function can re-compute them
+         */
+        resetChecksumsAndLengths(ipv4, udp);
+        
+        assertEquals(DHCP.OPCODE_REPLY, dhcp.getOpCode());
+        ListIterator<DHCPOption> lit = dhcp.getOptions().listIterator();
+        // Expect 5 correct options and an END option.
+        assertEquals(dhcp.getOptions().size(), 6);
+        while (lit.hasNext()) {
+            DHCPOption option = lit.next();
+            assertFalse(option.code == (byte)0x0c);
+        }
+
+        byte[] result = eth.serialize();
+        // Since one option is badly formated, the result is different.
+        assertFalse(Arrays.equals(this.dhcpPacketPXE, result));
+    }
+    
+    public void testDeSerializeBadHeader() {
+        Ethernet eth = new Ethernet();
+        eth.deserialize(dhcpPacketBadHeader, 0, dhcpPacketBadHeader.length);
+        assertTrue(eth.getPayload() instanceof IPv4);
+        IPv4 ipv4 = (IPv4) eth.getPayload();
+        assertTrue(ipv4.getPayload() instanceof UDP);
+        UDP udp = (UDP) ipv4.getPayload();
+        assertTrue(udp.getPayload() instanceof DHCP);
+        DHCP dhcp = (DHCP) udp.getPayload();
+
+        assertEquals(UDP.DHCP_CLIENT_PORT, udp.getSourcePort());
+        assertEquals(UDP.DHCP_SERVER_PORT, udp.getDestinationPort());
+        
+        // should get invalid opCode of 0
+        assertEquals(0, dhcp.getOpCode());
+    }
+}
diff --git a/src/test/java/net/onrc/onos/core/packet/EthernetTest.java b/src/test/java/net/onrc/onos/core/packet/EthernetTest.java
new file mode 100644
index 0000000..6293a43
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/packet/EthernetTest.java
@@ -0,0 +1,77 @@
+/**
+*    Copyright 2011, Big Switch Networks, Inc. 
+*    Originally created by David Erickson, Stanford University
+* 
+*    Licensed under the Apache License, Version 2.0 (the "License"); you may
+*    not use this file except in compliance with the License. You may obtain
+*    a copy of the License at
+*
+*         http://www.apache.org/licenses/LICENSE-2.0
+*
+*    Unless required by applicable law or agreed to in writing, software
+*    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+*    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+*    License for the specific language governing permissions and limitations
+*    under the License.
+**/
+
+/**
+ * 
+ */
+package net.onrc.onos.core.packet;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+
+import net.onrc.onos.core.packet.Ethernet;
+
+import org.junit.Test;
+
+/**
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ *
+ */
+public class EthernetTest {
+    @Test
+    public void testToMACAddress() {
+        byte[] address = new byte[] { 0x0, 0x11, 0x22, (byte) 0xff,
+                (byte) 0xee, (byte) 0xdd};
+        assertTrue(Arrays.equals(address, Ethernet
+                .toMACAddress("00:11:22:ff:ee:dd")));
+        assertTrue(Arrays.equals(address, Ethernet
+                .toMACAddress("00:11:22:FF:EE:DD")));
+    }
+
+    @Test
+    public void testSerialize() {
+        Ethernet ethernet = new Ethernet()
+            .setDestinationMACAddress("de:ad:be:ef:de:ad")
+            .setSourceMACAddress("be:ef:de:ad:be:ef")
+            .setEtherType((short) 0);
+        byte[] expected = new byte[] { (byte) 0xde, (byte) 0xad, (byte) 0xbe,
+                (byte) 0xef, (byte) 0xde, (byte) 0xad, (byte) 0xbe,
+                (byte) 0xef, (byte) 0xde, (byte) 0xad, (byte) 0xbe,
+                (byte) 0xef, 0x0, 0x0 };
+        assertTrue(Arrays.equals(expected, ethernet.serialize()));
+    }
+
+    @Test
+    public void testToLong() {
+        assertEquals(
+                281474976710655L,
+                Ethernet.toLong(new byte[] { (byte) 0xff, (byte) 0xff,
+                        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }));
+
+        assertEquals(
+                1103823438081L,
+                Ethernet.toLong(new byte[] { (byte) 0x01, (byte) 0x01,
+                        (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01 }));
+
+        assertEquals(
+                141289400074368L,
+                Ethernet.toLong(new byte[] { (byte) 0x80, (byte) 0x80,
+                        (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80 }));
+    }
+}
diff --git a/src/test/java/net/onrc/onos/core/packet/ICMPTest.java b/src/test/java/net/onrc/onos/core/packet/ICMPTest.java
new file mode 100644
index 0000000..e09ae24
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/packet/ICMPTest.java
@@ -0,0 +1,72 @@
+/**
+*    Copyright 2011, Big Switch Networks, Inc. 
+*    Originally created by David Erickson, Stanford University
+* 
+*    Licensed under the Apache License, Version 2.0 (the "License"); you may
+*    not use this file except in compliance with the License. You may obtain
+*    a copy of the License at
+*
+*         http://www.apache.org/licenses/LICENSE-2.0
+*
+*    Unless required by applicable law or agreed to in writing, software
+*    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+*    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+*    License for the specific language governing permissions and limitations
+*    under the License.
+**/
+
+/**
+ * 
+ */
+package net.onrc.onos.core.packet;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+
+import net.onrc.onos.core.packet.Data;
+import net.onrc.onos.core.packet.ICMP;
+import net.onrc.onos.core.packet.IPacket;
+import net.onrc.onos.core.packet.IPv4;
+
+import org.junit.Test;
+
+/**
+ * @author shudong.zhou@bigswitch.com
+ */
+public class ICMPTest {
+    private byte[] pktSerialized = new byte[] {
+            // (byte) 0xc8, 0x2a, 0x14, 0x2d, 0x35, (byte) 0xf1,
+            // 0x00, 0x0c, 0x29, 0x3b, (byte) 0x95, (byte) 0xf2, 0x08, 0x0,
+            0x45, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01,
+            (byte) 0xa3, (byte) 0xcb,
+            (byte) 0xc0, (byte) 0xa8, (byte) 0x0a, (byte) 0xe7,
+            (byte) 0xc0, (byte) 0xa8, (byte) 0x0a, (byte) 0xdb,
+            0x08, 0x00, 0x7f, 0x0a, 0x76, (byte) 0xf2, 0x00, 0x02,
+            0x01, 0x01, 0x01 };
+    @Test
+    public void testSerialize() {
+        IPacket packet = new IPv4()
+            .setIdentification((short) 0)
+            .setFlags((byte) 0x02)
+            .setTtl((byte) 64)
+            .setSourceAddress("192.168.10.231")
+            .setDestinationAddress("192.168.10.219")
+            .setPayload(new ICMP()
+                            .setIcmpType((byte) 8)
+                            .setIcmpCode((byte) 0)
+                            .setPayload(new Data(new byte[]
+                                        {0x76, (byte) 0xf2, 0x0, 0x2, 0x1, 0x1, 0x1}))
+                       );
+        byte[] actual = packet.serialize();
+        assertTrue(Arrays.equals(pktSerialized, actual));
+    }
+    
+    @Test
+    public void testDeserialize() {
+        IPacket packet = new IPv4();
+        packet.deserialize(pktSerialized, 0, pktSerialized.length);
+        byte[] pktSerialized1 = packet.serialize();
+        assertTrue(Arrays.equals(pktSerialized, pktSerialized1));
+    }
+}
diff --git a/src/test/java/net/onrc/onos/core/packet/IPv4Test.java b/src/test/java/net/onrc/onos/core/packet/IPv4Test.java
new file mode 100644
index 0000000..3c47ffb
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/packet/IPv4Test.java
@@ -0,0 +1,90 @@
+/**
+*    Copyright 2011, Big Switch Networks, Inc. 
+*    Originally created by David Erickson, Stanford University
+* 
+*    Licensed under the Apache License, Version 2.0 (the "License"); you may
+*    not use this file except in compliance with the License. You may obtain
+*    a copy of the License at
+*
+*         http://www.apache.org/licenses/LICENSE-2.0
+*
+*    Unless required by applicable law or agreed to in writing, software
+*    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+*    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+*    License for the specific language governing permissions and limitations
+*    under the License.
+**/
+
+/**
+ * 
+ */
+package net.onrc.onos.core.packet;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+
+import net.onrc.onos.core.packet.IPv4;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ *
+ */
+public class IPv4Test {
+    @Test
+    public void testToIPv4Address() {
+        int intIp = 0xc0a80001;
+        String stringIp = "192.168.0.1";
+        byte[] byteIp = new byte[] {(byte)192, (byte)168, (byte)0, (byte)1};
+        assertEquals(intIp, IPv4.toIPv4Address(stringIp));
+        assertEquals(intIp, IPv4.toIPv4Address(byteIp));
+        assertTrue(Arrays.equals(byteIp, IPv4.toIPv4AddressBytes(intIp)));
+        assertTrue(Arrays.equals(byteIp, IPv4.toIPv4AddressBytes(stringIp)));
+    }
+
+    @Test
+    public void testToIPv4AddressBytes() {
+        byte[] expected = new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
+        Assert.assertArrayEquals(expected, IPv4.toIPv4AddressBytes("255.255.255.255"));
+        expected = new byte[] {(byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80};
+        Assert.assertArrayEquals(expected, IPv4.toIPv4AddressBytes("128.128.128.128"));
+        expected = new byte[] {0x7f,0x7f,0x7f,0x7f};
+        Assert.assertArrayEquals(expected, IPv4.toIPv4AddressBytes("127.127.127.127"));
+    }
+
+    @Test
+    public void testSerialize() {
+        byte[] expected = new byte[] { 0x45, 0x00, 0x00, 0x14, 0x5e, 0x4e,
+                0x00, 0x00, 0x3f, 0x06, 0x31, 0x2e, (byte) 0xac, 0x18,
+                0x4a, (byte) 0xdf, (byte) 0xab, 0x40, 0x4a, 0x30 };
+        IPv4 packet = new IPv4()
+            .setIdentification((short) 24142)
+            .setTtl((byte) 63)
+            .setProtocol((byte) 0x06)
+            .setSourceAddress("172.24.74.223")
+            .setDestinationAddress("171.64.74.48");
+        byte[] actual = packet.serialize();
+        assertTrue(Arrays.equals(expected, actual));
+    }
+    
+    @Test
+    public void testDeserialize() {
+        // A real TLSv1 packet
+        byte[] pktSerialized = new byte[] { 0x45, 0x00,
+                0x00, 0x2e, 0x41, (byte) 0xbe, 0x40, 0x00, 0x40, 0x06,
+                (byte) 0xd4, (byte) 0xf0, (byte) 0xc0, (byte) 0xa8, 0x02, (byte) 0xdb, (byte) 0xd0, 0x55,
+                (byte) 0x90, 0x42, (byte) 0xd5, 0x48, 0x01, (byte) 0xbb, (byte) 0xe3, 0x50,
+                (byte) 0xb2, 0x2f, (byte) 0xfc, (byte) 0xf8, (byte) 0xa8, 0x2c, 0x50, 0x18,
+                (byte) 0xff, (byte) 0xff, 0x24, 0x3c, 0x00, 0x00, 0x14, 0x03,
+                0x01, 0x00, 0x01, 0x01
+        };
+        IPv4 packet = new IPv4();
+        packet.deserialize(pktSerialized, 0, pktSerialized.length);
+        byte[] pktSerialized1 = packet.serialize();
+        assertTrue(Arrays.equals(pktSerialized, pktSerialized1));
+    }
+}
diff --git a/src/test/java/net/onrc/onos/core/packet/LLDPOrganizationalTLVTest.java b/src/test/java/net/onrc/onos/core/packet/LLDPOrganizationalTLVTest.java
new file mode 100644
index 0000000..a887038
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/packet/LLDPOrganizationalTLVTest.java
@@ -0,0 +1,97 @@
+/**
+ *    Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *    not use this file except in compliance with the License. You may obtain
+ *    a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ *    License for the specific language governing permissions and limitations
+ *    under the License.
+ **/
+
+package net.onrc.onos.core.packet;
+
+import net.onrc.onos.core.packet.LLDPOrganizationalTLV;
+
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public class LLDPOrganizationalTLVTest {
+    private final byte[] expected = new byte[] {
+        //  Type: 127, Length: 13
+        (byte) 254, 13,
+        // OpenFlow OUI: 00-26-E1
+        0x0, 0x26, (byte)0xe1,
+        //  SubType: 12
+        0xc,
+        //  Bytes in "ExtraInfo"
+        0x45, 0x78, 0x74, 0x72, 0x61, 0x49, 0x6e, 0x66, 0x6f
+    };
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testShortOUI() {
+        LLDPOrganizationalTLV tlv = new LLDPOrganizationalTLV();
+        tlv.setOUI(new byte[2]);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testLongOUI() {
+        LLDPOrganizationalTLV tlv = new LLDPOrganizationalTLV();
+        tlv.setOUI(new byte[4]);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testLongInfoString() {
+        LLDPOrganizationalTLV tlv = new LLDPOrganizationalTLV();
+        tlv.setInfoString(new byte[LLDPOrganizationalTLV.MAX_INFOSTRING_LENGTH + 1]);
+    }
+
+    @Test
+    public void testMaxInfoString() {
+        LLDPOrganizationalTLV tlv = new LLDPOrganizationalTLV();
+        tlv.setInfoString(new byte[LLDPOrganizationalTLV.MAX_INFOSTRING_LENGTH]);
+    }
+
+    @Test
+    public void testInfoString() {
+        LLDPOrganizationalTLV tlv = new LLDPOrganizationalTLV();
+        tlv.setInfoString("ExtraInfo");
+        assertThat(tlv.getInfoString(), is("ExtraInfo".getBytes(Charset.forName("UTF-8"))));
+    }
+
+    @Test
+    public void testSerialize() {
+        LLDPOrganizationalTLV tlv = new LLDPOrganizationalTLV();
+        tlv.setLength((short) 13);
+        // OpenFlow OUI is 00-26-E1
+        tlv.setOUI(new byte[] {0x0, 0x26, (byte) 0xe1});
+        tlv.setSubType((byte) 12);
+        tlv.setInfoString("ExtraInfo".getBytes(Charset.forName("UTF-8")));
+
+        assertThat(tlv.getType(), is((byte)127));
+        assertThat(tlv.getLength(), is((short)13));
+        assertThat(tlv.getOUI(), is(new byte[] {0x0, 0x26, (byte) 0xe1}));
+        assertThat(tlv.getSubType(), is((byte)12));
+        assertThat(tlv.serialize(), is(expected));
+    }
+
+    @Test
+    public void testDeserialize() {
+        LLDPOrganizationalTLV tlv = new LLDPOrganizationalTLV();
+        tlv.deserialize(ByteBuffer.wrap(expected));
+
+        assertThat(tlv.getType(), is((byte)127));
+        assertThat(tlv.getLength(), is((short)13));
+        assertThat(tlv.getOUI(), is(new byte[] {0x0, 0x26, (byte) 0xe1}));
+        assertThat(tlv.getSubType(), is((byte)12));
+        assertThat(tlv.getInfoString(), is("ExtraInfo".getBytes(Charset.forName("UTF-8"))));
+    }
+}
diff --git a/src/test/java/net/onrc/onos/core/packet/LLDPTest.java b/src/test/java/net/onrc/onos/core/packet/LLDPTest.java
new file mode 100755
index 0000000..6ef83e2
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/packet/LLDPTest.java
@@ -0,0 +1,76 @@
+/**
+*    Copyright 2011, Big Switch Networks, Inc. 
+*    Originally created by David Erickson, Stanford University
+* 
+*    Licensed under the Apache License, Version 2.0 (the "License"); you may
+*    not use this file except in compliance with the License. You may obtain
+*    a copy of the License at
+*
+*         http://www.apache.org/licenses/LICENSE-2.0
+*
+*    Unless required by applicable law or agreed to in writing, software
+*    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+*    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+*    License for the specific language governing permissions and limitations
+*    under the License.
+**/
+
+/**
+ *
+ */
+package net.onrc.onos.core.packet;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+
+import net.onrc.onos.core.packet.Ethernet;
+import net.onrc.onos.core.packet.IPacket;
+import net.onrc.onos.core.packet.LLDP;
+import net.onrc.onos.core.packet.LLDPTLV;
+
+import org.junit.Test;
+
+/**
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ *
+ */
+public class LLDPTest {
+    protected byte[] pkt = {0x01,0x23,0x20,0x00,0x00,0x01,0x00,0x12,(byte) 0xe2,0x78,0x67,0x78,(byte) 0x88,(byte) 0xcc,0x02,0x07,
+            0x04,0x00,0x12,(byte) 0xe2,0x78,0x67,0x64,0x04,0x03,0x02,0x00,0x06,0x06,0x02,0x00,0x78,
+            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+
+    protected IPacket getPacket() {
+        return new Ethernet()
+        .setPad(true)
+        .setDestinationMACAddress("01:23:20:00:00:01")
+        .setSourceMACAddress("00:12:e2:78:67:78")
+        .setEtherType(Ethernet.TYPE_LLDP)
+        .setPayload(
+                new LLDP()
+                .setChassisId(new LLDPTLV().setType((byte) 1).setLength((short) 7).setValue(new byte[] {0x04, 0x00, 0x12, (byte) 0xe2, 0x78, 0x67, 0x64}))
+                .setPortId(new LLDPTLV().setType((byte) 2).setLength((short) 3).setValue(new byte[] {0x02, 0x00, 0x06}))
+                .setTtl(new LLDPTLV().setType((byte) 3).setLength((short) 2).setValue(new byte[] {0x00, 0x78}))
+            
+        );
+    }
+
+    @Test
+    public void testSerialize() throws Exception {
+        IPacket ethernet = getPacket();
+        assertTrue(Arrays.equals(pkt, ethernet.serialize()));
+    }
+
+    @Test
+    public void testDeserialize() throws Exception {
+        Ethernet ethernet = (Ethernet) new Ethernet().deserialize(pkt, 0, pkt.length);
+        ethernet.setPad(true);
+        assertTrue(Arrays.equals(pkt, ethernet.serialize()));
+
+        IPacket expected = getPacket();
+        assertEquals(expected, ethernet);
+    }
+}
diff --git a/src/test/java/net/onrc/onos/core/packet/PacketTest.java b/src/test/java/net/onrc/onos/core/packet/PacketTest.java
new file mode 100644
index 0000000..6ca9307
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/packet/PacketTest.java
@@ -0,0 +1,133 @@
+package net.onrc.onos.core.packet;
+
+import static org.junit.Assert.*;
+import net.onrc.onos.core.packet.ARP;
+import net.onrc.onos.core.packet.Data;
+import net.onrc.onos.core.packet.Ethernet;
+import net.onrc.onos.core.packet.IPacket;
+import net.onrc.onos.core.packet.IPv4;
+import net.onrc.onos.core.packet.UDP;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class PacketTest {
+    protected IPacket pkt1, pkt2, pkt3, pkt4;
+    protected IPacket dummyPkt;
+    protected IPacket[] packets;
+    
+    @Before
+    public void setUp() {
+        this.pkt1 = new Ethernet()
+        .setDestinationMACAddress("00:11:22:33:44:55")
+        .setSourceMACAddress("00:44:33:22:11:00")
+        .setEtherType(Ethernet.TYPE_IPv4)
+        .setPayload(
+                    new IPv4()
+                    .setTtl((byte) 128)
+                    .setSourceAddress("192.168.1.1")
+                    .setDestinationAddress("192.168.1.2")
+                    .setPayload(new UDP()
+                    .setSourcePort((short) 5000)
+                    .setDestinationPort((short) 5001)
+                    .setPayload(new Data(new byte[] {0x01}))));
+        
+        this.pkt2 = new Ethernet()
+        .setSourceMACAddress("00:44:33:22:11:01")
+        .setDestinationMACAddress("00:11:22:33:44:55")
+        .setEtherType(Ethernet.TYPE_ARP)
+        .setVlanID((short)5)
+        .setPayload(
+                    new ARP()
+                    .setHardwareType(ARP.HW_TYPE_ETHERNET)
+                    .setProtocolType(ARP.PROTO_TYPE_IP)
+                    .setHardwareAddressLength((byte) 6)
+                    .setProtocolAddressLength((byte) 4)
+                    .setOpCode(ARP.OP_REPLY)
+                    .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
+                    .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
+                    .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
+                    .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
+        
+        
+        this.pkt3 = new Ethernet()
+        .setSourceMACAddress("00:44:33:22:11:01")
+        .setDestinationMACAddress("00:11:22:33:44:55")
+        .setEtherType(Ethernet.TYPE_ARP)
+        .setPayload(
+                    new ARP()
+                    .setHardwareType(ARP.HW_TYPE_ETHERNET)
+                    .setProtocolType(ARP.PROTO_TYPE_IP)
+                    .setHardwareAddressLength((byte) 6)
+                    .setProtocolAddressLength((byte) 4)
+                    .setOpCode(ARP.OP_REPLY)
+                    .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
+                    .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
+                    .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
+                    .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
+        
+        this.pkt4 = new Ethernet()
+        .setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
+        .setSourceMACAddress("00:11:33:55:77:01")
+        .setEtherType(Ethernet.TYPE_IPv4)
+        .setPayload(
+                    new IPv4()
+                    .setTtl((byte) 128)
+                    .setSourceAddress("192.168.10.1")
+                    .setDestinationAddress("192.168.255.255")
+                    .setPayload(new UDP()
+                    .setSourcePort((short) 5000)
+                    .setDestinationPort((short) 5001)
+                    .setPayload(new Data(new byte[] {0x01}))));
+        
+        this.dummyPkt =  new IPv4()
+        .setTtl((byte) 32)
+        .setSourceAddress("1.2.3.4")
+        .setDestinationAddress("5.6.7.8");
+        
+        this.packets = new IPacket[] { pkt1, pkt2, pkt3, pkt4 };
+    }
+    
+    protected void doTestClone(IPacket pkt) {
+        if (pkt.getPayload() != null)
+            doTestClone(pkt.getPayload());
+        IPacket newPkt = (IPacket)pkt.clone();
+        assertSame(pkt.getClass(), newPkt.getClass());
+        assertNotSame(pkt, newPkt);
+        assertSame(pkt.getParent(), newPkt.getParent());
+        assertEquals(pkt, newPkt);
+        assertEquals(pkt.getPayload(), newPkt.getPayload());
+        if (pkt.getPayload() != null)
+            assertNotSame(pkt.getPayload(), newPkt.getPayload());
+        
+        if (pkt instanceof Ethernet) {
+            Ethernet eth = (Ethernet)pkt;
+            Ethernet newEth = (Ethernet)newPkt;
+            newEth.setDestinationMACAddress(new byte[] { 1,2,3,4,5,6});
+            assertEquals(false, newEth.getDestinationMAC()
+                                .equals(eth.getDestinationMAC()));
+            assertEquals(false, newPkt.equals(pkt));
+        }
+        if (pkt instanceof ARP) {
+            ARP arp = (ARP)pkt;
+            ARP newArp = (ARP)newPkt;
+            newArp.setSenderProtocolAddress(new byte[] {1,2,3,4});
+            assertEquals(false, newArp.getSenderProtocolAddress()
+                                .equals(arp.getSenderProtocolAddress()));
+            assertEquals(false, newPkt.equals(pkt));
+        }
+        
+        byte[] dummyData = dummyPkt.serialize().clone();
+        newPkt = (IPacket)pkt.clone();
+        newPkt.deserialize(dummyData, 0, dummyData.length);
+        assertEquals(false, newPkt.equals(pkt));
+    }
+    
+    @Test
+    public void testClone() {
+        for (IPacket pkt: packets) {
+            doTestClone(pkt);
+        }
+    }
+    
+}
diff --git a/src/test/java/net/onrc/onos/core/packet/TCPTest.java b/src/test/java/net/onrc/onos/core/packet/TCPTest.java
new file mode 100644
index 0000000..4817a99
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/packet/TCPTest.java
@@ -0,0 +1,78 @@
+/**
+*    Copyright 2011, Big Switch Networks, Inc. 
+*    Originally created by David Erickson, Stanford University
+* 
+*    Licensed under the Apache License, Version 2.0 (the "License"); you may
+*    not use this file except in compliance with the License. You may obtain
+*    a copy of the License at
+*
+*         http://www.apache.org/licenses/LICENSE-2.0
+*
+*    Unless required by applicable law or agreed to in writing, software
+*    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+*    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+*    License for the specific language governing permissions and limitations
+*    under the License.
+**/
+
+/**
+ * 
+ */
+package net.onrc.onos.core.packet;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+
+import net.onrc.onos.core.packet.IPacket;
+import net.onrc.onos.core.packet.IPv4;
+import net.onrc.onos.core.packet.TCP;
+
+import org.junit.Test;
+
+/**
+ * @author shudong.zhou@bigswitch.com
+ */
+public class TCPTest {
+    private byte[] pktSerialized = new byte[] { 0x45, 0x20,
+            0x00, 0x34, 0x1d, (byte) 0x85, 0x00, 0x00, 0x32, 0x06,
+            0x31, 0x1e, 0x4a, 0x7d, 0x2d, 0x6d, (byte) 0xc0, (byte) 0xa8,
+            0x01, 0x6f, 0x03, (byte) 0xe1, (byte) 0xc0, 0x32, (byte) 0xe3, (byte) 0xad,
+            (byte) 0xee, (byte) 0x88, (byte) 0xb7, (byte) 0xda, (byte) 0xd8, 0x24, (byte) 0x80, 0x10,
+            0x01, 0x0b, 0x59, 0x33, 0x00, 0x00, 0x01, 0x01,
+            0x08, 0x0a, 0x20, (byte) 0x9a, 0x41, 0x04, 0x07, 0x76,
+            0x53, 0x1f};
+    
+    @Test
+    public void testSerialize() {
+        IPacket packet = new IPv4()
+        .setDiffServ((byte) 0x20)
+        .setIdentification((short) 0x1d85)
+        .setFlags((byte) 0x00)
+        .setTtl((byte) 50)
+        .setSourceAddress("74.125.45.109")
+        .setDestinationAddress("192.168.1.111")
+        .setPayload(new TCP()
+                        .setSourcePort((short) 993)
+                        .setDestinationPort((short) 49202)
+                        .setSequence(0xe3adee88)
+                        .setAcknowledge(0xb7dad824)
+                        .setDataOffset((byte) 8)
+                        .setFlags((short) 0x10)
+                        .setWindowSize((short) 267)
+                        .setOptions(new byte[] {0x01, 0x01, 0x08, 0x0a, 0x20, (byte) 0x9a,
+                                                0x41, 0x04, 0x07, 0x76, 0x53, 0x1f})
+                        .setPayload(null)
+                   );
+        byte[] actual = packet.serialize();
+        assertTrue(Arrays.equals(pktSerialized, actual));
+    }
+    
+    @Test
+    public void testDeserialize() {
+        IPacket packet = new IPv4();
+        packet.deserialize(pktSerialized, 0, pktSerialized.length);
+        byte[] pktSerialized1 = packet.serialize();
+        assertTrue(Arrays.equals(pktSerialized, pktSerialized1));
+    }
+}
diff --git a/src/test/java/net/onrc/onos/core/packet/UDPTest.java b/src/test/java/net/onrc/onos/core/packet/UDPTest.java
new file mode 100644
index 0000000..b5eca46
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/packet/UDPTest.java
@@ -0,0 +1,60 @@
+/**
+*    Copyright 2011, Big Switch Networks, Inc. 
+*    Originally created by David Erickson, Stanford University
+* 
+*    Licensed under the Apache License, Version 2.0 (the "License"); you may
+*    not use this file except in compliance with the License. You may obtain
+*    a copy of the License at
+*
+*         http://www.apache.org/licenses/LICENSE-2.0
+*
+*    Unless required by applicable law or agreed to in writing, software
+*    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+*    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+*    License for the specific language governing permissions and limitations
+*    under the License.
+**/
+
+/**
+ * 
+ */
+package net.onrc.onos.core.packet;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+
+import net.onrc.onos.core.packet.Data;
+import net.onrc.onos.core.packet.IPacket;
+import net.onrc.onos.core.packet.IPv4;
+import net.onrc.onos.core.packet.UDP;
+
+import org.junit.Test;
+
+/**
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ *
+ */
+public class UDPTest {
+
+    @Test
+    public void testSerialize() {
+        byte[] expected = new byte[] { 0x45, 0x00, 0x00, 0x1d, 0x56, 0x23,
+                0x00, 0x00, (byte) 0x80, 0x11, 0x48, 0x7f, (byte) 0xc0,
+                (byte) 0xa8, 0x01, 0x02, 0x0c, (byte) 0x81, (byte) 0xce, 0x02,
+                0x17, (byte) 0xe1, 0x04, 0x5f, 0x00, 0x09, 0x46, 0x6e,
+                0x01 };
+        IPacket packet = new IPv4()
+            .setIdentification((short) 22051)
+            .setTtl((byte) 128)
+            .setSourceAddress("192.168.1.2")
+            .setDestinationAddress("12.129.206.2")
+            .setPayload(new UDP()
+                            .setSourcePort((short) 6113)
+                            .setDestinationPort((short) 1119)
+                            .setPayload(new Data(new byte[] {0x01}))
+                       );
+        byte[] actual = packet.serialize();
+        assertTrue(Arrays.equals(expected, actual));
+    }
+}
diff --git a/src/test/java/net/onrc/onos/core/registry/StandaloneRegistryTest.java b/src/test/java/net/onrc/onos/core/registry/StandaloneRegistryTest.java
new file mode 100644
index 0000000..5b1f59d
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/registry/StandaloneRegistryTest.java
@@ -0,0 +1,465 @@
+package net.onrc.onos.core.registry;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.onrc.onos.core.registry.ControllerRegistryEntry;
+import net.onrc.onos.core.registry.IdBlock;
+import net.onrc.onos.core.registry.RegistryException;
+import net.onrc.onos.core.registry.StandaloneRegistry;
+import net.onrc.onos.core.registry.IControllerRegistryService.ControlChangeCallback;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.openflow.util.HexString;
+
+/**
+ * Unit test for {@link StandaloneRegistry}.
+ * @author Naoki Shiota
+ *
+ */
+public class StandaloneRegistryTest {
+	protected static final long TIMEOUT_MSEC = 1000;
+	
+	protected StandaloneRegistry registry;
+	
+	/**
+	 * Implementation of {@link ControlChangeCallback} which defines callback interfaces called by Registry.
+	 * This class remembers past callback parameters and provides methods to access them.
+	 * This class also provides CountDownLatch so one can wait until the callback be called
+	 * specific times (specified by constructor parameter). Particularly, the first time callback
+	 * called is supposed for registration, this class has an independent latch to wait for
+	 * the first callback.
+	 * @author Naoki Shiota
+	 */
+	public static class LoggingCallback implements ControlChangeCallback {
+		private LinkedList<Long> dpidsCalledback = new LinkedList<Long>();
+		private LinkedList<Boolean> controlsCalledback = new LinkedList<Boolean>();
+		private CountDownLatch lock = null, registerLock = null;;
+		
+		/**
+		 * Constructor with number of times callback to be called.
+		 * @param numberToCall Number of times expected callback to be called
+		 */
+		public LoggingCallback(int numberToCall) {
+			lock = new CountDownLatch(numberToCall);
+			registerLock = new CountDownLatch(1);
+		}
+
+		/**
+		 * Wait until registration is finished (callback is called for the first time).
+		 * @throws InterruptedException
+		 */
+		public void waitForRegistration() throws InterruptedException {
+			registerLock.await();
+		}
+		
+		/**
+		 * Wait for registration specifying timeout.
+		 * @param msec Milliseconds to timeout
+		 * @throws InterruptedException
+		 */
+		public void waitForRegistration(long msec) throws InterruptedException {
+			registerLock.await(msec, TimeUnit.MILLISECONDS);
+		}
+
+		/**
+		 * Wait until callback is called specific times.
+		 * @throws InterruptedException
+		 */
+		public void waitUntilCalled() throws InterruptedException {
+			lock.await();
+		}
+		
+		/**
+		 * Wait until callback is called specific times, specifying timeout.
+		 * @param msec Milliseconds to timeout
+		 * @throws InterruptedException
+		 */
+		public void waitUntilCalled(long msec) throws InterruptedException {
+			lock.await(msec, TimeUnit.MILLISECONDS);
+		}
+		
+		/**
+		 * Get DPID parameter given by specific callback time.
+		 * @param index Specify which time to get parameter
+		 * @return DPID value by number.
+		 */
+		public Long getDpid(int index) { return dpidsCalledback.get(index); }
+		
+		/**
+		 * Get hasControl parameter given by specific callback time.
+		 * @param index Specify which time to get parameter
+		 * @return hasControl value
+		 */
+		public Boolean getControl(int index) { return controlsCalledback.get(index); }
+		
+		/**
+		 * Get DPID parameter given by latest call.
+		 * @return DPID value by number
+		 */
+		public Long getLatestDpid() { return dpidsCalledback.peekLast(); }
+		
+		/**
+		 * Get hasControl parameter given by latest call
+		 * @return hasControl value
+		 */
+		public Boolean getLatestControl() { return controlsCalledback.peekLast(); }
+		
+		@Override
+		public void controlChanged(long dpid, boolean hasControl) {
+			dpidsCalledback.addLast(dpid);
+			controlsCalledback.addLast(hasControl);
+			
+			lock.countDown();
+			registerLock.countDown();
+		}
+	};
+	
+	@Before
+	public void setUp() throws Exception {
+        FloodlightModuleContext fmc = new FloodlightModuleContext();
+		registry = new StandaloneRegistry();
+		registry.init(fmc);
+	}
+
+	@After
+	public void tearDown() {
+	}
+	
+	/**
+	 * Test if {@link StandaloneRegistry#registerController(String)} can run without error.
+	 */
+	@Test
+	public void testRegisterController() {
+		String controllerIdToRegister = "test";
+		try {
+			registry.registerController(controllerIdToRegister);
+		} catch (RegistryException e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		}
+		
+		// Register Controller ID doubly 
+		try {
+			registry.registerController(controllerIdToRegister);
+			fail("Double registration goes through without exception");
+		} catch (RegistryException e) {
+			// expected behavior
+		}
+	}
+	
+	/**
+	 * Test if {@link StandaloneRegistry#getControllerId()} can return correct ID.
+	 * @throws RegistryException
+	 */
+	@Test
+	public void testGetControllerId() throws RegistryException {
+		String controllerIdToRegister = "test";
+		
+		// try before controller is registered
+		String controllerId = registry.getControllerId();
+		assertNull(controllerId);
+		
+		// register
+		registry.registerController(controllerIdToRegister);
+
+		// call getControllerId and verify
+		controllerId = registry.getControllerId();
+		assertNotNull(controllerId);
+		assertEquals(controllerIdToRegister, controllerId);
+	}
+
+	/**
+	 * Test if {@link StandaloneRegistry#getAllControllers()} can return correct list of controllers.
+	 * @throws RegistryException
+	 */
+	@Test
+	public void testGetAllControllers() throws RegistryException {
+		String controllerIdToRegister = "test";
+		
+		// Test before register controller
+		try {
+			Collection<String> ctrls = registry.getAllControllers();
+			assertFalse(ctrls.contains(controllerIdToRegister));
+		} catch (RegistryException e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		}
+		
+		// register
+		registry.registerController(controllerIdToRegister);
+
+		// Test after register controller
+		try {
+			Collection<String> ctrls = registry.getAllControllers();
+			assertTrue(ctrls.contains(controllerIdToRegister));
+		} catch (RegistryException e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		}
+	}
+
+	/**
+	 * Test if {@link StandaloneRegistry#requestControl(long, ControlChangeCallback)} can correctly take control for switch so that callback is called.
+	 * @throws RegistryException
+	 * @throws InterruptedException
+	 */
+	@Test
+	public void testRequestControl() throws InterruptedException, RegistryException {
+		String controllerId = "test";
+		registry.registerController(controllerId);
+
+		LoggingCallback callback = new LoggingCallback(1);
+		long dpidToRequest = 1000L;
+
+		try {
+			registry.requestControl(dpidToRequest, callback);
+		} catch (RegistryException e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		}
+		
+		callback.waitForRegistration();
+		
+		long dpidCallback = callback.getLatestDpid();
+		boolean controlCallback = callback.getLatestControl();
+		
+		assertEquals(dpidToRequest, dpidCallback);
+		assertTrue(controlCallback);
+	}
+
+	/**
+	 * Test if {@link StandaloneRegistry#releaseControl(long)} can correctly release the control so that callback is called.
+	 * @throws InterruptedException
+	 * @throws RegistryException
+	 */
+	@Test
+	public void testReleaseControl() throws InterruptedException, RegistryException {
+		String controllerId = "test";
+		registry.registerController(controllerId);
+		
+		long dpidToRequest = 1000L;
+		LoggingCallback callback = new LoggingCallback(2);
+		
+		// to request and wait to take control
+		registry.requestControl(dpidToRequest, callback);
+		callback.waitForRegistration();
+		
+		registry.releaseControl(dpidToRequest);
+		
+		// verify
+		callback.waitUntilCalled();
+		assertEquals(dpidToRequest, (long)callback.getLatestDpid());
+		assertFalse(callback.getLatestControl());
+	}
+
+	/**
+	 * Test if {@link StandaloneRegistry#hasControl(long)} returns correct status.
+	 * @throws InterruptedException
+	 * @throws RegistryException
+	 */
+	@Test
+	public void testHasControl() throws InterruptedException, RegistryException {
+		String controllerId = "test";
+		registry.registerController(controllerId);
+		
+		long dpidToRequest = 1000L;
+		LoggingCallback callback = new LoggingCallback(2);
+		
+		// Test before request control
+		assertFalse(registry.hasControl(dpidToRequest));
+		
+		registry.requestControl(dpidToRequest, callback);
+		callback.waitForRegistration();
+		
+		// Test after take control
+		assertTrue(registry.hasControl(dpidToRequest));
+		
+		registry.releaseControl(dpidToRequest);
+		
+		callback.waitUntilCalled();
+
+		// Test after release control
+		assertFalse(registry.hasControl(dpidToRequest));
+	}
+
+	/**
+	 * Test if {@link StandaloneRegistry#getControllerForSwitch(long)} returns correct controller ID.
+	 * @throws InterruptedException
+	 * @throws RegistryException
+	 */
+	@Test
+	public void testGetControllerForSwitch() throws InterruptedException, RegistryException {
+		String controllerId = "test";
+		registry.registerController(controllerId);
+		
+		long dpidToRequest = 1000L;
+		LoggingCallback callback = new LoggingCallback(2);
+		
+		// Test before request control
+		try {
+			String controllerForSw = registry.getControllerForSwitch(dpidToRequest);
+			assertNotEquals(controllerId,controllerForSw);
+		} catch (RegistryException e) {
+			fail("Failed before request control : " + e.getMessage());
+			e.printStackTrace();
+		}
+
+		registry.requestControl(dpidToRequest, callback);
+		callback.waitForRegistration();
+
+		// Test after take control
+		try {
+			String controllerForSw = registry.getControllerForSwitch(dpidToRequest);
+			assertEquals(controllerId,controllerForSw);
+		} catch (RegistryException e) {
+			fail("Failed after take control : " + e.getMessage());
+			e.printStackTrace();
+		}
+
+		registry.releaseControl(dpidToRequest);
+		callback.waitUntilCalled();
+
+		// Test after release control
+		try {
+			String controllerForSw = registry.getControllerForSwitch(dpidToRequest);
+			assertNotEquals(controllerId,controllerForSw);
+		} catch (RegistryException e) {
+			fail("Failed after release control : " + e.getMessage());
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Test if {@link StandaloneRegistry#getAllSwitches()} returns correct list of switches.
+	 * @throws InterruptedException
+	 * @throws RegistryException
+	 */
+	@Test
+	public void testGetAllSwitches() throws InterruptedException, RegistryException {
+		String controllerId = "test";
+		registry.registerController(controllerId);
+
+		long dpidToRequest = 1000L;
+		String dpidToRequestStr = HexString.toHexString(dpidToRequest);
+		LoggingCallback callback = new LoggingCallback(2);
+
+		// Test before request control
+		Map<String, List<ControllerRegistryEntry>> switches = registry.getAllSwitches();
+		assertNotNull(switches);
+		assertFalse(switches.keySet().contains(dpidToRequestStr));
+
+		registry.requestControl(dpidToRequest, callback);
+		callback.waitForRegistration();
+
+		// Test after take control
+		switches = registry.getAllSwitches();
+		assertNotNull(switches);
+		assertTrue(switches.keySet().contains(dpidToRequestStr));
+		int count = 0;
+		for(ControllerRegistryEntry ctrl : switches.get(dpidToRequestStr)) {
+			if(ctrl.getControllerId().equals(controllerId)) {
+				++count;
+			}
+		}
+		assertEquals(1,count);
+		
+		registry.releaseControl(dpidToRequest);
+		callback.waitUntilCalled();
+
+		// Test after release control
+		switches = registry.getAllSwitches();
+		assertNotNull(switches);
+		assertFalse(switches.keySet().contains(dpidToRequestStr));
+	}
+
+	/**
+	 * Test if {@link StandaloneRegistry#getSwitchesControlledByController(String)} returns correct list of switches.
+	 * @throws InterruptedException
+	 * @throws RegistryException
+	 */
+	// TODO: remove @Ignore after implement StandaloneRegistry#getSwitchesControlledByController
+	@Ignore @Test
+	public void testGetSwitchesControlledByController() throws InterruptedException, RegistryException {
+		String controllerId = "test";
+		registry.registerController(controllerId);
+
+		long dpidToRequest = 1000L;
+		String dpidToRequestStr = HexString.toHexString(dpidToRequest);
+		LoggingCallback callback = new LoggingCallback(2);
+
+		// Test before request control
+		Collection<Long> switches = registry.getSwitchesControlledByController(controllerId);
+		assertNotNull(switches);
+		assertFalse(switches.contains(dpidToRequestStr));
+
+		registry.requestControl(dpidToRequest, callback);
+		callback.waitForRegistration();
+
+		// Test after take control
+		switches = registry.getSwitchesControlledByController(controllerId);
+		assertNotNull(switches);
+		assertTrue(switches.contains(dpidToRequestStr));
+		int count = 0;
+		for(Long dpid : switches) {
+			if((long)dpid == dpidToRequest) {
+				++count;
+			}
+		}
+		assertEquals(1, count);
+		
+		registry.releaseControl(dpidToRequest);
+		callback.waitUntilCalled();
+
+		// Test after release control
+		switches = registry.getSwitchesControlledByController(controllerId);
+		assertNotNull(switches);
+		assertFalse(switches.contains(dpidToRequestStr));
+	}
+
+	/**
+	 * Test if {@link StandaloneRegistry#allocateUniqueIdBlock()} returns appropriate object.
+	 * Get bulk of IdBlocks and check if they do have unique range of IDs.
+	 */
+	@Test
+	public void testAllocateUniqueIdBlock() {
+		// Number of blocks to be verified that any of them has unique block
+		final int NUM_BLOCKS = 100;
+		ArrayList<IdBlock> blocks = new ArrayList<IdBlock>(NUM_BLOCKS);
+		
+		for(int i = 0; i < NUM_BLOCKS; ++i) {
+			blocks.add(registry.allocateUniqueIdBlock());
+		}
+		
+		for(int i = 0; i < NUM_BLOCKS; ++i) {
+			IdBlock block1 = blocks.get(i);
+			for(int j = i + 1; j < NUM_BLOCKS; ++j) {
+				IdBlock block2 = blocks.get(j);
+				IdBlock lower,higher;
+				
+				if(block1.getStart() < block2.getStart()) {
+					lower = block1;
+					higher = block2;
+				} else {
+					lower = block2;
+					higher = block1;
+				}
+				
+				assertTrue(lower.getSize() > 0L);
+				assertTrue(higher.getSize() > 0L);
+				assertTrue(lower.getEnd() < higher.getStart());
+			}
+		}
+	}
+}
diff --git a/src/test/java/net/onrc/onos/core/registry/ZookeeperRegistryTest.java b/src/test/java/net/onrc/onos/core/registry/ZookeeperRegistryTest.java
new file mode 100644
index 0000000..06de77e
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/registry/ZookeeperRegistryTest.java
@@ -0,0 +1,601 @@
+package net.onrc.onos.core.registry;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.test.FloodlightTestCase;
+import net.onrc.onos.core.registry.ControllerRegistryEntry;
+import net.onrc.onos.core.registry.ControllerService;
+import net.onrc.onos.core.registry.IdBlock;
+import net.onrc.onos.core.registry.RegistryException;
+import net.onrc.onos.core.registry.ZookeeperRegistry;
+import net.onrc.onos.core.registry.StandaloneRegistryTest.LoggingCallback;
+import net.onrc.onos.core.registry.ZookeeperRegistry.SwitchLeaderListener;
+
+import org.apache.curator.RetryPolicy;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.framework.listen.ListenerContainer;
+import org.apache.curator.framework.recipes.atomic.AtomicValue;
+import org.apache.curator.framework.recipes.atomic.DistributedAtomicLong;
+import org.apache.curator.framework.recipes.cache.ChildData;
+import org.apache.curator.framework.recipes.cache.PathChildrenCache;
+import org.apache.curator.framework.recipes.cache.PathChildrenCache.StartMode;
+import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
+import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
+import org.apache.curator.framework.recipes.leader.LeaderLatch;
+import org.apache.curator.x.discovery.ServiceCache;
+import org.apache.curator.x.discovery.ServiceCacheBuilder;
+import org.apache.curator.x.discovery.ServiceDiscovery;
+import org.apache.curator.x.discovery.ServiceDiscoveryBuilder;
+import org.apache.curator.x.discovery.ServiceInstance;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openflow.util.HexString;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+/**
+ * Unit test for {@link ZookeeperRegistry}.
+ * NOTE: {@link FloodlightTestCase} conflicts with PowerMock. If FloodLight-related methods need to be tested,
+ *       implement another test class to test them.
+ * @author Naoki Shiota
+ *
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({ZookeeperRegistry.class, CuratorFramework.class, CuratorFrameworkFactory.class,
+	ServiceDiscoveryBuilder.class, ServiceDiscovery.class, ServiceCache.class, PathChildrenCache.class,
+	ZookeeperRegistry.SwitchPathCacheListener.class})
+public class ZookeeperRegistryTest extends FloodlightTestCase {
+	private final static Long ID_BLOCK_SIZE = 0x100000000L;
+	
+	protected ZookeeperRegistry registry;
+	protected CuratorFramework client;
+	
+	protected PathChildrenCacheListener pathChildrenCacheListener;
+	protected final String CONTROLLER_ID = "controller2013";
+
+	/**
+	 * Initialize {@link ZookeeperRegistry} Object and inject initial value with {@link ZookeeperRegistry#init(FloodlightModuleContext)} method.
+	 * This setup code also tests {@link ZookeeperRegistry#init(FloodlightModuleContext)} method itself.
+	 */
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		
+		pathChildrenCacheListener = null;
+		
+		// Mock of CuratorFramework
+		client = createCuratorFrameworkMock();
+		
+		// Mock of CuratorFrameworkFactory
+		PowerMock.mockStatic(CuratorFrameworkFactory.class);
+		EasyMock.expect(CuratorFrameworkFactory.newClient((String)EasyMock.anyObject(),
+				EasyMock.anyInt(), EasyMock.anyInt(), (RetryPolicy)EasyMock.anyObject())).andReturn(client);
+		PowerMock.replay(CuratorFrameworkFactory.class);
+
+		FloodlightModuleContext fmc = new FloodlightModuleContext();
+		registry = new ZookeeperRegistry();
+		fmc.addService(ZookeeperRegistry.class, registry);
+		
+		registry.init(fmc);
+		
+		PowerMock.verify(client, CuratorFrameworkFactory.class);
+	}
+
+	/**
+	 * Clean up member variables (empty for now).
+	 */
+	@After
+	public void tearDown() throws Exception {
+		super.tearDown();
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#registerController(String)} method can go through without exception.
+	 * (Exceptions are usually out of test target, but {@link ZookeeperRegistry#registerController(String)} throws an exception in case of invalid registration.)
+	 */
+	@Test
+	public void testRegisterController() {
+		String controllerIdToRegister = "controller2013";
+		
+		try {
+			registry.registerController(controllerIdToRegister);
+		} catch (RegistryException e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		}
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#getControllerId()} correctly returns registered ID.
+	 * @throws Exception
+	 */
+	@Test
+	public void testGetControllerId() throws Exception {
+		String controllerIdToRegister = "controller1";
+		
+		// try before controller is registered
+		String controllerId = registry.getControllerId();
+		assertNull(controllerId);
+		
+		// register
+		registry.registerController(controllerIdToRegister);
+	
+		// call getControllerId and verify
+		controllerId = registry.getControllerId();
+		assertNotNull(controllerId);
+		assertEquals(controllerIdToRegister, controllerId);
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#getAllControllers()} returns all controllers.
+	 * Controllers to be returned are injected while setup. See {@link ZookeeperRegistryTest#createCuratorFrameworkMock()}
+	 * to what controllers are injected using mock {@link ServiceCache}.
+	 * @throws Exception
+	 */
+	@Test
+	public void testGetAllControllers() throws Exception {
+		String controllerIdRegistered = "controller1";
+		String controllerIdNotRegistered = "controller2013";
+
+		try {
+			Collection<String> ctrls = registry.getAllControllers();
+			assertTrue(ctrls.contains(controllerIdRegistered));
+			assertFalse(ctrls.contains(controllerIdNotRegistered));
+		} catch (RegistryException e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		}
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#requestControl(long, net.onrc.onos.core.registry.IControllerRegistryService.ControlChangeCallback)}
+	 * correctly take control of specific switch. Because {@link ZookeeperRegistry#requestControl(long, net.onrc.onos.core.registry.IControllerRegistryService.ControlChangeCallback)}
+	 * doesn't return values, inject mock {@link LeaderLatch} object and verify latch is correctly set up.
+	 * @throws Exception
+	 */
+	@Test
+	public void testRequestControl() throws Exception {
+		// Mock LeaderLatch
+		LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
+		latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
+		EasyMock.expectLastCall().once();
+		latch.start();
+		EasyMock.expectLastCall().once();
+		EasyMock.replay(latch);
+		
+		PowerMock.expectNew(LeaderLatch.class,
+				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(String.class))
+				.andReturn(latch).once();
+		PowerMock.replay(LeaderLatch.class);
+		
+		String controllerId = "controller2013";
+		registry.registerController(controllerId);
+
+		LoggingCallback callback = new LoggingCallback(1);
+		long dpidToRequest = 2000L;
+
+		try {
+			registry.requestControl(dpidToRequest, callback);
+		} catch (RegistryException e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		}
+		
+		EasyMock.verify(latch);
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#releaseControl(long)} correctly release control of specific switch.
+	 * Because {@link ZookeeperRegistry#releaseControl(long)} doesn't return values, inject mock
+	 * {@link LeaderLatch} object and verify latch is correctly set up.
+	 * @throws Exception
+	 */
+	@Test
+	public void testReleaseControl() throws Exception {
+		// Mock of LeaderLatch
+		LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
+		latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
+		EasyMock.expectLastCall().once();
+		latch.start();
+		EasyMock.expectLastCall().once();
+		latch.removeListener(EasyMock.anyObject(SwitchLeaderListener.class));
+		EasyMock.expectLastCall().once();
+		latch.close();
+		EasyMock.expectLastCall().once();
+		EasyMock.replay(latch);
+		
+		PowerMock.expectNew(LeaderLatch.class,
+				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(String.class))
+				.andReturn(latch).once();
+		PowerMock.replay(LeaderLatch.class);
+		
+		String controllerId = "controller2013";
+		registry.registerController(controllerId);
+		
+		long dpidToRequest = 2000L;
+		LoggingCallback callback = new LoggingCallback(1);
+		
+		registry.requestControl(dpidToRequest, callback);
+		registry.releaseControl(dpidToRequest);
+		
+		EasyMock.verify(latch);
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#hasControl(long)} returns correct status whether controller has control of specific switch.
+	 * @throws Exception
+	 */
+	@Test
+	public void testHasControl() throws Exception {
+		// Mock of LeaderLatch
+		LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
+		latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
+		EasyMock.expectLastCall().once();
+		latch.start();
+		EasyMock.expectLastCall().once();
+		EasyMock.expect(latch.hasLeadership()).andReturn(true).anyTimes();
+		latch.removeListener(EasyMock.anyObject(SwitchLeaderListener.class));
+		EasyMock.expectLastCall().once();
+		latch.close();
+		EasyMock.expectLastCall().once();
+		EasyMock.replay(latch);
+		
+		PowerMock.expectNew(LeaderLatch.class,
+				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(String.class))
+				.andReturn(latch);
+		PowerMock.replay(LeaderLatch.class);
+		
+		String controllerId = "controller2013";
+		registry.registerController(controllerId);
+		
+		long dpidToRequest = 2000L;
+		LoggingCallback callback = new LoggingCallback(2);
+		
+		// Test before request control
+		assertFalse(registry.hasControl(dpidToRequest));
+
+		registry.requestControl(dpidToRequest, callback);
+		
+		// Test after request control
+		assertTrue(registry.hasControl(dpidToRequest));
+		
+		registry.releaseControl(dpidToRequest);
+		
+		// Test after release control
+		assertFalse(registry.hasControl(dpidToRequest));
+		
+		EasyMock.verify(latch);
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#getControllerForSwitch(long)} correctly returns controller ID of specific switch.
+	 * Relation between controllers and switches are defined by {@link ZookeeperRegistryTest#setPathChildrenCache()} function.
+	 * @throws Throwable
+	 */
+	@Test
+	public void testGetControllerForSwitch() throws Throwable {
+		long dpidRegistered = 1000L;
+		long dpidNotRegistered = 2000L;
+		
+		setPathChildrenCache();
+		
+		String controllerForSw = registry.getControllerForSwitch(dpidRegistered);
+		assertEquals("controller1",controllerForSw);
+
+		controllerForSw = registry.getControllerForSwitch(dpidNotRegistered);
+		assertEquals(null, controllerForSw);
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#getSwitchesControlledByController(String)} returns correct list of
+	 * switches controlled by a controller.
+	 * @throws Exception
+	 */
+	// TODO: Test after getSwitchesControlledByController() is implemented.
+	@Ignore @Test
+	public void testGetSwitchesControlledByController() throws Exception {
+		String controllerIdRegistered = "controller1";
+		String dpidRegistered = HexString.toHexString(1000L);
+		String controllerIdNotRegistered = CONTROLLER_ID;
+		
+		Collection<Long> switches = registry.getSwitchesControlledByController(controllerIdRegistered);
+		assertNotNull(switches);
+		assertTrue(switches.contains(dpidRegistered));
+
+		switches = registry.getSwitchesControlledByController(controllerIdNotRegistered);
+		assertNotNull(switches);
+		assertEquals(0, switches.size());
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#getAllSwitches()} returns correct list of all switches.
+	 * Switches are injected in {@link ZookeeperRegistryTest#setPathChildrenCache()} function.
+	 * @throws Exception
+	 */
+	@Test
+	public void testGetAllSwitches() throws Exception {
+		String [] dpids = {
+				HexString.toHexString(1000L),
+				HexString.toHexString(1001L),
+				HexString.toHexString(1002L),
+		};
+		
+		setPathChildrenCache();
+
+		Map<String, List<ControllerRegistryEntry>> switches = registry.getAllSwitches();
+		assertNotNull(switches);
+		assertEquals(dpids.length, switches.size());
+		for(String dpid : dpids) {
+			assertTrue(switches.keySet().contains(dpid));
+		}
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#allocateUniqueIdBlock()} can assign IdBlock without duplication.
+	 */
+	@Test
+	public void testAllocateUniqueIdBlock() {
+		// Number of blocks to be verified that any of them has unique block
+		final int NUM_BLOCKS = 100;
+		ArrayList<IdBlock> blocks = new ArrayList<IdBlock>(NUM_BLOCKS);
+		
+		for(int i = 0; i < NUM_BLOCKS; ++i) {
+			IdBlock block = registry.allocateUniqueIdBlock();
+			assertNotNull(block);
+			blocks.add(block);
+		}
+		
+		for(int i = 0; i < NUM_BLOCKS; ++i) {
+			IdBlock block1 = blocks.get(i);
+			for(int j = i + 1; j < NUM_BLOCKS; ++j) {
+				IdBlock block2 = blocks.get(j);
+				IdBlock lower,higher;
+				
+				if(block1.getStart() < block2.getStart()) {
+					lower = block1;
+					higher = block2;
+				} else {
+					lower = block2;
+					higher = block1;
+				}
+				
+				assertTrue(lower.getSize() > 0L);
+				assertTrue(higher.getSize() > 0L);
+				assertTrue(lower.getEnd() <= higher.getStart());
+			}
+		}
+	}
+	
+	
+	//-------------------------- Creation of mock objects --------------------------
+	/**
+	 * Create mock {@link CuratorFramework} object with initial value below.<br>
+	 *   [Ctrl ID]    : [DPID]<br>
+	 * controller1    :  1000<br>
+	 * controller2    :  1001<br>
+	 * controller2    :  1002<br>
+	 * controller2013 : nothing
+	 * @return Created mock object
+	 * @throws Exception
+	 */
+	@SuppressWarnings({ "serial", "unchecked" })
+	private CuratorFramework createCuratorFrameworkMock() throws Exception {
+		// Mock of AtomicValue
+		AtomicValue<Long> atomicValue = EasyMock.createMock(AtomicValue.class);
+		EasyMock.expect(atomicValue.succeeded()).andReturn(true).anyTimes();
+		EasyMock.expect(atomicValue.preValue()).andAnswer(new IAnswer<Long>() {
+			private long value = 0;
+			@Override
+			public Long answer() throws Throwable {
+				value += ID_BLOCK_SIZE;
+				return value;
+			}
+		}).anyTimes();
+		EasyMock.expect(atomicValue.postValue()).andAnswer(new IAnswer<Long>() {
+			private long value = ID_BLOCK_SIZE;
+			@Override
+			public Long answer() throws Throwable {
+				value += ID_BLOCK_SIZE;
+				return value;
+			}
+		}).anyTimes();
+		EasyMock.replay(atomicValue);
+		
+		// Mock DistributedAtomicLong
+		DistributedAtomicLong daLong = EasyMock.createMock(DistributedAtomicLong.class);
+		EasyMock.expect(daLong.add(EasyMock.anyLong())).andReturn(atomicValue).anyTimes();
+		EasyMock.replay(daLong);
+		PowerMock.expectNew(DistributedAtomicLong.class,
+				new Class<?> [] {CuratorFramework.class, String.class, RetryPolicy.class},
+				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(RetryPolicy.class)).
+				andReturn(daLong).anyTimes();
+		PowerMock.replay(DistributedAtomicLong.class);
+		
+		// Mock ListenerContainer
+		ListenerContainer<PathChildrenCacheListener> listenerContainer = EasyMock.createMock(ListenerContainer.class);
+		listenerContainer.addListener(EasyMock.anyObject(PathChildrenCacheListener.class));
+		EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+			@Override
+			public Object answer() throws Throwable {
+				pathChildrenCacheListener = (PathChildrenCacheListener)EasyMock.getCurrentArguments()[0];
+				return null;
+			}
+		}).once();
+		EasyMock.replay(listenerContainer);
+
+		// Mock PathChildrenCache
+		PathChildrenCache pathChildrenCacheMain = createPathChildrenCacheMock(CONTROLLER_ID, new String[] {"/switches"}, listenerContainer);
+		PathChildrenCache pathChildrenCache1 = createPathChildrenCacheMock("controller1", new String[] {HexString.toHexString(1000L)}, listenerContainer);
+		PathChildrenCache pathChildrenCache2 = createPathChildrenCacheMock("controller2", new String[] { 
+			HexString.toHexString(1001L), HexString.toHexString(1002L) },listenerContainer);
+		
+		// Mock PathChildrenCache constructor
+		PowerMock.expectNew(PathChildrenCache.class,
+				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
+				andReturn(pathChildrenCacheMain).once();
+		PowerMock.expectNew(PathChildrenCache.class,
+				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
+				andReturn(pathChildrenCache1).once();
+		PowerMock.expectNew(PathChildrenCache.class,
+				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
+				andReturn(pathChildrenCache2).anyTimes();
+		PowerMock.replay(PathChildrenCache.class);
+		
+		// Mock ServiceCache
+		ServiceCache<ControllerService> serviceCache = EasyMock.createMock(ServiceCache.class);
+		serviceCache.start();
+		EasyMock.expectLastCall().once();
+		EasyMock.expect(serviceCache.getInstances()).andReturn(new ArrayList<ServiceInstance<ControllerService> > () {{
+			add(createServiceInstanceMock("controller1"));
+			add(createServiceInstanceMock("controller2"));
+		}}).anyTimes();
+		EasyMock.replay(serviceCache);
+		
+		// Mock ServiceCacheBuilder
+		ServiceCacheBuilder<ControllerService> serviceCacheBuilder = EasyMock.createMock(ServiceCacheBuilder.class);
+		EasyMock.expect(serviceCacheBuilder.name(EasyMock.anyObject(String.class))).andReturn(serviceCacheBuilder).once();
+		EasyMock.expect(serviceCacheBuilder.build()).andReturn(serviceCache).once();
+		EasyMock.replay(serviceCacheBuilder);
+
+		// Mock ServiceDiscovery
+		ServiceDiscovery<ControllerService> serviceDiscovery = EasyMock.createMock(ServiceDiscovery.class);
+		serviceDiscovery.start();
+		EasyMock.expectLastCall().once();
+		EasyMock.expect(serviceDiscovery.serviceCacheBuilder()).andReturn(serviceCacheBuilder).once();
+		serviceDiscovery.registerService(EasyMock.anyObject(ServiceInstance.class));
+		EasyMock.expectLastCall().once();
+		EasyMock.replay(serviceDiscovery);
+		
+		// Mock CuratorFramework
+		CuratorFramework client = EasyMock.createMock(CuratorFramework.class);
+		client.start();
+		EasyMock.expectLastCall().once();
+		EasyMock.expect(client.usingNamespace(EasyMock.anyObject(String.class))).andReturn(client);
+		EasyMock.replay(client);
+
+		// Mock ServiceDiscoveryBuilder
+		ServiceDiscoveryBuilder<ControllerService> builder = EasyMock.createMock(ServiceDiscoveryBuilder.class);
+		EasyMock.expect(builder.client(client)).andReturn(builder).once();
+		EasyMock.expect(builder.basePath(EasyMock.anyObject(String.class))).andReturn(builder);
+		EasyMock.expect(builder.build()).andReturn(serviceDiscovery);
+		EasyMock.replay(builder);
+		
+		PowerMock.mockStatic(ServiceDiscoveryBuilder.class);
+		EasyMock.expect(ServiceDiscoveryBuilder.builder(ControllerService.class)).andReturn(builder).once();
+		PowerMock.replay(ServiceDiscoveryBuilder.class);
+
+		return client;
+	}
+	
+	/**
+	 * Create mock {@link ServiceInstance} object using given controller ID.
+	 * @param controllerId Controller ID to represent instance's payload (ControllerService).
+	 * @return Mock ServiceInstance object
+	 */
+	private ServiceInstance<ControllerService> createServiceInstanceMock(String controllerId) {
+		ControllerService controllerService = EasyMock.createMock(ControllerService.class);
+		EasyMock.expect(controllerService.getControllerId()).andReturn(controllerId).anyTimes();
+		EasyMock.replay(controllerService);
+		
+		@SuppressWarnings("unchecked")
+		ServiceInstance<ControllerService> serviceInstance = EasyMock.createMock(ServiceInstance.class);
+		EasyMock.expect(serviceInstance.getPayload()).andReturn(controllerService).anyTimes();
+		EasyMock.replay(serviceInstance);
+
+		return serviceInstance;
+	}
+	
+	/**
+	 * Create mock {@link PathChildrenCache} using given controller ID and DPIDs.
+	 * @param controllerId Controller ID to represent current data.
+	 * @param paths List of HexString indicating switch's DPID.
+	 * @param listener Callback object to be set as Listenable.
+	 * @return Mock PathChildrenCache object
+	 * @throws Exception
+	 */
+	private PathChildrenCache createPathChildrenCacheMock(final String controllerId, final String [] paths,
+			ListenerContainer<PathChildrenCacheListener> listener) throws Exception {
+		PathChildrenCache pathChildrenCache = EasyMock.createMock(PathChildrenCache.class);
+		
+		EasyMock.expect(pathChildrenCache.getListenable()).andReturn(listener).anyTimes();
+		
+		pathChildrenCache.start(EasyMock.anyObject(StartMode.class));
+		EasyMock.expectLastCall().anyTimes();
+		
+		List<ChildData> childs = new ArrayList<ChildData>();
+		for(String path : paths) {
+			childs.add(createChildDataMockForCurrentData(controllerId,path));
+		}
+		EasyMock.expect(pathChildrenCache.getCurrentData()).andReturn(childs).anyTimes();
+		
+		pathChildrenCache.rebuild();
+		EasyMock.expectLastCall().anyTimes();
+		
+		EasyMock.replay(pathChildrenCache);
+
+		return pathChildrenCache;
+	}
+	
+	/**
+	 * Create mock {@link ChildData} for {@link PathChildrenCache#getCurrentData()} return value.
+	 * This object need to include 'sequence number' in tail of path string. ("-0" means 0th sequence)
+	 * @param controllerId Controller ID
+	 * @param path HexString indicating switch's DPID
+	 * @return Mock ChildData object
+	 */
+	private ChildData createChildDataMockForCurrentData(String controllerId, String path) {
+		ChildData data = EasyMock.createMock(ChildData.class);
+		EasyMock.expect(data.getPath()).andReturn(path + "-0").anyTimes();
+		EasyMock.expect(data.getData()).andReturn(controllerId.getBytes()).anyTimes();
+		EasyMock.replay(data);
+		
+		return data;
+	}
+
+	/**
+	 * Inject relations between controllers and switches using callback object.
+	 * @throws Exception
+	 */
+	private void setPathChildrenCache() throws Exception {
+		pathChildrenCacheListener.childEvent(client,
+				createChildrenCacheEventMock("controller1", HexString.toHexString(1000L), PathChildrenCacheEvent.Type.CHILD_ADDED));
+		pathChildrenCacheListener.childEvent(client,
+				createChildrenCacheEventMock("controller2", HexString.toHexString(1001L), PathChildrenCacheEvent.Type.CHILD_ADDED));
+		pathChildrenCacheListener.childEvent(client,
+				createChildrenCacheEventMock("controller2", HexString.toHexString(1002L), PathChildrenCacheEvent.Type.CHILD_ADDED));
+	}
+
+	/**
+	 * Create mock {@link PathChildrenCacheEvent} object using given controller ID and DPID.
+	 * @param controllerId Controller ID.
+	 * @param path HexString of DPID.
+	 * @param type Event type to be set to mock object.
+	 * @return Mock PathChildrenCacheEvent object
+	 */
+	private PathChildrenCacheEvent createChildrenCacheEventMock(String controllerId, String path,
+			PathChildrenCacheEvent.Type type) {
+		PathChildrenCacheEvent event = EasyMock.createMock(PathChildrenCacheEvent.class);
+		ChildData data = EasyMock.createMock(ChildData.class);
+		
+		EasyMock.expect(data.getPath()).andReturn(path).anyTimes();
+		EasyMock.expect(data.getData()).andReturn(controllerId.getBytes()).anyTimes();
+		EasyMock.replay(data);
+		
+		EasyMock.expect(event.getType()).andReturn(type).anyTimes();
+		EasyMock.expect(event.getData()).andReturn(data).anyTimes();
+		EasyMock.replay(event);
+		
+		return event;
+	}
+}