diff --git a/src/test/java/net/onrc/onos/registry/controller/StandaloneRegistryTest.java b/src/test/java/net/onrc/onos/registry/controller/StandaloneRegistryTest.java
new file mode 100644
index 0000000..802c137
--- /dev/null
+++ b/src/test/java/net/onrc/onos/registry/controller/StandaloneRegistryTest.java
@@ -0,0 +1,461 @@
+package net.onrc.onos.registry.controller;
+
+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.registry.controller.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 StandaloneRegistry.
+ * @author Naoki Shiota
+ *
+ */
+public class StandaloneRegistryTest {
+	protected static final long TIMEOUT_MSEC = 1000;
+	
+	protected StandaloneRegistry registry;
+	
+	/**
+	 * Implementation of 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 param). 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 registerController() 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 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 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 requestControl() 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 releaseControl() 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 hasControl() 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 getControllerForSwitch() 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 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 getSwitchesControlledByController() 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 allocateUniqueIdBlock() returns appropriate object.
+	 */
+	@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/registry/controller/ZookeeperRegistryTest.java b/src/test/java/net/onrc/onos/registry/controller/ZookeeperRegistryTest.java
new file mode 100644
index 0000000..f557663
--- /dev/null
+++ b/src/test/java/net/onrc/onos/registry/controller/ZookeeperRegistryTest.java
@@ -0,0 +1,602 @@
+package net.onrc.onos.registry.controller;
+
+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.registry.controller.StandaloneRegistryTest.LoggingCallback;
+import net.onrc.onos.registry.controller.ZookeeperRegistry.SwitchLeaderListener;
+
+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;
+
+import com.netflix.curator.RetryPolicy;
+import com.netflix.curator.framework.CuratorFramework;
+import com.netflix.curator.framework.CuratorFrameworkFactory;
+import com.netflix.curator.framework.listen.ListenerContainer;
+import com.netflix.curator.framework.recipes.atomic.AtomicValue;
+import com.netflix.curator.framework.recipes.atomic.DistributedAtomicLong;
+import com.netflix.curator.framework.recipes.cache.ChildData;
+import com.netflix.curator.framework.recipes.cache.PathChildrenCache;
+import com.netflix.curator.framework.recipes.cache.PathChildrenCacheEvent;
+import com.netflix.curator.framework.recipes.cache.PathChildrenCacheListener;
+import com.netflix.curator.framework.recipes.cache.PathChildrenCache.StartMode;
+import com.netflix.curator.framework.recipes.leader.LeaderLatch;
+import com.netflix.curator.x.discovery.ServiceCache;
+import com.netflix.curator.x.discovery.ServiceCacheBuilder;
+import com.netflix.curator.x.discovery.ServiceDiscovery;
+import com.netflix.curator.x.discovery.ServiceDiscoveryBuilder;
+import com.netflix.curator.x.discovery.ServiceInstance;
+
+/**
+ * Unit test for ZookeeperRegistry.
+ * NOTE: 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 ZookeeperRegistry Object and inject initial value with init() method.
+	 * This setup code also tests init() 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 registerController() method can go through without exception.
+	 * (Exceptions are usually out of test target, but registerController() 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 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 getAllControllers() returns all controllers.
+	 * Controllers are injected while setup. See createCuratorFrameworkMock() to what controllers
+	 * are injected using ServiceCache Mock.
+	 * @throws Exception
+	 */
+	@Test
+	public void testGetAllControllers() throws Exception {
+		String controllerIdRegistered = "controller1";
+		String controllerIdNotRegistered = "controller2013";
+
+		// Test registered controller
+		try {
+			Collection<String> ctrls = registry.getAllControllers();
+			assertTrue(ctrls.contains(controllerIdRegistered));
+			assertFalse(ctrls.contains(controllerIdNotRegistered));
+		} catch (RegistryException e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		}
+	}
+
+	/**
+	 * Test if requestControl() correctly take control of specific switch.
+	 * Because requestControl() doesn't return values, inject mock LeaderLatch object and verify latch is correctly set up.
+	 * @throws Exception
+	 */
+	@Test
+	public void testRequestControl() 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.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);
+
+		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 releaseControl() correctly release control of specific switch.
+	 * Because releaseControl() doesn't return values, inject mock 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.removeAllListeners();
+		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 = 1000L;
+		LoggingCallback callback = new LoggingCallback(1);
+		
+		// to request and wait to take control
+		registry.requestControl(dpidToRequest, callback);
+		registry.releaseControl(dpidToRequest);
+		
+		// verify
+		EasyMock.verify(latch);
+	}
+
+	/**
+	 * Test if hasControl() 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.removeAllListeners();
+		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 getControllerForSwitch() correctly returns controller ID of specific switch.
+	 * Relation between controllers and switches are defined by 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 getSwitchesControlledByController() returns correct list of switches controlled by
+	 * a controller.
+	 * @throws Exception
+	 */
+	// TODO: Test after implementation of getSwitch() is done.
+	@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 getAllSwitches() returns correct list of all switches.
+	 * Switches are injected in 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 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());
+			}
+		}
+	}
+	
+	/**
+	 * Create mock CuratorFramework object with initial value below.
+	 *   [Ctrl ID]    : [DPID]
+	 * controller1    :  1000
+	 * controller2    :  1001
+	 * controller2    :  1002
+	 * controller2013 : nothing
+	 * @return Created mock object
+	 * @throws Exception
+	 */
+	@SuppressWarnings("serial")
+	private CuratorFramework createCuratorFrameworkMock() throws Exception {
+		// Mock of AtomicValue
+		@SuppressWarnings("unchecked")
+		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 of 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 of ListenerContainer
+		@SuppressWarnings("unchecked")
+		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 of 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 of 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 of ServiceCache
+		@SuppressWarnings("unchecked")
+		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 of ServiceCacheBuilder
+		@SuppressWarnings("unchecked")
+		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 of ServiceDiscovery
+		@SuppressWarnings("unchecked")
+		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 of 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 of ServiceDiscoveryBuilder
+		@SuppressWarnings("unchecked")
+		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 ServiceInstance object using given controller ID.
+	 * @param controllerId Controller ID to represent instance's payload (ControllerSeervice).
+	 * @return
+	 */
+	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 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
+	 * @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 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
+	 */
+	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,
+				createChildDataEventMock("controller1", HexString.toHexString(1000L), PathChildrenCacheEvent.Type.CHILD_ADDED));
+		pathChildrenCacheListener.childEvent(client,
+				createChildDataEventMock("controller2", HexString.toHexString(1001L), PathChildrenCacheEvent.Type.CHILD_ADDED));
+		pathChildrenCacheListener.childEvent(client,
+				createChildDataEventMock("controller2", HexString.toHexString(1002L), PathChildrenCacheEvent.Type.CHILD_ADDED));
+	}
+
+	/**
+	 * Create mock ChildDataEvent 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
+	 */
+	private PathChildrenCacheEvent createChildDataEventMock(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;
+	}
+}
