diff --git a/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java b/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
index e48c519..7e82bf0 100644
--- a/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
+++ b/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
@@ -116,10 +116,17 @@
 		throw new RuntimeException("Not yet implemented");
 	}
 	
+	private long blockTop = 0L;
+	private static final long BLOCK_SIZE = 0x1000000L;
 	@Override
 	public IdBlock allocateUniqueIdBlock(){
-		//XXX Not exactly unique...
-		return new IdBlock(0L, 0x10000000L, 0x10000000L);
+		long blockHead = blockTop;
+		long blockTail = blockTop + BLOCK_SIZE;
+		
+		IdBlock block = new IdBlock(blockHead, blockTail, BLOCK_SIZE);
+		blockTop = blockTail;
+		
+		return block;
 	}
 
 	@Override
diff --git a/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java b/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
index 82259a9..f9fb62e 100644
--- a/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
+++ b/src/main/java/net/onrc/onos/registry/controller/ZookeeperRegistry.java
@@ -109,13 +109,7 @@
 		}
 	}
 	
-	
-	/**
-	 * Listens for changes to the switch znodes in Zookeeper. This maintains
-	 * the second level of PathChildrenCaches that hold the controllers 
-	 * contending for each switch - there's one for each switch.
-	 */
-	PathChildrenCacheListener switchPathCacheListener = new PathChildrenCacheListener() {
+	protected class SwitchPathCacheListener implements PathChildrenCacheListener {
 		@Override
 		public void childEvent(CuratorFramework client,
 				PathChildrenCacheEvent event) throws Exception {
@@ -158,6 +152,12 @@
 			
 		}
 	};
+	/**
+	 * Listens for changes to the switch znodes in Zookeeper. This maintains
+	 * the second level of PathChildrenCaches that hold the controllers 
+	 * contending for each switch - there's one for each switch.
+	 */
+	PathChildrenCacheListener switchPathCacheListener = new SwitchPathCacheListener();
 	protected ServiceDiscovery<ControllerService> serviceDiscovery;
 	protected ServiceCache<ControllerService> serviceCache;
 
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;
+	}
+}
