Squashed commit of the following:

commit 7452e6d2acdbf0290c41b50ac4b7064411782a0e
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Tue Jun 25 14:36:29 2013 -0700

    Complete implementation of unit test for ZookeeperRegistry.

commit 9d35d5f09570872acf16977614f18b0be087580f
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Mon Jun 24 17:45:11 2013 -0700

    Debug

commit 07d43392e4324af93986e6095536727f3497e327
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Fri Jun 21 16:32:35 2013 -0700

    Implementation of mock CuratorFramework is done.

commit 9230449c4ed4326721e29abe8dc01b3115a74041
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Fri Jun 21 13:52:25 2013 -0700

    Add some mock object to ZookeeperRegistry

commit 912a03932e8b1c60f19a9daadf08fb719e5ccf92
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Thu Jun 20 11:43:47 2013 -0700

    Create test class for ZookeeperRegistry

commit 68e4ae5e9b0f265c3f21ce757b36381a9368826a
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Wed Jun 19 17:46:03 2013 -0700

    Implement StandaloneRegistryTest

commit d81bf9f11159df9abf545bc471970a78ccdf1193
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Tue Jun 18 15:47:37 2013 -0700

    Create test class for StandAloneRegistry
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;
+	}
+}