Merge branch 'proxyarp'
diff --git a/README.md b/README.md
index 8c0cc0a..495a2ed 100644
--- a/README.md
+++ b/README.md
@@ -18,6 +18,7 @@
     $ mvn clean
     $ mvn compile
 
+    NOTE: installing maven for the first time may switch java version from 1.7 to 1.6 causing cassandra to not run
 
 Dependencies
 ------------
diff --git a/cluster-mgmt/bin/func.sh b/cluster-mgmt/bin/func.sh
index fe65ab6..b42ead1 100755
--- a/cluster-mgmt/bin/func.sh
+++ b/cluster-mgmt/bin/func.sh
@@ -29,9 +29,11 @@
   case "$1" in
     start)
       echo "Starting ZK.."
-      dsh -g $basename "$ZK_DIR/bin/zkServer.sh start"
+#      dsh -g $basename "$ZK_DIR/bin/zkServer.sh start"
+      dsh -g $basename 'cd ONOS; ./start-zk.sh start'
       while [ 1 ]; do
-        nup=`dsh -g $basename "$ZK_DIR/bin/zkServer.sh status" | grep "Mode" | egrep "leader|follower" | wc -l`
+#        nup=`dsh -g $basename "$ZK_DIR/bin/zkServer.sh status" | grep "Mode" | egrep "leader|follower" | wc -l`
+        nup=`dsh -g $basename "cd ONOS; ./start-zk.sh status" | grep "Mode" | egrep "leader|follower|standalone" | wc -l`
         if [ $nup == $nr_nodes ]; then
           echo "everybody's up: $nup up of of $nr_nodes"
           echo "ZK started"
@@ -125,7 +127,9 @@
     start)
       if [ x$2 == "x" -o x$2 == "xall" ]; then
         echo "Starting ONOS on all nodes"
-        dsh -g ${basename} "cd $ONOS_DIR; ./start-onos.sh start"
+        dsh -w ${basename}1 "cd $ONOS_DIR; ./start-onos.sh start"
+        sleep 3
+        dsh -g ${basename} -x ${basename}1 "cd $ONOS_DIR; ./start-onos.sh start"
         dsh -g ${basename} "cd $ONOS_DIR; ./start-rest.sh start"
       else
         echo "Starting ONOS on ${basename}$2"
diff --git a/cluster-mgmt/bin/zk b/cluster-mgmt/bin/zk
index 262c936..b2033ad 100755
--- a/cluster-mgmt/bin/zk
+++ b/cluster-mgmt/bin/zk
@@ -1,5 +1,5 @@
 #! /bin/bash
-. ${HOME}/bin/func.sh
+. `dirname $0`/func.sh
 
 #$0 $1 $2
 `basename $0` $1 $2
diff --git a/cluster-mgmt/template/onsdemo_core.py.devA b/cluster-mgmt/template/onsdemo_core.py.devA
new file mode 100755
index 0000000..ad74e4b
--- /dev/null
+++ b/cluster-mgmt/template/onsdemo_core.py.devA
@@ -0,0 +1,158 @@
+#!/usr/bin/python
+
+"""
+Start up a Simple topology
+"""
+from mininet.net import Mininet
+from mininet.node import Controller, RemoteController
+from mininet.log import setLogLevel, info, error, warn, debug
+from mininet.cli import CLI
+from mininet.topo import Topo
+from mininet.util import quietRun
+from mininet.moduledeps import pathCheck
+from mininet.link import Link, TCLink
+
+from sys import exit
+import os.path
+from subprocess import Popen, STDOUT, PIPE
+
+import sys
+
+
+#import argparse
+
+class MyController( Controller ):
+    def __init__( self, name, ip='127.0.0.1', port=6633, **kwargs):
+        """Init.
+           name: name to give controller
+           ip: the IP address where the remote controller is
+           listening
+           port: the port where the remote controller is listening"""
+        Controller.__init__( self, name, ip=ip, port=port, **kwargs )
+
+    def start( self ):
+        "Overridden to do nothing."
+        return
+
+    def stop( self ):
+        "Overridden to do nothing."
+        return
+
+    def checkListening( self ):
+        "Warn if remote controller is not accessible"
+        listening = self.cmd( "echo A | telnet -e A %s %d" %
+                              ( self.ip, self.port ) )
+        if 'Unable' in listening:
+            warn( "Unable to contact the remote controller"
+                  " at %s:%d\n" % ( self.ip, self.port ) )
+
+class SDNTopo( Topo ):
+    "SDN Topology"
+
+    def __init__( self, *args, **kwargs ):
+        Topo.__init__( self, *args, **kwargs )
+
+        sw5 = self.addSwitch('sw5', dpid='00000000ba5eba13')
+        sw2 = self.addSwitch('sw2', dpid='00000000ba5eba11')
+        sw3 = self.addSwitch('sw3', dpid='00000008a208f901')
+        sw4 = self.addSwitch('sw4', dpid='000000000000ba12')
+        sw6 = self.addSwitch('sw6', dpid='0000204e7f518a35')
+        sw1 = self.addSwitch('sw1', dpid='0000001697089a46')
+
+        host1 = self.addHost( 'host1' )
+        host2 = self.addHost( 'host2' )
+        host3 = self.addHost( 'host3' )
+        host4 = self.addHost( 'host4' )
+        host5 = self.addHost( 'host5' )
+        host6 = self.addHost( 'host6' )
+
+        self.addLink( host1, sw1 )
+        self.addLink( host2, sw2 )
+        self.addLink( host3, sw3 )
+        self.addLink( host4, sw4 )
+        self.addLink( host5, sw5 )
+        self.addLink( host6, sw6 )
+
+        self.addLink( sw1, sw2 )
+        self.addLink( sw1, sw6 )
+        self.addLink( sw2, sw3 )
+        self.addLink( sw3, sw4 )
+        self.addLink( sw3, sw6 )
+        self.addLink( sw4, sw5 )
+        self.addLink( sw5, sw6 )
+        self.addLink( sw4, sw6 )
+
+def startsshd( host ):
+    "Start sshd on host"
+    info( '*** Starting sshd\n' )
+    name, intf, ip = host.name, host.defaultIntf(), host.IP()
+    banner = '/tmp/%s.banner' % name
+    host.cmd( 'echo "Welcome to %s at %s" >  %s' % ( name, ip, banner ) )
+    host.cmd( '/usr/sbin/sshd -o "Banner %s"' % banner, '-o "UseDNS no"' )
+    info( '***', host.name, 'is running sshd on', intf, 'at', ip, '\n' )
+
+def startsshds ( hosts ):
+    for h in hosts:
+        startsshd( h )
+
+def stopsshd( ):
+    "Stop *all* sshd processes with a custom banner"
+    info( '*** Shutting down stale sshd/Banner processes ',
+          quietRun( "pkill -9 -f Banner" ), '\n' )
+
+def sdnnet(opt):
+#    os.system('/home/ubuntu/openflow/controller/controller ptcp: &')
+#    os.system('/home/ubuntu/openflow/controller/controller ptcp:7000 &')
+
+    topo = SDNTopo()
+    info( '*** Creating network\n' )
+#    net = Mininet( topo=topo, controller=RemoteController )
+    net = Mininet( topo=topo, controller=MyController, link=TCLink)
+#    dc = DebugController('c3', ip='127.0.0.1', port=7000)
+#    net.addController(dc)
+#    net.addController(controller=RemoteController)
+
+    host1, host2, host3, host4, host5, host6 = net.get( 'host1', 'host2', 'host3', 'host4', 'host5', 'host6')
+
+    ## Adding 2nd, 3rd and 4th interface to host1 connected to sw1 (for another BGP peering)
+    sw1 = net.get('sw1')
+    sw2 = net.get('sw2')
+    sw3 = net.get('sw3')
+    sw4 = net.get('sw4')
+    sw5 = net.get('sw5')
+    sw6 = net.get('sw6')
+
+    net.start()
+
+    sw2.attach('tap01_2')
+    sw3.attach('tap01_3')
+    sw4.attach('tap01_4')
+    sw4.attach('tap01_5')
+    sw5.attach('tap01_6')
+    sw6.attach('tap01_7')
+    sw1.attach('tap01_8')
+
+    host1.defaultIntf().setIP('192.168.100.141/16') 
+    host2.defaultIntf().setIP('192.168.100.142/16')
+    host3.defaultIntf().setIP('192.168.100.143/16')
+    host4.defaultIntf().setIP('192.168.100.144/16')
+    host5.defaultIntf().setIP('192.168.100.145/16')
+    host6.defaultIntf().setIP('192.168.100.146/16')
+
+    hosts = [ host1, host2, host3, host4, host5, host6 ]
+    stopsshd ()
+    startsshds ( hosts )
+
+    if opt=="cli":
+        CLI(net)
+        stopsshd()
+        net.stop()
+
+if __name__ == '__main__':
+    setLogLevel( 'info' )
+    if len(sys.argv) == 1:
+      sdnnet("cli")
+    elif len(sys.argv) == 2 and sys.argv[1] == "-n":
+      sdnnet("nocli")
+    else:
+      print "%s [-n]" % sys.argv[0]
diff --git a/pom.xml b/pom.xml
index 0a8c37c..52fe30a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -112,16 +112,53 @@
           </execution>
         </executions>
       </plugin>-->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <version>2.9</version>
+        <configuration>
+          <charset>UTF-8</charset>
+          <locale>en</locale>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
   <!-- for getting visualization reporting   -->
   <reporting>
+    <excludeDefaults>true</excludeDefaults>
+    <outputDirectory>${project.build.directory}/site</outputDirectory>
     <plugins>
       <plugin>
         <groupId>org.apache.camel</groupId>
         <artifactId>guice-maven-plugin</artifactId>
         <version>2.11.0</version>
       </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-project-info-reports-plugin</artifactId>
+        <version>2.4</version>
+        <configuration>
+          <dependencyDetailsEnabled>false</dependencyDetailsEnabled>
+          <dependencyLocationsEnabled>false</dependencyLocationsEnabled>
+        </configuration>
+        <reportSets>
+          <reportSet>
+            <reports>
+              <report>dependencies</report>
+              <report>scm</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <version>2.9</version>
+        <configuration>
+          <charset>UTF-8</charset>
+          <locale>en</locale>
+        </configuration>
+      </plugin>
     </plugins>
   </reporting>
   <dependencies>
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
index d08da7c..3a5c9e2 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
@@ -14,6 +14,12 @@
 import com.tinkerpop.frames.annotations.gremlin.GremlinParam;
 import com.tinkerpop.frames.VertexFrame;
 
+/*
+ * This is the interfaces to make the objects for Cassandra DB.
+ * They are interfaces, but it is also implementation,
+ * so this handles various control to the objects.  
+ * Please take a look at tinkerpop/frames annotation doc to understand more.
+ */
 public interface INetMapTopologyObjects {
 	
 public interface IBaseObject extends VertexFrame {
@@ -62,7 +68,7 @@
 		public Iterable<IDeviceObject> getDevices();
 		
 		@JsonIgnore
-		@Incidence(label="switch",direction = Direction.IN)
+		@Adjacency(label="switch",direction = Direction.IN)
 		public Iterable<IFlowEntry> getFlowEntries();
 
 	}
@@ -114,11 +120,11 @@
 		public void removeDevice(final IDeviceObject device);
 		
 		@JsonIgnore
-		@Incidence(label="inport",direction = Direction.IN)
+		@Adjacency(label="inport",direction = Direction.IN)
 		public Iterable<IFlowEntry> getInFlowEntries();
 		
 		@JsonIgnore
-		@Incidence(label="outport",direction = Direction.IN)
+		@Adjacency(label="outport",direction = Direction.IN)
 		public Iterable<IFlowEntry> getOutFlowEntries();
 		
 		@JsonIgnore
@@ -155,11 +161,11 @@
 		public Iterable<IPortObject> getAttachedPorts();
 			
 		@JsonIgnore
-		@Incidence(label="host",direction=Direction.IN)
+		@Adjacency(label="host",direction=Direction.IN)
 		public void setHostPort(final IPortObject port);
 		
 		@JsonIgnore
-		@Incidence(label="host",direction=Direction.IN)
+		@Adjacency(label="host",direction=Direction.IN)
 		public void removeHostPort(final IPortObject port);
 		
 		@JsonIgnore
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
index 50783c9..6e42771 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
@@ -22,6 +22,9 @@
 import com.tinkerpop.pipes.PipeFunction;
 import com.tinkerpop.pipes.transform.PathPipe;
 
+/**
+ * This is the class for storing the information of links into CassandraDB
+ */
 public class LinkStorageImpl implements ILinkStorage {
 	
 	protected static Logger log = LoggerFactory.getLogger(LinkStorageImpl.class);
@@ -126,7 +129,7 @@
 	}
 	
 	/**
-	 * Delete multiple records in the LinkStorage.
+	 * Delete multiple records in LinkStorage.
 	 * @param links List of records to be deleted.
 	 */
 	@Override
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
index 03a5e8e..126efb3 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
@@ -72,7 +72,8 @@
 		
 		log.info("SwitchStorage:addSwitch(): dpid {} ", dpid);
 		try {
-			newSwitch(dpid);
+			ISwitchObject sw = newSwitch(dpid);
+			if ( sw == null ) throw new RuntimeException();
             op.commit();
 		} catch (Exception e) {
 			e.printStackTrace();
diff --git a/src/main/java/net/onrc/onos/ofcontroller/routing/TopoRouteService.java b/src/main/java/net/onrc/onos/ofcontroller/routing/TopoRouteService.java
index 432e578..5328eae 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/routing/TopoRouteService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/routing/TopoRouteService.java
@@ -40,6 +40,10 @@
  * of shortest paths.
  */
 class Node {
+    /**
+     * A class for storing Link information for fast computation of shortest
+     * paths.
+     */
     class Link {
 	public Node me;			// The node this link originates from
 	public Node neighbor;		// The neighbor node on the other side
@@ -90,7 +94,9 @@
     }
 };
 
-
+/**
+ * A class for implementing Topology Route Service.
+ */
 public class TopoRouteService implements IFloodlightModule, ITopoRouteService {
 
     /** The logger. */
@@ -99,6 +105,11 @@
     
     protected GraphDBOperation op;
 
+    /**
+     * Get the collection of module services.
+     *
+     * @return the collection of services provided by this module.
+     */
     @Override
     public Collection<Class<? extends IFloodlightService>> getModuleServices() {
         Collection<Class<? extends IFloodlightService>> l = 
@@ -107,6 +118,11 @@
         return l;
     }
 
+    /**
+     * Get a map with the services provided by this module.
+     *
+     * @return a map with the services provided by this module.
+     */
     @Override
     public Map<Class<? extends IFloodlightService>, IFloodlightService> 
 			       getServiceImpls() {
@@ -118,6 +134,11 @@
         return m;
     }
 
+    /**
+     * Get the collection with the services this module depends on.
+     *
+     * @return the collection with the services this module depends on.
+     */
     @Override
     public Collection<Class<? extends IFloodlightService>> 
                                                     getModuleDependencies() {
@@ -128,6 +149,12 @@
         return l;
     }
 
+    /**
+     * Init the module.
+     *
+     * @param context the module context to use for the initialization.
+     * @see FloodlightModuleContext.
+     */
     @Override
     public void init(FloodlightModuleContext context)
 	throws FloodlightModuleException {
@@ -135,25 +162,22 @@
     	op = new GraphDBOperation("");
     }
 
+    /**
+     * Startup initialization.
+     */
     @Override
     public void startUp(FloodlightModuleContext context) {
 	// TODO: Add the approprate setup
     }
 
-
-    static class ShortestPathLoopFunction implements PipeFunction<LoopBundle<Vertex>, Boolean> {
-	String dpid;
-	public ShortestPathLoopFunction(String dpid) {
-	    super();
-	    this.dpid = dpid;
-	}
-	public Boolean compute(LoopBundle<Vertex> bundle) {
-	    Boolean output = false;
-	    if (! bundle.getObject().getProperty("dpid").equals(dpid)) {
-		output = true;
-	    }
-	    return output;
-	}
+    /**
+     * Set the database operation handler.
+     *
+     * @param init_op the database operation handler to use for the
+     * initialization.
+     */
+    public void setDbOperationHandler(GraphDBOperation init_op) {
+    	op = init_op;
     }
 
     /**
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/FlowId.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowId.java
index 2310972..de955ba 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/FlowId.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowId.java
@@ -13,7 +13,7 @@
  */
 @JsonDeserialize(using=FlowIdDeserializer.class)
 @JsonSerialize(using=FlowIdSerializer.class)
-public class FlowId {
+public class FlowId implements Comparable<FlowId> {
     private long value;
 
     /**
@@ -76,4 +76,16 @@
     public String toString() {
 	return "0x" + Long.toHexString(this.value);
     }
+
+    /**
+     * Compare two FlowId objects numerically using their Flow IDs.
+     *
+     * @return the value 0 if the Flow ID is equal to the argument's Flow ID;
+     *         a value less than 0 if the Flow ID is numerically less than the argument's Flow ID;
+     *         and a value greater than 0 if the Flow ID is numerically greater than the argument's Flow ID.
+     */
+ 	@Override
+	public int compareTo(FlowId o) {
+		return Long.valueOf(this.value).compareTo(o.value());
+	}
 }
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..640a49d 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,22 @@
 		throw new RuntimeException("Not yet implemented");
 	}
 	
+	private long blockTop = 0L;
+	private static final long BLOCK_SIZE = 0x1000000L;
+	
+	/**
+	 * Returns a block of IDs which are unique and unused.
+	 * Range of IDs is fixed size and is assigned incrementally as this method called.
+	 */
 	@Override
-	public IdBlock allocateUniqueIdBlock(){
-		//XXX Not exactly unique...
-		return new IdBlock(0L, 0x10000000L, 0x10000000L);
+	public synchronized IdBlock allocateUniqueIdBlock(){
+		long blockHead = blockTop;
+		long blockTail = blockTop + BLOCK_SIZE;
+		
+		IdBlock block = new IdBlock(blockHead, blockTail - 1, 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..2d2083f 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;
 
@@ -379,6 +379,12 @@
 		return data;
 	}
 	
+	/**
+	 * Returns a block of IDs which are unique and unused.
+	 * Range of IDs is fixed size and is assigned incrementally as this method called.
+	 * Since the range of IDs is managed by Zookeeper in distributed way, this method may block when
+	 * requests come up simultaneously.
+	 */
 	public IdBlock allocateUniqueIdBlock(){
 		try {
 			AtomicValue<Long> result = null;
diff --git a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
index 88e2d35..ecdc2d7 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
@@ -70,6 +70,12 @@
 import net.floodlightcontroller.test.FloodlightTestCase;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 import net.onrc.onos.ofcontroller.core.IOFSwitchPortListener;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoRouteService;
+import net.onrc.onos.ofcontroller.flowmanager.FlowManager;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
+import net.onrc.onos.ofcontroller.routing.TopoRouteService;
+import net.onrc.onos.registry.controller.IControllerRegistryService;
+import net.onrc.onos.registry.controller.StandaloneRegistry;
 
 import org.easymock.Capture;
 import org.easymock.EasyMock;
@@ -82,6 +88,8 @@
 import org.openflow.protocol.OFPacketIn;
 import org.openflow.protocol.OFPacketIn.OFPacketInReason;
 import org.openflow.protocol.OFPhysicalPort;
+import org.openflow.protocol.OFPhysicalPort.OFPortConfig;
+import org.openflow.protocol.OFPhysicalPort.OFPortState;
 import org.openflow.protocol.OFPortStatus;
 import org.openflow.protocol.OFPortStatus.OFPortReason;
 import org.openflow.protocol.OFStatisticsReply;
@@ -128,16 +136,26 @@
         tp = new MockThreadPoolService();
         fmc.addService(IThreadPoolService.class, tp);
         
+        // Following added by ONOS
+        // TODO replace with mock if further testing is needed.
+        fmc.addService(IFlowService.class, new FlowManager() );
+        fmc.addService(ITopoRouteService.class, new TopoRouteService() );
+        StandaloneRegistry sr = new StandaloneRegistry();
+        fmc.addService(IControllerRegistryService.class, sr );
+
+        
         ppt.init(fmc);
         restApi.init(fmc);
         memstorage.init(fmc);
         cm.init(fmc);
         tp.init(fmc);
+        sr.init(fmc);
         ppt.startUp(fmc);
         restApi.startUp(fmc);
         memstorage.startUp(fmc);
         cm.startUp(fmc);
         tp.startUp(fmc);
+        sr.startUp(fmc);
     }
 
     public Controller getController() {
@@ -394,7 +412,6 @@
         expect(newsw.getBuffers()).andReturn(0).anyTimes();
         expect(newsw.getTables()).andReturn((byte)0).anyTimes();
         expect(newsw.getActions()).andReturn(0).anyTimes();
-        expect(newsw.getPorts()).andReturn(new ArrayList<OFPhysicalPort>());
         controller.activeSwitches.put(0L, oldsw);
         replay(newsw, channel, channel2);
 
@@ -647,7 +664,7 @@
         assertTrue("Check that update is HARoleUpdate", 
                    upd instanceof Controller.HARoleUpdate);
         Controller.HARoleUpdate roleUpd = (Controller.HARoleUpdate)upd;
-        assertSame(null, roleUpd.oldRole);
+        assertSame(Role.MASTER, roleUpd.oldRole);
         assertSame(Role.SLAVE, roleUpd.newRole);
     }
     
@@ -701,15 +718,16 @@
         state.hasGetConfigReply = true;
         // Role support disabled. Switch should be promoted to active switch
         // list. 
-        setupSwitchForAddSwitch(chdlr.sw, 0L);
-        chdlr.sw.clearAllFlowMods();
-        replay(controller.roleChanger, chdlr.sw);
-        chdlr.checkSwitchReady();
-        verify(controller.roleChanger, chdlr.sw);
-        assertSame(OFChannelState.HandshakeState.READY, state.hsState);
-        assertSame(chdlr.sw, controller.activeSwitches.get(0L));
-        assertTrue(controller.connectedSwitches.contains(chdlr.sw));
-        assertTrue(state.firstRoleReplyReceived);
+// FIXME: ONOS modified the behavior to always submit Role Request to trigger OFS error.
+//        setupSwitchForAddSwitch(chdlr.sw, 0L);
+//        chdlr.sw.clearAllFlowMods();
+//        replay(controller.roleChanger, chdlr.sw);
+//        chdlr.checkSwitchReady();
+//        verify(controller.roleChanger, chdlr.sw);
+//        assertSame(OFChannelState.HandshakeState.READY, state.hsState);
+//        assertSame(chdlr.sw, controller.activeSwitches.get(0L));
+//        assertTrue(controller.connectedSwitches.contains(chdlr.sw));
+//        assertTrue(state.firstRoleReplyReceived);
         reset(chdlr.sw);
         reset(controller.roleChanger);
         controller.connectedSwitches.clear();
@@ -719,9 +737,15 @@
         // Role support enabled. 
         state.hsState = OFChannelState.HandshakeState.FEATURES_REPLY;
         controller.role = Role.MASTER;
+        expect(chdlr.sw.getStringId()).andReturn("SomeID").anyTimes();
+        expect(chdlr.sw.getId()).andReturn(42L).anyTimes();
         Capture<Collection<OFSwitchImpl>> swListCapture = 
                     new Capture<Collection<OFSwitchImpl>>();
         controller.roleChanger.submitRequest(capture(swListCapture), 
+                    same(Role.SLAVE));
+        Capture<Collection<OFSwitchImpl>> swListCapture2 = 
+                new Capture<Collection<OFSwitchImpl>>();
+        controller.roleChanger.submitRequest(capture(swListCapture2), 
                     same(Role.MASTER));
         replay(controller.roleChanger, chdlr.sw);
         chdlr.checkSwitchReady();
@@ -729,7 +753,7 @@
         assertSame(OFChannelState.HandshakeState.READY, state.hsState);
         assertTrue(controller.activeSwitches.isEmpty());
         assertTrue(controller.connectedSwitches.contains(chdlr.sw));
-        assertTrue(state.firstRoleReplyReceived);
+//        assertTrue(state.firstRoleReplyReceived);
         Collection<OFSwitchImpl> swList = swListCapture.getValue();
         assertEquals(1, swList.size());
         assertTrue("swList must contain this switch", swList.contains(chdlr.sw));
@@ -825,7 +849,7 @@
         state.firstRoleReplyReceived = false;
         controller.role = Role.SLAVE;
         expect(chdlr.sw.checkFirstPendingRoleRequestXid(xid)).andReturn(true);
-        chdlr.sw.deliverRoleRequestNotSupportedEx(xid);
+        expect(chdlr.sw.deliverRoleRequestNotSupportedEx(xid)).andReturn(Role.SLAVE);
         expect(chdlr.sw.getChannel()).andReturn(ch).anyTimes();
         expect(ch.close()).andReturn(null);
         
@@ -845,7 +869,7 @@
         state.firstRoleReplyReceived = false;
         controller.role = Role.SLAVE;
         expect(chdlr.sw.checkFirstPendingRoleRequestXid(xid)).andReturn(true);
-        chdlr.sw.deliverRoleRequestNotSupportedEx(xid);
+        expect(chdlr.sw.deliverRoleRequestNotSupportedEx(xid)).andReturn(Role.SLAVE);
         expect(chdlr.sw.getChannel()).andReturn(ch).anyTimes();
         expect(ch.close()).andReturn(null);
         replay(ch, chdlr.sw);
@@ -864,7 +888,7 @@
         state.firstRoleReplyReceived = false;
         controller.role = Role.MASTER;
         expect(chdlr.sw.checkFirstPendingRoleRequestXid(xid)).andReturn(true);
-        chdlr.sw.deliverRoleRequestNotSupportedEx(xid);
+        expect(chdlr.sw.deliverRoleRequestNotSupportedEx(xid)).andReturn(Role.MASTER);
         setupSwitchForAddSwitch(chdlr.sw, 0L);
         chdlr.sw.clearAllFlowMods();
         replay(ch, chdlr.sw);
@@ -1102,6 +1126,26 @@
         assertEquals(SwitchUpdateType.PORTCHANGED, swUpdate.switchUpdateType);
     }
     
+    public void verifyPortAddedUpdateInQueue(IOFSwitch sw) throws Exception {
+        assertEquals(2, controller.updates.size());
+        IUpdate update = controller.updates.take();
+        assertEquals(true, update instanceof SwitchUpdate);
+        SwitchUpdate swUpdate = (SwitchUpdate)update;
+        assertEquals(sw, swUpdate.sw);
+        assertEquals(SwitchUpdateType.PORTADDED, swUpdate.switchUpdateType);
+        verifyPortChangedUpdateInQueue(sw);
+    }
+    
+    public void verifyPortRemovedUpdateInQueue(IOFSwitch sw) throws Exception {
+        assertEquals(2, controller.updates.size());
+        IUpdate update = controller.updates.take();
+        assertEquals(true, update instanceof SwitchUpdate);
+        SwitchUpdate swUpdate = (SwitchUpdate)update;
+        assertEquals(sw, swUpdate.sw);
+        assertEquals(SwitchUpdateType.PORTREMOVED, swUpdate.switchUpdateType);
+        verifyPortChangedUpdateInQueue(sw);
+    }
+    
     /*
      * Test handlePortStatus()
      * TODO: test correct updateStorage behavior!
@@ -1122,25 +1166,51 @@
         replay(sw);
         controller.handlePortStatusMessage(sw, ofps, false);
         verify(sw);
-        verifyPortChangedUpdateInQueue(sw);
+        verifyPortAddedUpdateInQueue(sw);
         reset(sw);
         
+        // ONOS:Port is considered added if Link state is not down and not configured to be down
         ofps.setReason((byte)OFPortReason.OFPPR_MODIFY.ordinal());
         sw.setPort(port);
         expectLastCall().once();
         replay(sw);
         controller.handlePortStatusMessage(sw, ofps, false);
         verify(sw);
-        verifyPortChangedUpdateInQueue(sw);
+        verifyPortAddedUpdateInQueue(sw);
         reset(sw);
         
+        // ONOS:Port is considered removed if Link state is down
+        ofps.setReason((byte)OFPortReason.OFPPR_MODIFY.ordinal());
+        port.setState(OFPortState.OFPPS_LINK_DOWN.getValue());
+        sw.setPort(port);
+        expectLastCall().once();
+        replay(sw);
+        controller.handlePortStatusMessage(sw, ofps, false);
+        verify(sw);
+        verifyPortRemovedUpdateInQueue(sw);
+        reset(sw);
+        port.setState(0);// reset
+        
+        // ONOS: .. or is configured to be down
+        ofps.setReason((byte)OFPortReason.OFPPR_MODIFY.ordinal());
+        port.setConfig(OFPortConfig.OFPPC_PORT_DOWN.getValue());
+        sw.setPort(port);
+        expectLastCall().once();
+        replay(sw);
+        controller.handlePortStatusMessage(sw, ofps, false);
+        verify(sw);
+        verifyPortRemovedUpdateInQueue(sw);
+        reset(sw);
+        port.setConfig(0);// reset
+        
+        
         ofps.setReason((byte)OFPortReason.OFPPR_DELETE.ordinal());
         sw.deletePort(port.getPortNumber());
         expectLastCall().once();
         replay(sw);
         controller.handlePortStatusMessage(sw, ofps, false);
         verify(sw);
-        verifyPortChangedUpdateInQueue(sw);
+        verifyPortRemovedUpdateInQueue(sw);
         reset(sw);
     }
 }
diff --git a/src/test/java/net/floodlightcontroller/core/internal/RoleChangeCallbackTest.java b/src/test/java/net/floodlightcontroller/core/internal/RoleChangeCallbackTest.java
new file mode 100644
index 0000000..2aeb60e
--- /dev/null
+++ b/src/test/java/net/floodlightcontroller/core/internal/RoleChangeCallbackTest.java
@@ -0,0 +1,143 @@
+package net.floodlightcontroller.core.internal;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+// Extends Controller class to access protected inner class
+public class RoleChangeCallbackTest extends Controller {
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	/**
+	 * Test if {@link RoleChangeCallback#controlChanged(long, boolean)} correctly calls {@link RoleChanger#submitRequest(Collection, net.floodlightcontroller.core.IFloodlightProviderService.Role)}
+	 * when connectedSwitch is not empty.
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	@Test
+	public void testNormalSwitches() throws Exception {
+		Long [] dpids = new Long [] { 1000L, 1001L, 1002L, 1003L };
+		final long dpidExist = 1000L;
+		final long dpidNotExist = 2000L;
+		
+		roleChanger = EasyMock.createMock(RoleChanger.class);
+		
+		// First call will be called with (dpidExist,true)
+		roleChanger.submitRequest(EasyMock.anyObject(Collection.class), EasyMock.anyObject(Role.class));
+		EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+			@Override
+			public Object answer() throws Throwable {
+				Collection<OFSwitchImpl> switches = (Collection<OFSwitchImpl>)EasyMock.getCurrentArguments()[0];
+				Role role = (Role)EasyMock.getCurrentArguments()[1];
+
+				List<Long> dpids = new ArrayList<Long>();
+				
+				for(OFSwitchImpl sw : switches) {
+					dpids.add(sw.getId());
+				}
+				assertTrue(dpids.contains(dpidExist));
+				assertEquals(role, Role.MASTER);
+				
+				return null;
+			}
+		}).once();
+
+		// Second call will be called with (dpidExist,false)
+		roleChanger.submitRequest(EasyMock.anyObject(Collection.class), EasyMock.anyObject(Role.class));
+		EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+			@Override
+			public Object answer() throws Throwable {
+				Collection<OFSwitchImpl> switches = (Collection<OFSwitchImpl>)EasyMock.getCurrentArguments()[0];
+				Role role = (Role)EasyMock.getCurrentArguments()[1];
+
+				List<Long> dpids = new ArrayList<Long>();
+				
+				for(OFSwitchImpl sw : switches) {
+					dpids.add(sw.getId());
+				}
+				assertTrue(dpids.contains(dpidExist));
+				assertEquals(role, Role.SLAVE);
+				
+				return null;
+			}
+		}).once();
+
+		EasyMock.replay(roleChanger);
+		
+		initNetwork(roleChanger, dpids);
+		
+		RoleChangeCallback callback = new RoleChangeCallback();
+		callback.controlChanged(dpidExist, true);
+		callback.controlChanged(dpidExist, false);
+		callback.controlChanged(dpidNotExist, true);
+		callback.controlChanged(dpidNotExist, false);
+		
+		EasyMock.verify(roleChanger);
+	}
+
+	/**
+	 * Test if {@link RoleChangeCallback#controlChanged(long, boolean)} doesn't call RoleChanger methods
+	 * when connectedSwitch is empty.
+	 * @throws Exception
+	 */
+	@Test
+	public void testEmptySwitches() throws Exception {
+		Long [] dpids = new Long [] {};
+		final long dpidToTest = 1000L;
+		
+		roleChanger = EasyMock.createMock(RoleChanger.class);
+		// roleChanger methods must not be used
+		EasyMock.replay(roleChanger);
+		
+		initNetwork(roleChanger, dpids);
+		
+		RoleChangeCallback callback = new RoleChangeCallback();
+		callback.controlChanged(dpidToTest, true);
+		callback.controlChanged(dpidToTest, false);
+		
+		EasyMock.verify(roleChanger);
+	}
+	
+	/**
+	 * Create mock OFSwitchImpl object.
+	 * @param id
+	 * @return
+	 */
+	private OFSwitchImpl createOFSwitchImplMock(Long id) {
+		OFSwitchImpl sw = EasyMock.createMock(OFSwitchImpl.class);
+
+		EasyMock.expect(sw.getId()).andReturn(id).anyTimes();
+		EasyMock.replay(sw);
+		
+		return sw;
+	}
+	
+	/**
+	 * Setup connectedSwitches
+	 * @param changer
+	 * @param ids
+	 * @throws Exception
+	 */
+	private void initNetwork(RoleChanger changer, Long [] ids) throws Exception {
+		connectedSwitches = new HashSet<OFSwitchImpl>();
+		
+		for(Long id : ids) {
+			connectedSwitches.add(createOFSwitchImplMock(id));
+		}
+	}
+}
diff --git a/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java b/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java
index 991afff..a6a6d85 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java
@@ -16,6 +16,7 @@
 import org.easymock.EasyMock;
 import org.jboss.netty.channel.Channel;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
 public class RoleChangerTest {
@@ -58,6 +59,7 @@
      * The connection should be closed.
      */
     @Test
+    @Ignore // FIXME: ONOS modified the behavior here to intentionally trigger OFS error.
     public void testSendRoleRequestMasterNotSupported() {
         LinkedList<OFSwitchImpl> switches = new LinkedList<OFSwitchImpl>();
         
diff --git a/src/test/java/net/onrc/onos/graph/GraphDBConnectionTest.java b/src/test/java/net/onrc/onos/graph/GraphDBConnectionTest.java
new file mode 100644
index 0000000..bee936d
--- /dev/null
+++ b/src/test/java/net/onrc/onos/graph/GraphDBConnectionTest.java
@@ -0,0 +1,229 @@
+/**
+ * 
+ */
+package net.onrc.onos.graph;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.expect;
+import static org.powermock.api.easymock.PowerMock.*;
+
+import java.util.*;
+
+import net.onrc.onos.graph.GraphDBOperation;
+
+import org.easymock.IAnswer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.util.wrappers.event.EventTransactionalGraph;
+import com.tinkerpop.frames.FramedGraph;
+
+/**
+ * @author Toshio Koide
+ *
+ */
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({
+	GraphDBConnection.class,
+	GraphDBOperation.class,
+	TitanFactory.class,
+	EventTransactionalGraph.class})
+public class GraphDBConnectionTest {
+	private static TitanGraph graph = null;
+	private static EventTransactionalGraph<TitanGraph> eg = null;
+	private static Boolean isGraphOpen = false;
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	
+	private void expectDBConnectionAvailable() throws Exception {
+		isGraphOpen = false;
+		
+		// create mock objects
+		mockStatic(TitanFactory.class);
+		mockStatic(EventTransactionalGraph.class);
+		graph = createMock(TitanGraph.class);
+		eg = createMock(EventTransactionalGraph.class);
+		
+		// setup expectations
+		expect(graph.isOpen()).andAnswer(new IAnswer<Boolean>() {
+			@Override
+			public Boolean answer() throws Throwable {
+				return isGraphOpen;
+			}
+		}).anyTimes();
+		expect(TitanFactory.open("/path/to/dummy")).andAnswer(new IAnswer<TitanGraph>() {
+			@Override
+			public TitanGraph answer() throws Throwable {
+				isGraphOpen = true;
+				return graph;
+			}
+		}).anyTimes();
+		expect(graph.getIndexedKeys(Vertex.class)).andReturn(new TreeSet<String>());
+		graph.createKeyIndex("dpid", Vertex.class);
+		graph.createKeyIndex("port_id", Vertex.class);
+		graph.createKeyIndex("type", Vertex.class);
+		graph.createKeyIndex("dl_addr", Vertex.class);
+		graph.createKeyIndex("flow_id", Vertex.class);
+		graph.createKeyIndex("flow_entry_id", Vertex.class);
+		graph.createKeyIndex("switch_state", Vertex.class);
+		graph.commit();
+		expectNew(EventTransactionalGraph.class, graph).andReturn(eg);
+	}
+	
+	/**
+	 * Test method for {@link net.onrc.onos.graph.GraphDBConnection#getInstance(java.lang.String)}.
+	 * @throws Exception
+	 */
+	@Test
+	public final void testGetInstance() throws Exception {
+		// setup expectations
+		expectDBConnectionAvailable();
+		
+		// start the test
+		replayAll();
+		GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
+
+		// verify the test
+		verifyAll();
+		assertNotNull(conn);
+	}
+
+	/**
+	 * Test method for {@link net.onrc.onos.graph.GraphDBConnection#getFramedGraph()}.
+	 * @throws Exception
+	 */
+	@Test
+	public final void testGetFramedGraph() throws Exception {
+		// setup expectations
+		expectDBConnectionAvailable();
+		
+		// start the test
+		replayAll();
+		GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
+		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+		
+		// verify the test
+		verifyAll();
+		assertNotNull(fg);
+		assertEquals(graph, fg.getBaseGraph());
+	}
+
+	/**
+	 * Test method for {@link net.onrc.onos.graph.GraphDBConnection#addEventListener(net.onrc.onos.graph.LocalGraphChangedListener)}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testAddEventListener() throws Exception {
+		// instantiate required objects
+		LocalGraphChangedListener listener = new LocalTopologyEventListener(null);
+
+		// setup expectations
+		expectDBConnectionAvailable();
+		eg.addListener(listener);
+		
+		// start the test
+		replayAll();
+		GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
+		conn.addEventListener(listener);
+		
+		// verify the test
+		verifyAll();
+	}
+
+	/**
+	 * Test method for {@link net.onrc.onos.graph.GraphDBConnection#isValid()}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testIsValid() throws Exception {
+		// setup expectations
+		expectDBConnectionAvailable();
+
+		// start the test
+		replayAll();
+		GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
+		Boolean result = conn.isValid();
+		
+		// verify the test
+		verifyAll();
+		assertTrue(result);
+	}
+
+	/**
+	 * Test method for {@link net.onrc.onos.graph.GraphDBConnection#commit()}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testCommit() throws Exception {
+		// setup expectations
+		expectDBConnectionAvailable();
+		graph.commit();
+		
+		// start the test
+		replayAll();
+		GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
+		conn.commit();
+
+		// verify the test
+		verifyAll();
+	}
+
+	/**
+	 * Test method for {@link net.onrc.onos.graph.GraphDBConnection#rollback()}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testRollback() throws Exception {
+		// setup expectations
+		expectDBConnectionAvailable();
+		graph.rollback();
+		
+		// start the test
+		replayAll();
+		GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
+		conn.rollback();
+
+		// verify the test
+		verifyAll();
+	}
+
+	/**
+	 * Test method for {@link net.onrc.onos.graph.GraphDBConnection#close()}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testClose() throws Exception {
+		// setup expectations
+		expectDBConnectionAvailable();
+		graph.commit();
+		
+		// start the test
+		replayAll();
+		GraphDBConnection conn = GraphDBConnection.getInstance("/path/to/dummy");
+		conn.close();
+
+		// verify the test
+		verifyAll();
+	}
+
+}
diff --git a/src/test/java/net/onrc/onos/util/GraphDBOperationTest.java b/src/test/java/net/onrc/onos/graph/GraphDBOperationTest.java
similarity index 97%
rename from src/test/java/net/onrc/onos/util/GraphDBOperationTest.java
rename to src/test/java/net/onrc/onos/graph/GraphDBOperationTest.java
index f85cc4f..e99ca81 100644
--- a/src/test/java/net/onrc/onos/util/GraphDBOperationTest.java
+++ b/src/test/java/net/onrc/onos/graph/GraphDBOperationTest.java
@@ -1,7 +1,7 @@
 /**
  * 
  */
-package net.onrc.onos.util;
+package net.onrc.onos.graph;
 
 import static org.junit.Assert.*;
 
@@ -95,11 +95,12 @@
 	public final void testNewSwitch() {
 		assertNull(op.searchSwitch("123"));
 
-		op.newSwitch("123");		
+		ISwitchObject sw = op.newSwitch("123");
+		assertEquals(sw.getDPID(), "123");
 		op.commit();
 
-		ISwitchObject sw = op.searchSwitch("123");
-		assertNotNull(op);
+		sw = op.searchSwitch("123");
+		assertNotNull(sw);
 		assertEquals("123", sw.getDPID());
 	}
 
@@ -232,7 +233,7 @@
 	public final void testNewPort() {
 		assertFalse(testdb.getVertices("type", "port").iterator().hasNext());
 		
-		IPortObject port = op.newPort((short) 10);
+		IPortObject port = op.newPort("1", (short) 10);
 		assertTrue(port.getNumber() == 10);
 		op.commit();
 		
@@ -250,12 +251,12 @@
 		IPortObject port;
 		
 		sw = op.newSwitch("1");
-		sw.addPort(op.newPort((short) 1));
-		sw.addPort(op.newPort((short) 2));
+		sw.addPort(op.newPort("1", (short) 1));
+		sw.addPort(op.newPort("1", (short) 2));
 		
 		sw = op.newSwitch("2");
-		sw.addPort(op.newPort((short) 1));
-		sw.addPort(op.newPort((short) 2));
+		sw.addPort(op.newPort("2", (short) 1));
+		sw.addPort(op.newPort("2", (short) 2));
 
 		op.commit();
 
@@ -300,8 +301,8 @@
 		IPortObject port;
 		
 		sw = op.newSwitch("1");
-		sw.addPort(op.newPort((short) 1));
-		sw.addPort(op.newPort((short) 2));
+		sw.addPort(op.newPort("1", (short) 1));
+		sw.addPort(op.newPort("1", (short) 2));
 		
 		op.commit();
 
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIDeviceObjectTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIDeviceObjectTest.java
new file mode 100644
index 0000000..3ea90ba
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIDeviceObjectTest.java
@@ -0,0 +1,206 @@
+package net.onrc.onos.ofcontroller.core;
+
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.slf4j.LoggerFactory;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+
+//Add Powermock preparation
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
+public class INetMapTopologyObjectsIDeviceObjectTest {
+	
+	//The test network is ./titan/schema/test-network.xml
+
+	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+
+	String conf;
+    private GraphDBConnection conn = null;
+    private GraphDBOperation ope = null;
+    private TitanGraph titanGraph = null;
+	
+	@Before
+	public void setUp() throws Exception {
+		conf = "/dummy/path/to/db";
+		
+		// Make mock cassandra DB
+		// Replace TitanFactory.open() to return mock DB
+		TestDatabaseManager.deleteTestDatabase();
+		titanGraph = TestDatabaseManager.getTestDatabase();
+		//TestDatabaseManager.populateTestData(titanGraph);
+		PowerMock.mockStatic(TitanFactory.class);
+		EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
+		PowerMock.replay(TitanFactory.class);
+		
+		conn = GraphDBConnection.getInstance(conf);
+		ope = new GraphDBOperation(conn);
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		titanGraph.shutdown();
+		TestDatabaseManager.deleteTestDatabase();
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for get and set MacAddress method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the mac address.
+	 * 2. Should get the mac address.
+	 */
+	@Test
+	public void testSetGetMacAddress() {
+		String macaddr = "00:00:00:00:00:00:0a:07";
+		IDeviceObject devObj = ope.newDevice();
+		devObj.setMACAddress(macaddr);
+		assertEquals(devObj.getMACAddress(), macaddr);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for get and set IPAddress method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the ip address.
+	 * 2. Should get the ip address.
+	 */
+	@Test
+	public void testSetGetIPAddress() {
+		String ipaddr = "192.168.0.1";
+		IDeviceObject devObj = ope.newDevice();
+		devObj.setIPAddress(ipaddr);
+		assertEquals(devObj.getIPAddress(), ipaddr);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for get attached port.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should get the attached ports.
+	 */
+	@Test
+	public void testGetAttachedPort() {
+		String dpid = "00:00:00:00:00:00:0a:07";
+		Short number = 1;	
+		Short number2 = 2;
+		IPortObject portObj = ope.newPort(dpid, number);
+		IPortObject portObj2 = ope.newPort(dpid, number2);
+		
+		String ipaddr = "192.168.0.1";
+		IDeviceObject devObj = ope.newDevice();
+		
+		portObj.setDevice(devObj);
+		portObj2.setDevice(devObj);
+		
+		HashMap<Short, IPortObject> portObjectList = new HashMap<Short, IPortObject>();
+		for(IPortObject port : devObj.getAttachedPorts())
+		{
+			portObjectList.put(port.getNumber(), port);
+		}
+		
+		assertTrue(portObjectList.containsValue(portObj));
+		assertTrue(portObjectList.containsValue(portObj2));
+		
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and remove host port method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set host port from the device.
+	 * 2. Should remove host port from the device.
+	 */
+	@Test
+	public void testSetRemoveHostPort() {
+		String dpid = "00:00:00:00:00:00:0a:07";
+		Short number = 1;	
+		Short number2 = 2;
+		IPortObject portObj = ope.newPort(dpid, number);
+		IPortObject portObj2 = ope.newPort(dpid, number2);
+		
+		String ipaddr = "192.168.0.1";
+		IDeviceObject devObj = ope.newDevice();
+		
+		devObj.setHostPort(portObj);
+		
+		HashMap<String, IDeviceObject> portObjectList = new HashMap<String, IDeviceObject>();
+		for(IDeviceObject dev : portObj.getDevices())
+		{
+			portObjectList.put(dev.getMACAddress(), dev);
+		}
+		assertTrue(portObjectList.containsValue(devObj));
+		
+		devObj.removeHostPort(portObj);
+		
+		HashMap<String, IDeviceObject> portObjectList2 = new HashMap<String, IDeviceObject>();
+		for(IDeviceObject dev : portObj.getDevices())
+		{
+			portObjectList2.put(dev.getMACAddress(), dev);
+		}
+		assertTrue(!portObjectList2.containsValue(devObj));
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for getSwitch method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should get the switch connected to the device.
+	 */
+	@Test
+	public void testGetSwitches() {
+		String dpid = "00:00:00:00:00:00:0a:07";
+		String dpid2 = "00:00:00:00:00:00:0a:08";
+		Short number = 1;	
+		Short number2 = 2;	
+		ISwitchObject swObj = ope.newSwitch(dpid);
+		ISwitchObject swObj2 = ope.newSwitch(dpid2);
+		IPortObject portObj = ope.newPort(dpid, number);
+		IPortObject portObj2 = ope.newPort(dpid2, number2);
+		swObj.addPort(portObj);
+		swObj2.addPort(portObj2);
+		IDeviceObject devObj = ope.newDevice();
+		portObj.setDevice(devObj);
+		portObj2.setDevice(devObj);
+		
+		HashMap<String, ISwitchObject> switchObjectList = new HashMap<String, ISwitchObject>();
+		for(ISwitchObject sw : devObj.getSwitch())
+		{
+			switchObjectList.put(sw.getDPID(), sw);
+		}
+		assertTrue(switchObjectList.containsValue(swObj));
+		assertTrue(switchObjectList.containsValue(swObj2));
+	}
+	
+	
+}
\ No newline at end of file
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowEntryTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowEntryTest.java
new file mode 100644
index 0000000..eba7447
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowEntryTest.java
@@ -0,0 +1,348 @@
+package net.onrc.onos.ofcontroller.core;
+
+import static org.junit.Assert.*;
+
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.slf4j.LoggerFactory;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+
+//Add Powermock preparation
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
+public class INetMapTopologyObjectsIFlowEntryTest {
+	
+	//The test network is ./titan/schema/test-network.xml
+
+	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+
+	String conf;
+    private GraphDBConnection conn = null;
+    private GraphDBOperation ope = null;
+    private TitanGraph titanGraph = null;
+	private IFlowEntry flowEntry = null;
+	
+	@Before
+	public void setUp() throws Exception {
+		conf = "/dummy/path/to/db";
+		
+		// Make mock cassandra DB
+		// Replace TitanFactory.open() to return mock DB
+		TestDatabaseManager.deleteTestDatabase();
+		titanGraph = TestDatabaseManager.getTestDatabase();
+		//TestDatabaseManager.populateTestData(titanGraph);
+		PowerMock.mockStatic(TitanFactory.class);
+		EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
+		PowerMock.replay(TitanFactory.class);
+		
+		conn = GraphDBConnection.getInstance(conf);
+		ope = new GraphDBOperation(conn);
+		
+		flowEntry = ope.newFlowEntry();
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		titanGraph.shutdown();
+		TestDatabaseManager.deleteTestDatabase();
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get FlowEntryId.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set FlowEntryId.
+	 * 2. Should get FlowEntryId.
+	 */
+	@Test
+	public void testSetGetFlowEntryId() {
+		String flowEntryId = "xx";
+		flowEntry.setFlowEntryId(flowEntryId);
+		assertEquals(flowEntry.getFlowEntryId(), flowEntryId);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get SwitchDpid.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set SwitchDpid.
+	 * 2. Should get SwitchDpid.
+	 */
+	@Test
+	public void testSetGetSwitchDpid() {
+		String switchDpid = "00:00:00:00:00:11";
+		flowEntry.setSwitchDpid(switchDpid);
+		assertEquals(flowEntry.getSwitchDpid(), switchDpid);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get UserState.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set UserState.
+	 * 2. Should get UserState.
+	 */
+	@Test
+	public void testSetGetUserState() {
+		String userStete = "good";
+		flowEntry.setUserState(userStete);
+		assertEquals(flowEntry.getUserState(), userStete);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get SwitchState.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set SwitchState.
+	 * 2. Should get SwitchState.
+	 */
+	@Test
+	public void testSetGetSwitchState() {
+		String switchStete = "ACTIVE";
+		flowEntry.setSwitchState(switchStete);
+		assertEquals(flowEntry.getSwitchState(), switchStete);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get ErrorStateType.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set ErrorStateType.
+	 * 2. Should get ErrorStateType.
+	 */
+	@Test
+	public void testSetGetErrorStateType() {
+		String errorSteteType = "error";
+		flowEntry.setErrorStateType(errorSteteType);
+		assertEquals(flowEntry.getErrorStateType(), errorSteteType);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get ErrorStateCode.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set ErrorStateCode.
+	 * 2. Should get ErrorStateCode.
+	 */
+	@Test
+	public void testSetGetErrorStateCode() {
+		String errorSteteCode = "error";
+		flowEntry.setErrorStateCode(errorSteteCode);
+		assertEquals(flowEntry.getErrorStateCode(), errorSteteCode);
+	}	
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get MatchInPort.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set MatchInPort.
+	 * 2. Should get MatchInPort.
+	 */
+	@Test
+	public void testSetGetMatchInPort() {
+		Short inPort = 1;
+		flowEntry.setMatchInPort(inPort);
+		assertEquals(flowEntry.getMatchInPort(), inPort);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get MatchEthernetFrameType.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set MatchEthernetFrameType.
+	 * 2. Should get MatchEthernetFrameType.
+	 */
+	@Test
+	public void testSetGetMatchEthernetFrameType() {
+		Short matchEthernetFrameType = 1;
+		flowEntry.setMatchEthernetFrameType(matchEthernetFrameType);
+		assertEquals(flowEntry.getMatchEthernetFrameType(), matchEthernetFrameType);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get MatchSrcMac.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set MatchSrcMac.
+	 * 2. Should get MatchSrcMac.
+	 */
+	@Test
+	public void testSetGetMatchSrcMac() {
+		String matchSrcMac = "00:00:00:00:00:11";
+		flowEntry.setMatchSrcMac(matchSrcMac);
+		assertEquals(flowEntry.getMatchSrcMac(), matchSrcMac);
+	}	
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get MatchDstMac.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set MatchDstMac.
+	 * 2. Should get MatchDstMac.
+	 */
+	@Test
+	public void testSetGetMatchDstMac() {
+		String matchDstMac = "00:00:00:00:00:11";
+		flowEntry.setMatchDstMac(matchDstMac);
+		assertEquals(flowEntry.getMatchDstMac(), matchDstMac);
+	}	
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get SrcIPv4Net.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set SrcIPv4Net.
+	 * 2. Should get SrcIPv4Net.
+	 */
+	@Test
+	public void testSetGetMatchSrcIPv4Net() {
+		String srcIPv4Net = "192.168.0.1";
+		flowEntry.setMatchSrcIPv4Net(srcIPv4Net);
+		assertEquals(flowEntry.getMatchSrcIPv4Net(), srcIPv4Net);
+	}	
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get MatchDstIPv4Net.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set MatchDstIPv4Net.
+	 * 2. Should get MatchDstIPv4Net.
+	 */
+	@Test
+	public void testSetGetMatchDstIPv4Net() {
+		String dstIPv4Net = "192.168.0.1";
+		flowEntry.setMatchDstIPv4Net(dstIPv4Net);
+		assertEquals(flowEntry.getMatchDstIPv4Net(), dstIPv4Net);
+	}	
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get ActionOutput.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set ActionOutput.
+	 * 2. Should get ActionOutput.
+	 */
+	@Test
+	public void testSetGetActionOutput() {
+		Short actionOutput = 1;
+		flowEntry.setActionOutput(actionOutput);
+		assertEquals(flowEntry.getActionOutput(), actionOutput);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get FlowPath.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set FlowPath.
+	 * 2. Should get FlowPath.
+	 */
+	@Test
+	public void testSetGetFlowPath() {
+		IFlowPath fp = ope.newFlowPath();
+		String flowId = "xx";
+		fp.setFlowId(flowId);
+		flowEntry.setFlow(fp);
+		IFlowPath fp2 = flowEntry.getFlow();
+		assertEquals(fp2.getFlowId(), flowId);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get Switch.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set Switch.
+	 * 2. Should get Switch.
+	 */
+	@Test
+	public void testSetGetSwitch() {
+		String dpid = "00:00:00:00:00:22";
+		ISwitchObject sw1 = ope.newSwitch(dpid);
+		flowEntry.setSwitch(sw1);
+		ISwitchObject sw2 = flowEntry.getSwitch();
+		assertEquals(sw2, sw1);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get InPort.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set InPort.
+	 * 2. Should get InPort.
+	 */
+	@Test
+	public void testSetGetInPort() {
+		String dpid = "00:00:00:00:00:22";
+		Short portNum = 4;
+		IPortObject port1 = ope.newPort(dpid, portNum);
+		flowEntry.setInPort(port1);
+		IPortObject port2 = flowEntry.getInPort();
+		assertEquals(port2, port1);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get OutPort.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set OutPort.
+	 * 2. Should get OutPort.
+	 */
+	@Test
+	public void testSetGetOutPort() {
+		String dpid = "00:00:00:00:00:22";
+		Short portNum = 4;
+		IPortObject port1 = ope.newPort(dpid, portNum);
+		flowEntry.setOutPort(port1);
+		IPortObject port2 = flowEntry.getOutPort();
+		assertEquals(port2, port1);
+	}
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowPathTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowPathTest.java
new file mode 100644
index 0000000..9765af8
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowPathTest.java
@@ -0,0 +1,383 @@
+package net.onrc.onos.ofcontroller.core;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.slf4j.LoggerFactory;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+
+//Add Powermock preparation
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
+public class INetMapTopologyObjectsIFlowPathTest {
+	
+	//The test network is ./titan/schema/test-network.xml
+
+	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+
+	String conf;
+    private GraphDBConnection conn = null;
+    private GraphDBOperation ope = null;
+    private TitanGraph titanGraph = null;
+	private IFlowPath flowPath = null;
+	private IFlowEntry flowEntry = null;
+	
+	@Before
+	public void setUp() throws Exception {
+		conf = "/dummy/path/to/db";
+		
+		// Make mock cassandra DB
+		// Replace TitanFactory.open() to return mock DB
+		TestDatabaseManager.deleteTestDatabase();
+		titanGraph = TestDatabaseManager.getTestDatabase();
+		//TestDatabaseManager.populateTestData(titanGraph);
+		PowerMock.mockStatic(TitanFactory.class);
+		EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
+		PowerMock.replay(TitanFactory.class);
+		
+		conn = GraphDBConnection.getInstance(conf);
+		ope = new GraphDBOperation(conn);
+		
+		flowPath = ope.newFlowPath();
+		flowEntry = ope.newFlowEntry();
+		flowEntry.setState("zz");
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		titanGraph.shutdown();
+		TestDatabaseManager.deleteTestDatabase();
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for get and set FlowId method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the flow id.
+	 * 2. Should get the flow id.
+	 */
+	@Test
+	public void testSetGetFlowId() {
+		String flowId = "xx";
+		flowPath.setFlowId(flowId);
+		assertEquals(flowPath.getFlowId(), flowId);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for get and set InstallerId method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the installer id.
+	 * 2. Should get the installer id.
+	 */
+	@Test
+	public void testSetGetInstallerId() {
+		String flowId = "xx";
+		String installerId = "yy";
+		flowPath.setFlowId(flowId);
+		flowPath.setInstallerId(installerId);
+		assertEquals(flowPath.getInstallerId(), installerId);
+	}
+
+	/**
+	 * Desc:
+	 *  Test method for get and set SourceSwitch method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the source switch.
+	 * 2. Should get the source switch.
+	 */
+	@Test
+	public void testSetGetSourceSwitch() {
+		String flowId = "xx";
+		String sourceSwitch = "aa";
+		flowPath.setFlowId(flowId);
+		flowPath.setSrcSwitch(sourceSwitch);
+		assertEquals(flowPath.getSrcSwitch(), sourceSwitch);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for get and set SourcePort method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the source port.
+	 * 2. Should get the source port.
+	 */
+	@Test
+	public void testSetGetSourcePort() {
+		String flowId = "xx";
+		Short sourcePort = 1;
+		flowPath.setFlowId(flowId);
+		flowPath.setSrcPort(sourcePort);
+		assertEquals(flowPath.getSrcPort(), sourcePort);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for get and set DestSwitch method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the dest switch.
+	 * 2. Should get the dest switch.
+	 */
+	@Test
+	public void testSetGetDestSwitch() {
+		String flowId = "xx";
+		String destSwitch = "bb";
+		flowPath.setFlowId(flowId);
+		flowPath.setDstSwitch(destSwitch);
+		assertEquals(flowPath.getDstSwitch(), destSwitch);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for get and set DestPort method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the source dest port.
+	 * 2. Should get the source dest port.
+	 */
+	@Test
+	public void testSetGetDstPort() {
+		String flowId = "xx";
+		Short dstPort = 2;
+		flowPath.setFlowId(flowId);
+		flowPath.setDstPort(dstPort);
+		assertEquals(flowPath.getDstPort(), dstPort);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for get and set DataPathSummary method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the data path summary.
+	 * 2. Should get the data path summary.
+	 */
+	@Test
+	public void testSetGetDataPathSummary() {
+		String flowId = "xx";
+		String dataPathSummary = "yy";
+		flowPath.setFlowId(flowId);
+		flowPath.setInstallerId(dataPathSummary);
+		assertEquals(flowPath.getInstallerId(), dataPathSummary);
+	}
+	
+	public boolean testIFlowEntry(IFlowPath fp, IFlowEntry fe)
+	{
+		ArrayList<IFlowEntry> flowEntryList = new ArrayList<IFlowEntry>();
+		for(IFlowEntry inFlowEntry : fp.getFlowEntries())
+		{
+			flowEntryList.add(inFlowEntry);
+		}
+		return flowEntryList.contains(fe);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for addFlowEntry and getFlorEntries method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should add the FlowEntry.
+	 * 2. Should get the FlowEntries. It is tested in the testIFlowEntry method.
+	 */
+	@Test
+	public void testAddFlowEntryAndGetFlowEntries() {
+		String flowId = "xx";
+		flowPath.setFlowId(flowId);
+		flowPath.addFlowEntry(flowEntry);
+		IFlowEntry flowEntry2 = ope.newFlowEntry();
+		flowPath.addFlowEntry(flowEntry2);
+		assertTrue(testIFlowEntry(flowPath, flowEntry));
+		assertTrue(testIFlowEntry(flowPath, flowEntry2));
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for remove FlowEntry.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should remove FlowEntry.
+	 */
+	@Test
+	public void testRemoveFlowEntry() {
+		String flowId = "xx";
+		flowPath.setFlowId(flowId);
+		flowPath.addFlowEntry(flowEntry);
+		flowPath.removeFlowEntry(flowEntry);
+		assertTrue(!testIFlowEntry(flowPath, flowEntry));
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get MatchEthernetFrameType
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set MatchEthernetFrameType.
+	 * 2. Should get MatchEthernetFrameType.
+	 */
+	@Test
+	public void testSetGetMatchEthernetFrameType() {
+		String flowId = "xx";
+		Short matchEthernetFrameTypeShort = 1;
+		flowPath.setFlowId(flowId);
+		flowPath.setMatchEthernetFrameType(matchEthernetFrameTypeShort);
+		assertEquals(flowPath.getMatchEthernetFrameType(), matchEthernetFrameTypeShort);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get MatchSrcMac
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set MatchSrcMac.
+	 * 2. Should get MatchSrcMac.
+	 */
+	@Test
+	public void testSetGetMatchSrcMac() {
+		String flowId = "xx";
+		String matchSrcMac = "00:00:00:00:00:11";
+		flowPath.setFlowId(flowId);
+		flowPath.setMatchSrcMac(matchSrcMac);
+		assertEquals(flowPath.getMatchSrcMac(), matchSrcMac);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get MatchDstMac.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set MatchDstMac.
+	 * 2. Should get MatchDstMac.
+	 */
+	@Test
+	public void testSetGetMatchDstMac() {
+		String flowId = "xx";
+		String matchDstMac = "00:00:00:00:00:11";
+		flowPath.setFlowId(flowId);
+		flowPath.setMatchDstMac(matchDstMac);
+		assertEquals(flowPath.getMatchDstMac(), matchDstMac);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get SrcIPv4Net.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set SrcIPv4Net.
+	 * 2. Should get SrcIPv4Net.
+	 */
+	@Test
+	public void testSetGetMatchSrcIPv4Net() {
+		String flowId = "xx";
+		String ip = "192.168.0.1";
+		flowPath.setFlowId(flowId);
+		flowPath.setMatchSrcIPv4Net(ip);
+		assertEquals(flowPath.getMatchSrcIPv4Net(), ip);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get DstIPv4Net.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set DstIPv4Net.
+	 * 2. Should get DstIPv4Net.
+	 */
+	@Test
+	public void testSetGetMatchDstIPv4Net() {
+		String flowId = "xx";
+		String ip = "192.168.0.1";
+		flowPath.setFlowId(flowId);
+		flowPath.setMatchDstIPv4Net(ip);
+		assertEquals(flowPath.getMatchDstIPv4Net(), ip);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get UserState.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set UserState.
+	 * 2. Should get UserState.
+	 */
+	@Test
+	public void testSetGetUserState() {
+		String flowId = "xx";
+		String userStatus = "Good";
+		flowPath.setFlowId(flowId);
+		flowPath.setUserState(userStatus);
+		assertEquals(flowPath.getUserState(), userStatus);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for get Switches.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should get switches.
+	 */
+	@Test
+	public void testGetSwitches() {
+		String flowId = "xx";
+		String dpid = "1";
+		flowPath.setFlowId(flowId);
+		ISwitchObject sw = ope.newSwitch(dpid);
+		flowEntry.setSwitch(sw);
+		flowPath.addFlowEntry(flowEntry);
+		
+		HashMap<String, ISwitchObject> swList = new HashMap<String, ISwitchObject>();
+		for(ISwitchObject insw : flowPath.getSwitches()){
+			swList.put(sw.getDPID(), insw);
+		}
+		
+		assertTrue(swList.containsKey(dpid));
+	}
+	
+	//TODO Dont know how to set the state property.
+	@Test
+	public void testGetState() {
+		String status = null;
+		assertEquals(flowPath.getState(), status);
+	}
+	
+	
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIPortObjectTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIPortObjectTest.java
new file mode 100644
index 0000000..2ddab3d
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIPortObjectTest.java
@@ -0,0 +1,359 @@
+package net.onrc.onos.ofcontroller.core;
+
+import static org.junit.Assert.*;
+
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
+import net.onrc.onos.ofcontroller.flowmanager.FlowManager;
+import net.onrc.onos.ofcontroller.util.FlowId;
+import net.onrc.onos.ofcontroller.util.FlowPath;
+
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openflow.protocol.OFPhysicalPort.OFPortState;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.slf4j.LoggerFactory;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+//Add Powermock preparation
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
+public class INetMapTopologyObjectsIPortObjectTest {
+	
+	//The test network is ./titan/schema/test-network.xml
+
+	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+
+	String conf;
+    private GraphDBConnection conn = null;
+    private GraphDBOperation ope = null;
+    private TitanGraph titanGraph = null;
+    
+    private ISwitchObject swObj;
+    private IPortObject portObj;
+    private IPortObject portObj2;
+    String dpid;
+    Short number;
+    Short number2;
+    
+    private ISwitchObject swObjParty;
+    private IPortObject portObjParty1;
+    private IPortObject portObjParty2;  
+    String dpidParty;
+    Short numberParty1;
+    Short numberParty2;
+    
+    
+	@Before
+	public void setUp() throws Exception {
+		conf = "/dummy/path/to/db";
+		
+		// Make mock cassandra DB
+		// Replace TitanFactory.open() to return mock DB
+		TestDatabaseManager.deleteTestDatabase();
+		titanGraph = TestDatabaseManager.getTestDatabase();
+		//TestDatabaseManager.populateTestData(titanGraph);
+		PowerMock.mockStatic(TitanFactory.class);
+		EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
+		PowerMock.replay(TitanFactory.class);
+		
+		conn = GraphDBConnection.getInstance(conf);
+		ope = new GraphDBOperation(conn);
+		
+		dpid = "00:00:00:00:00:00:0a:07";
+		number = 1;	
+		number2 = 2;
+		swObj = ope.newSwitch(dpid);
+		portObj = ope.newPort(dpid, number);
+		portObj2 = ope.newPort(dpid, number2);
+
+		swObj.addPort(portObj);	
+		swObj.addPort(portObj2);
+		
+		dpidParty = "00:00:00:00:00:00:0a:08";
+		numberParty1 = 1;
+		numberParty2 = 2;
+		swObjParty = ope.newSwitch(dpidParty);
+		portObjParty1 = ope.newPort(dpidParty, numberParty1);
+		portObjParty2 = ope.newPort(dpidParty, numberParty2);
+		swObjParty.addPort(portObjParty1);	
+		swObjParty.addPort(portObjParty2);
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		titanGraph.shutdown();
+		TestDatabaseManager.deleteTestDatabase();
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get port number property.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the port number.
+	 * 2. Should get the port number.
+	 */
+	@Test
+	public void testSetGetNumber() {
+		assertEquals(portObj.getNumber(), number);
+		Short testedNumber = 4;
+		portObj.setNumber(testedNumber);
+		assertEquals(portObj.getNumber(), testedNumber);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get port id property.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the port id.
+	 * 2. Should get the port id.
+	 */
+	@Test
+	public void testSetGetPortId() {
+		String portId = "test1";
+		portObj.setPortId(portId);
+		assertEquals(portObj.getPortId(), portId);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get port desc property.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the port desc.
+	 * 2. Should get the port desc.
+	 */
+	@Test
+	public void testSetGetDesc() {
+		String testedDesc = "port 4 at ATL Switch";
+		portObj.setDesc(testedDesc);
+		assertEquals(portObj.getDesc(), testedDesc);
+	}
+	
+	
+	/**
+	 * Desc:
+	 *  Test method for set and get port status property.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the port status.
+	 * 2. Should get the port status.
+	 */
+	@Test
+	public void testSetGetPortState() {
+		Integer portState = OFPortState.OFPPS_STP_FORWARD.getValue();
+		portObj.setPortState(portState);
+		assertEquals(portObj.getPortState(), portState);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for get switch object.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should get the switch status.
+	 */
+	@Test
+	public void testGetSwitch() {
+		ISwitchObject sw = portObj.getSwitch();
+		assertEquals(sw.getDPID(), dpid);
+	}
+	
+	private boolean checkIDeviceObject(IPortObject IportObj, String mac)
+	{
+		HashMap<String, IDeviceObject> devList = new HashMap<String, IDeviceObject>();
+		for(IDeviceObject IdevObj : IportObj.getDevices())
+		{
+			devList.put(IdevObj.getMACAddress(), IdevObj);
+		}
+		return devList.containsKey(mac);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set and remove device object.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the device object.
+	 * 2. SHould remove the device object.
+	 */
+	@Test
+	public void testSetAndRemoveDevice() {
+		IDeviceObject devObj = ope.newDevice();
+		String devMac = "00:00:00:00:00:11";
+		devObj.setMACAddress(devMac);
+		
+		boolean b = checkIDeviceObject(portObj, devMac);
+		assertTrue(!b);
+		portObj.setDevice(devObj);
+		boolean b2 = checkIDeviceObject(portObj, devMac);
+		assertTrue(b2);
+		
+		portObj.removeDevice(devObj);
+		boolean b3 = checkIDeviceObject(portObj, devMac);
+		assertTrue(!b3);
+		
+	}	
+	
+	/**
+	 * Desc:
+	 *  Test method for get devices object.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should get the device objects.
+	 */
+	@Test
+	public void testGetDevices() {
+		IDeviceObject devObj = ope.newDevice();
+		String devMac = "58:55:ca:c4:1b:a0";
+		devObj.setMACAddress(devMac);
+		
+		portObj.setDevice(devObj);
+		boolean b = checkIDeviceObject(portObj, devMac);
+		assertTrue(b);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for set, get and remove linked port.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the linked objects.
+	 * 2. Should get the linked objects.
+	 * 3. SHould remove the liked objects.
+	 */
+	@Test
+	public void testSetGetRemoveLinkedPorts() {
+		String dpidParty = "00:00:00:00:00:00:00:08";
+		ISwitchObject swParty = ope.newSwitch(dpidParty);
+		Short poShort = 1;
+		IPortObject poParty = ope.newPort(dpidParty, poShort);
+		swParty.addPort(poParty);
+		
+		portObj.setLinkPort(poParty);
+		
+		ArrayList<IPortObject> iPortList = new ArrayList<IPortObject>();
+		for(IPortObject port : portObj.getLinkedPorts()) {
+			iPortList.add(port);
+		}	
+		assertTrue(iPortList.contains(poParty));	
+		
+		portObj.removeLink(poParty);
+		
+		ArrayList<IPortObject> iPortList2 = new ArrayList<IPortObject>();
+		for(IPortObject port : portObj.getLinkedPorts()) {
+			iPortList2.add(port);
+		}	
+		
+		assertTrue(!iPortList2.contains(poParty));
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for get inbound flowEntry
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should get the inbound flowEntry.
+	 */
+	@Test
+	public void testGetInFlowEntries() {
+
+		portObj.setLinkPort(portObj2);
+		
+		IFlowPath flowPathObj = ope.newFlowPath();
+		
+		String flowEId = "1";
+		IFlowEntry flowEntryObj = ope.newFlowEntry();		
+		flowEntryObj.setFlowEntryId(flowEId);
+		flowEntryObj.setInPort(portObj);
+		flowEntryObj.setOutPort(portObj2);
+		flowEntryObj.setSwitch(swObj);
+		flowEntryObj.setFlow(flowPathObj);
+		
+		String flowEId2 = "2";
+		IFlowEntry flowEntryObj2 = ope.newFlowEntry();		
+		flowEntryObj2.setFlowEntryId(flowEId2);
+		flowEntryObj2.setInPort(portObjParty1);
+		flowEntryObj2.setOutPort(portObjParty2);
+		flowEntryObj.setSwitch(swObjParty);
+		flowEntryObj2.setFlow(flowPathObj);
+		
+		HashMap<String, IFlowEntry> flowEntryList = new HashMap<String, IFlowEntry>();
+		for(IFlowEntry flowEnt : portObj.getInFlowEntries())
+		{				
+			flowEntryList.put(flowEnt.getFlowEntryId(), flowEnt);
+		}
+		
+		assertTrue(flowEntryList.containsValue(flowEntryObj));
+		
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for get outbound flowEntry
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should get the outbound flowEntry.
+	 */
+	@Test
+	public void testGetOutFlowEntries() {
+		
+		portObj.setLinkPort(portObj2);
+		
+		IFlowPath flowPathObj = ope.newFlowPath();
+		
+		String flowEId = "1";
+		IFlowEntry flowEntryObj = ope.newFlowEntry();		
+		flowEntryObj.setFlowEntryId(flowEId);
+		flowEntryObj.setInPort(portObj);
+		flowEntryObj.setOutPort(portObj2);
+		flowEntryObj.setSwitch(swObj);
+		flowEntryObj.setFlow(flowPathObj);
+		
+		String flowEId2 = "2";
+		IFlowEntry flowEntryObj2 = ope.newFlowEntry();		
+		flowEntryObj2.setFlowEntryId(flowEId2);
+		flowEntryObj2.setInPort(portObjParty1);
+		flowEntryObj2.setOutPort(portObjParty2);
+		flowEntryObj.setSwitch(swObjParty);
+		flowEntryObj2.setFlow(flowPathObj);
+		
+		HashMap<String, IFlowEntry> flowEntryList = new HashMap<String, IFlowEntry>();
+		for(IFlowEntry flowEnt : portObj2.getOutFlowEntries())
+		{				
+			flowEntryList.put(flowEnt.getFlowEntryId(), flowEnt);
+		}
+		
+		assertTrue(flowEntryList.containsValue(flowEntryObj));
+		
+	}
+
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsISwitchObjectTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsISwitchObjectTest.java
new file mode 100644
index 0000000..c4dca4b
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsISwitchObjectTest.java
@@ -0,0 +1,285 @@
+package net.onrc.onos.ofcontroller.core;
+
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.slf4j.LoggerFactory;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+
+//Add Powermock preparation
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
+public class INetMapTopologyObjectsISwitchObjectTest {
+	
+	//The test network is ./titan/schema/test-network.xml
+
+	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+
+	String conf;
+    private GraphDBConnection conn = null;
+    private GraphDBOperation ope = null;
+    private TitanGraph titanGraph = null;
+	
+	@Before
+	public void setUp() throws Exception {
+		conf = "/dummy/path/to/db";
+		
+		// Make mock cassandra DB
+		// Replace TitanFactory.open() to return mock DB
+		TestDatabaseManager.deleteTestDatabase();
+		titanGraph = TestDatabaseManager.getTestDatabase();
+		//TestDatabaseManager.populateTestData(titanGraph);
+		PowerMock.mockStatic(TitanFactory.class);
+		EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
+		PowerMock.replay(TitanFactory.class);
+		
+		conn = GraphDBConnection.getInstance(conf);
+		ope = new GraphDBOperation(conn);
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		titanGraph.shutdown();
+		TestDatabaseManager.deleteTestDatabase();
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for get and set state method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the status of the switch.
+	 * 2. Should get the status of the switch.
+	 */
+	@Test
+	public void testSetGetState() {
+		String dpid = "00:00:00:00:00:00:0a:07";
+		String state = "ACTIVE";
+		ISwitchObject swObj = ope.newSwitch(dpid);
+		swObj.setState(state);
+		assertEquals(swObj.getState(), state);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for get and set Type method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the Type of the switch.
+	 * 2. Should get the Type of the switch.
+	 */
+	@Test
+	public void testSetGetType() {
+		String dpid = "00:00:00:00:00:00:0a:07";
+		String type = "Switch";
+		ISwitchObject swObj = ope.newSwitch(dpid);
+		swObj.setType("Switch");
+		assertEquals(swObj.getType(), type);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for getDPID method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should get the dpid of the switch.
+	 */
+	@Test
+	public void testGetDPID() {
+		String dpid = "00:00:00:00:00:00:0a:07";
+		ISwitchObject swObj = ope.newSwitch(dpid);
+		
+		assertEquals(swObj.getDPID(), dpid);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for setDPID method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should set the dpid of the switch.
+	 */
+	@Test
+	public void testSetDPID() {
+		String dpid = "00:00:00:00:00:00:0a:07";
+		String dpid2 = "00:00:00:00:00:00:0a:08";
+		ISwitchObject obj = ope.newSwitch(dpid);
+		assertEquals(obj.getDPID(), dpid);
+		
+		obj.setDPID(dpid2);
+		assertEquals(obj.getDPID(), dpid2);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for getPorts method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should get all of ports taken by the switch.
+	 */
+	@Test
+	public void testGetPorts() {
+		String dpid = "00:00:00:00:00:00:0a:07";
+		Short portNumber = 1;
+		int testSwitchPortNumber = 1;
+		ISwitchObject swObj = ope.newSwitch(dpid);
+		IPortObject portObj = ope.newPort(dpid, portNumber);
+
+		swObj.addPort(portObj);
+		int i = 0;
+		for(IPortObject port : swObj.getPorts()){
+			i++;
+		}
+		assertEquals(testSwitchPortNumber, 1);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for add and getPort method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should add the port.
+	 * 1. Should get the port.
+	 */
+	@Test
+	public void testGetPort() {
+		String dpid = "00:00:00:00:00:00:0a:07";
+		Short portNumber = 1;
+		ISwitchObject swObj = ope.newSwitch(dpid);
+		IPortObject portObj = ope.newPort(dpid, portNumber);
+		
+		swObj.addPort(portObj);
+		IPortObject portObj2 = swObj.getPort(portNumber);
+		assertEquals(portObj, portObj2);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for add and removePort method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should add a port to the switch.
+	 * 1. Should remove a port from the switch.
+	 */
+	@Test
+	public void testAddRemovePorts() {
+		String dpid = "00:00:00:00:00:00:0a:07";
+		Short portNum = 1;
+		ISwitchObject swObj = ope.newSwitch(dpid);
+		IPortObject portObj = ope.newPort(dpid, portNum);
+		swObj.addPort(portObj);
+		
+		IPortObject portObj2 = swObj.getPort(portNum);
+		assertEquals(portObj2, portObj);
+		swObj.removePort(portObj);
+		assertNull(swObj.getPort(portNum));
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for getDevices method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should get all devices attached to the switch.
+	 */
+	@Test
+	public void testGetDevices() {
+		String dpid = "00:00:00:00:00:00:0a:07";
+		Short portNum = 1;
+		String devMac = "00:00:00:00:00:11";
+		int numOfDev = 1;
+		
+		ISwitchObject swObj = ope.newSwitch(dpid);
+		IPortObject portObj = ope.newPort(dpid, portNum);
+		IDeviceObject devObj = ope.newDevice();
+		devObj.setMACAddress(devMac);
+		swObj.addPort(portObj);
+		portObj.setDevice(devObj);
+		
+		int i = 0;
+		for(IDeviceObject dev : swObj.getDevices()){
+			i++;
+		}
+		assertEquals(i, numOfDev);
+	}
+	
+	/**
+	 * Desc:
+	 *  Test method for getFlowEntries method.
+	 * Condition:
+	 *  N/A
+	 * Expect:
+	 * 1. Should get all flowEntries attached to the switch.
+	 */
+	@Test
+	public void testGetFlowEntries() {
+		String dpid = "00:00:00:00:00:00:0a:07";
+		Short number = 1;	
+		Short number2 = 2;
+		Short number3 = 3;
+		ISwitchObject swObj = ope.newSwitch(dpid);
+		IPortObject portObj = ope.newPort(dpid, number);
+		IPortObject portObj2 = ope.newPort(dpid, number2);
+		IPortObject portObj3 = ope.newPort(dpid, number3);
+
+		swObj.addPort(portObj);	
+		swObj.addPort(portObj2);
+		swObj.addPort(portObj3);
+		
+		IFlowPath flowPathObj = ope.newFlowPath();
+		
+		String flowEId = "1";
+		IFlowEntry flowEntryObj = ope.newFlowEntry();		
+		flowEntryObj.setFlowEntryId(flowEId);
+		flowEntryObj.setInPort(portObj);
+		flowEntryObj.setOutPort(portObj2);
+		flowEntryObj.setSwitch(swObj);
+		flowEntryObj.setFlow(flowPathObj);
+		
+		String flowEId2 = "2";
+		IFlowEntry flowEntryObj2 = ope.newFlowEntry();		
+		flowEntryObj2.setFlowEntryId(flowEId2);
+		flowEntryObj2.setInPort(portObj);
+		flowEntryObj2.setOutPort(portObj3);
+		flowEntryObj2.setSwitch(swObj);
+		flowEntryObj2.setFlow(flowPathObj);
+		
+		HashMap<String, IFlowEntry> flowEntryList = new HashMap<String, IFlowEntry>();
+		for(IFlowEntry flowEnt : swObj.getFlowEntries())
+		{				
+			flowEntryList.put(flowEnt.getFlowEntryId(), flowEnt);
+		}
+		
+		assertTrue(flowEntryList.containsValue(flowEntryObj));
+		assertTrue(flowEntryList.containsValue(flowEntryObj2));
+	}
+
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
index 5c42452..9b1c4d6 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
@@ -6,7 +6,6 @@
 
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -33,6 +32,11 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+/**
+ * Unit test for {@link LinkStorageImpl}.
+ * @author Naoki Shiota
+ *
+ */
 @RunWith(PowerMockRunner.class)
 @PrepareForTest({LinkStorageImpl.class, GraphDBConnection.class, GraphDBOperation.class})
 public class LinkStorageImplTest {
@@ -100,12 +104,14 @@
 	 */
 	@Before
 	public void setUp() throws Exception{
+		// Create mock GraphDBConnection (replace Singleton object to mock one)
 		PowerMock.mockStatic(GraphDBConnection.class);
 		PowerMock.suppress(PowerMock.constructor(GraphDBConnection.class));
-		conn = PowerMock.createNiceMock(GraphDBConnection.class);
+		conn = PowerMock.createMock(GraphDBConnection.class);
 		EasyMock.expect(GraphDBConnection.getInstance((String)EasyMock.anyObject())).andReturn(conn).anyTimes();
 		PowerMock.replay(GraphDBConnection.class);
 		
+		// Create mock GraphDBOperation
 		ope = createMockGraphDBOperation();
 		PowerMock.expectNew(GraphDBOperation.class, new Class<?>[] {GraphDBConnection.class}, EasyMock.anyObject(GraphDBConnection.class)).andReturn(ope).anyTimes();
 		PowerMock.replay(GraphDBOperation.class);
@@ -121,18 +127,16 @@
 	
 	/**
 	 * Closing code called after each tests.
-	 * Discard test graph data.
 	 * @throws Exception
 	 */
 	@After
 	public void tearDown() throws Exception {
-		// finish code
 		linkStorage.close();
 	}
 	
 	// TODO: remove @Ignore after UPDATE method is implemented
 	/**
-	 * Test if update() can correctly updates LinkInfo for a Link.
+	 * Test if {@link LinkStorageImpl#update(Link, LinkInfo, DM_OPERATION)} can correctly updates LinkInfo for a Link.
 	 */
 	@Ignore @Test
 	public void testUpdate_UpdateSingleLink() {
@@ -147,7 +151,7 @@
 	}
 	
 	/**
-	 * Test if update() can correctly creates a Link.
+	 * Test if {@link LinkStorageImpl#update(Link, DM_OPERATION)} can correctly creates a Link.
 	 */
 	@Test
 	public void testUpdate_CreateSingleLink() {
@@ -157,18 +161,10 @@
 		//Use the link storage API to add the link
 		linkStorage.update(linkToCreate, ILinkStorage.DM_OPERATION.CREATE);
 		doTestLinkExist(linkToVerify);
-
-		// Avoiding duplication is out of scope. DBOperation is responsible for this.
-//		// Add same link
-//		Link linkToCreateTwice = createFeasibleLink();
-//		linkStorage.update(linkToCreateTwice, ILinkStorage.DM_OPERATION.CREATE);
-//		
-//		// this occurs assertion failure if there are two links in titanGraph
-//		doTestLinkIsInGraph(linkToVerify);
 	}
 
 	/**
-	 * Test if update() can correctly inserts a Link.
+	 * Test if {@link LinkStorageImpl#update(Link, DM_OPERATION)}can correctly inserts a Link.
 	 */
 	@Test
 	public void testUpdate_InsertSingleLink(){
@@ -181,7 +177,7 @@
 	}
 	
 	/**
-	 * Test if update() can correctly deletes a Link.
+	 * Test if {@link LinkStorageImpl#update(Link, DM_OPERATION)} can correctly deletes a Link.
 	 */
 	@Test
 	public void testUpdate_DeleteSingleLink(){
@@ -194,7 +190,7 @@
 	}
 
 	/**
-	 * Test if update() can correctly creates multiple Links.
+	 * Test if {@link LinkStorageImpl#update(List, DM_OPERATION)} can correctly creates multiple Links.
 	 */
 	@Test
 	public void testUpdate_CreateLinks(){
@@ -206,34 +202,10 @@
 		for(Link l : linksToVerify) {
 			doTestLinkExist(l);
 		}
-	
-		// Out of scope: DBOperation is responsible for avoiding duplication.
-//		// Test creation of existing links
-//		linksToCreate = createFeasibleLinks();
-//		linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
-//		for(Link l : linksToVerify) {
-//			doTestLinkIsInGraph(l);
-//		}
-	}
-	
-	/**
-	 * Test if update() can handle mixture of normal/abnormal input for creation of Links.
-	 * Deprecated: DBOperation is responsible.
-	 */
-	@Ignore @Test
-	public void testUpdate_CreateLinks_Mixuture(){
-		List<Link> linksToCreate = new ArrayList<Link>();
-		linksToCreate.add(createFeasibleLink());
-		linksToCreate.add(createExistingLink());
-		
-		// Test creation of mixture of new/existing links
-		linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
-		doTestLinkExist(createFeasibleLink());
-		doTestLinkExist(createExistingLink());
 	}
 
 	/**
-	 * Test if update() can correctly inserts multiple Links.
+	 * Test if {@link LinkStorageImpl#update(List, DM_OPERATION)} can correctly inserts multiple Links.
 	 */
 	@Test
 	public void testUpdate_InsertLinks(){
@@ -248,22 +220,7 @@
 	}
 	
 	/**
-	 * Test if update() can handle mixture of normal/abnormal input for creation of Links.
-	 */
-	@Ignore @Test
-	public void testUpdate_InsertLinks_Mixuture(){
-		List<Link> linksToInsert = new ArrayList<Link>();
-		linksToInsert.add(createFeasibleLink());
-		linksToInsert.add(createExistingLink());
-		
-		// Test insertion of mixture of new/existing links
-		linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
-		doTestLinkExist(createFeasibleLink());
-		doTestLinkExist(createExistingLink());
-	}
-
-	/**
-	 * Test if update() can correctly deletes multiple Links.
+	 * Test if  {@link LinkStorageImpl#update(List, DM_OPERATION)} can correctly deletes multiple Links.
 	 */
 	@Test
 	public void testUpdate_DeleteLinks(){
@@ -277,24 +234,9 @@
 		}
 	}
 	
-	/**
-	 * Test if update() can handle mixture of normal/abnormal input for deletion of Links.
-	 */
-	@Ignore @Test
-	public void testUpdate_DeleteLinks_Mixuture(){
-		List<Link> linksToDelete = new ArrayList<Link>();
-		linksToDelete.add(createFeasibleLink());
-		linksToDelete.add(createExistingLink());
-		
-		// Test deletion of mixture of new/existing links
-		linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
-		doTestLinkNotExist(createFeasibleLink());
-		doTestLinkNotExist(createExistingLink());
-	}
-	
 	// TODO: remove @Ignore after UPDATE method is implemented
 	/**
-	 * Test if updateLink() can correctly updates LinkInfo for a Link.
+	 * Test if {@link LinkStorageImpl#updateLink(Link, LinkInfo, DM_OPERATION)} can correctly updates LinkInfo for a Link.
 	 */
 	@Ignore @Test
 	public void testUpdateLink_Update() {
@@ -309,7 +251,7 @@
 	}
 	
 	/**
-	 * Test if updateLink() can correctly creates a Link.
+	 * Test if {@link LinkStorageImpl#updateLink(Link, LinkInfo, DM_OPERATION)} can correctly creates a Link.
 	 */
 	@Test
 	public void testUpdateLink_Create() {
@@ -322,7 +264,7 @@
 	}
 	
 	/**
-	 * Test if updateLink() can correctly inserts a Link.
+	 * Test if {@link LinkStorageImpl#updateLink(Link, LinkInfo, DM_OPERATION)} can correctly inserts a Link.
 	 */
 	@Test
 	public void testUpdateLink_Insert() {
@@ -337,7 +279,7 @@
 	
 	// TODO: Check if addOrUpdateLink() should accept DELETE operation. If not, remove this test.
 	/**
-	 * Test if updateLink() can correctly deletes a Link.
+	 * Test if {@link LinkStorageImpl#updateLink(Link, LinkInfo, DM_OPERATION)} can correctly deletes a Link.
 	 */
 	@Ignore @Test
 	public void testUpdateLink_Delete() {
@@ -357,7 +299,7 @@
 	}
 	
 	/**
-	 * Test if getLinks() can correctly return Links connected to specific DPID and port.
+	 * Test if {@link LinkStorageImpl#getLinks(Long, short)} can correctly return Links connected to specific DPID and port.
 	 */
 	@Test
 	public void testGetLinks_ByDpidPort(){
@@ -383,7 +325,7 @@
 	}
 	
 	/**
-	 * Test if getLinks() can correctly return Links connected to specific MAC address.
+	 * Test if {@link LinkStorageImpl#getLinks(String)} can correctly return Links connected to specific MAC address.
 	 */
 	@Test
 	public void testGetLinks_ByString() {
@@ -398,7 +340,7 @@
 	}
 	
 	/**
-	 * Test if deleteLink() can correctly delete a Link.
+	 * Test if {@link LinkStorageImpl#deleteLink(Link)} can correctly delete a Link.
 	 */
 	@Test
 	public void testDeleteLink() {
@@ -411,7 +353,7 @@
 	}
 	
 	/**
-	 * Test if deleteLinks() can correctly delete Links.
+	 * Test if {@link LinkStorageImpl#deleteLinks(List)} can correctly delete Links.
 	 */
 	@Test
 	public void testDeleteLinks(){
@@ -423,24 +365,9 @@
 			doTestLinkNotExist(l);
 		}
 	}
-	
-	/**
-	 * Test if deleteLinks() can handle mixture of normal/abnormal input.
-	 */
-	@Ignore @Test
-	public void testDeleteLinks_Mixture(){
-		List<Link> linksToDelete = new ArrayList<Link>();
-		linksToDelete.add(createFeasibleLink());
-		linksToDelete.add(createExistingLink());
-		
-		// Test deletion of mixture of new/existing links
-		linkStorage.deleteLinks(linksToDelete);
-		doTestLinkNotExist(createFeasibleLink());
-		doTestLinkNotExist(createExistingLink());
-	}
 
 	/**
-	 * Test if getActiveLinks() can correctly return active Links.
+	 * Test if {@link LinkStorageImpl#getActiveLinks()} can correctly return active Links.
 	 */
 	@Test
 	public void testGetActiveLinks() {
@@ -454,7 +381,7 @@
 	}
 	
 	/**
-	 * Test if deleteLinksOnPort() can delete Links.
+	 * Test if {@link LinkStorageImpl#deleteLinksOnPort(Long, short)} can delete Links.
 	 */
 	@Test
 	public void testDeleteLinksOnPort() {
@@ -493,11 +420,12 @@
 	 * Test if titanGraph has specific Link with specific LinkInfo
 	 * @param link 
 	 */
+	// TODO: Fix me
 	private void doTestLinkHasStateOf(Link link, LinkInfo info) {
 	}
 	
 	/**
-	 * Class defines a function called back when IPortObject#removeLink is called.
+	 * Class defines a function called back when {@link IPortObject#removeLink(IPortObject)} is called.
 	 * @author Naoki Shiota
 	 *
 	 */
@@ -521,9 +449,8 @@
 	}
 	
 	/**
-	 * Class defines a function called back when IPortObject#setLinkPort is called.
+	 * Class defines a function called back when {@link IPortObject#setLinkPort(IPortObject)} is called.
 	 * @author Naoki Shiota
-	 *
 	 */
 	private class SetLinkPortCallback implements IAnswer<Object> {
 		private long dpid;
@@ -546,7 +473,7 @@
 	}
 	
 	/**
-	 * Class defines a function called back when IPortObject#getSwitch is called.
+	 * Class defines a function called back when {@link IPortObject#getSwitch()} is called.
 	 * @author Naoki Shiota
 	 *
 	 */
@@ -565,7 +492,7 @@
 	}
 	
 	/**
-	 * Class defines a function called back when IPortObject#getLinkedPorts is called.
+	 * Class defines a function called back when {@link IPortObject#getLinkedPorts()} is called.
 	 * @author Naoki Shiota
 	 *
 	 */
@@ -594,7 +521,7 @@
 	}
 
 	/**
-	 * Class defines a function called back when ISwitchObject#getPorts is called.
+	 * Class defines a function called back when {@link LinkStorageImplTest} is called.
 	 * @author Naoki Shiota
 	 *
 	 */
@@ -619,7 +546,7 @@
 
 	// ------------------------Creation of Mock-----------------------------
 	/**
-	 * Create a mock GraphDBOperation which hooks port-related methods.
+	 * Create a mock {@link GraphDBOperation} which hooks port-related methods.
 	 * @return EasyMock-wrapped GraphDBOperation object.
 	 */
 	@SuppressWarnings("serial")
@@ -692,8 +619,8 @@
 	}
 	
 	/**
-	 * Create a mock IPortObject using given DPID and port number.
-	 * IPortObject can't store DPID, so DPID is stored to mockToPortInfoMap for later use.
+	 * Create a mock {@link IPortObject} using given DPID and port number.
+	 * {@link IPortObject} can't store DPID, so DPID is stored to mockToPortInfoMap for later use.
 	 * Duplication is not checked.
 	 * @param dpid DPID of a port
 	 * @param number Port Number
@@ -725,7 +652,7 @@
 	}
 	
 	/**
-	 * Create a mock ISwitchObject using given DPID number.
+	 * Create a mock {@link ISwitchObject} using given DPID number.
 	 * Duplication is not checked.
 	 * @param dpid DPID of a switch
 	 * @return EasyMock-wrapped ISwitchObject
@@ -811,7 +738,7 @@
 	}
 	
 	/**
-	 * Returns new Link object of an existing link
+	 * Returns new {@link Link} object of an existing link
 	 * @return new Link object
 	 */
 	private Link createExistingLink() {
@@ -819,7 +746,7 @@
 	}
 	
 	/**
-	 * Returns new Link object of a not-existing but feasible link
+	 * Returns new {@link Link} object of a not-existing but feasible link
 	 * @return new Link object
 	 */
 	private Link createFeasibleLink() {
@@ -833,7 +760,7 @@
 	}
 
 	/**
-	 * Returns list of Link objects which all has information of existing link in titanGraph
+	 * Returns list of existing {@link Link} objects
 	 * @return ArrayList of new Link objects
 	 */
 	private List<Link> createExistingLinks() {
@@ -844,7 +771,7 @@
 	}
 	
 	/**
-	 * Returns list of Link objects which all has information of not-existing but feasible link
+	 * Returns list of {@link Link} objects that are all not-existing but feasible
 	 * @return ArrayList of new Link objects
 	 */
 	private List<Link> createFeasibleLinks() {
@@ -855,7 +782,7 @@
 	}
 	
 	/**
-	 * Returns new LinkInfo object with convenient values.
+	 * Returns new {@link LinkInfo} object with convenient values.
 	 * @return LinkInfo object
 	 */
 	private LinkInfo createFeasibleLinkInfo(long time) {
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java
index d2a6712..4956136 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java
@@ -80,7 +80,6 @@
 	 * Expect:
 	 * 	Call SwitchStorageImpl.addSwitch func with proper properties.
 	 */
-	@Ignore 
 	@Test
 	public void testAddSwitch() {
 		String dpid = "00:00:00:00:00:00:0a:07";
@@ -144,7 +143,6 @@
 	 * Expect:
 	 * 	Write the status as info log.
 	 */
-	//@Ignore 
 	@Test
 	public void testAddSwitchAbnormal() {
 		String dpid = "00:00:00:00:00:00:0a:07";
@@ -152,6 +150,7 @@
 		//Expectation of mock operation.
 		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
 		expect(mockOpe.newSwitch(dpid)).andReturn(null);
+		mockOpe.rollback();
 		mockOpe.close();
 		replay(mockOpe);
 		
@@ -163,7 +162,7 @@
 	 * Desc:
 	 *  Test method for addSwitch method.
 	 * Condition:
-	 *  Tthrow runtimeException. 
+	 *  Throw runtimeException. 
 	 * Expect:
 	 * 	The rollback method is called.
 	 */
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestDatabaseManager.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestDatabaseManager.java
index b4cfc31..5b0a5b1 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestDatabaseManager.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestDatabaseManager.java
@@ -56,11 +56,22 @@
         
         //Change the type of all port numbers to short in the database
         Iterator<Vertex> it = titanGraph.getVertices("type", "port").iterator();
+
         while (it.hasNext()){
         	Vertex port = it.next();
-        	Integer portNum = (Integer) port.getProperty("number");
-        	port.setProperty("number", portNum.shortValue());
+
+        	if(port.getProperty("number") instanceof Short)
+        	{
+        		Short portNum = (Short) port.getProperty("number");
+        		port.setProperty("number", portNum.shortValue());
+        	}
+        	else{
+        		Integer portNum = (Integer) port.getProperty("number");	
+        		port.setProperty("number", portNum.shortValue());
+        	}
+
         }
+        
         titanGraph.stopTransaction(Conclusion.SUCCESS);
 	}
 	
@@ -73,4 +84,4 @@
 		}
 	}
 	
-}
\ No newline at end of file
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java b/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
new file mode 100644
index 0000000..06e828d
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
@@ -0,0 +1,1201 @@
+package net.onrc.onos.ofcontroller.flowmanager;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.cmpEq;
+import static org.powermock.api.easymock.PowerMock.*;
+
+import java.util.*;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.floodlightcontroller.restserver.IRestApiService;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoRouteService;
+import net.onrc.onos.ofcontroller.flowmanager.web.FlowWebRoutable;
+import net.onrc.onos.ofcontroller.util.*;
+
+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.protocol.OFFlowMod;
+import org.openflow.protocol.OFType;
+import org.openflow.protocol.factory.BasicFactory;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+/**
+ * @author Toshio Koide
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({FlowManager.class, GraphDBOperation.class, System.class, Executors.class})
+public class FlowManagerTest {
+	private static FloodlightModuleContext context;
+	private static IFloodlightProviderService floodlightProvider;
+	private static ITopoRouteService topoRouteService;
+	private static IRestApiService restApi;
+	private static GraphDBOperation op;
+	
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	/**
+	 * @throws java.lang.Exception
+	 */
+	@After
+	public void tearDown() throws Exception {
+	}
+	
+	/**
+	 * @throws java.lang.Exception
+	 */
+	private void expectInitWithContext() throws Exception {
+		// create mock objects
+		context = createMock(FloodlightModuleContext.class);
+		floodlightProvider = createMock(IFloodlightProviderService.class);
+		topoRouteService = createMock(ITopoRouteService.class);
+		restApi = createMock(IRestApiService.class);
+		op = createMock(GraphDBOperation.class);
+
+		// setup expectations
+		expect(context.getServiceImpl(IFloodlightProviderService.class)).andReturn(floodlightProvider);
+		expect(context.getServiceImpl(ITopoRouteService.class)).andReturn(topoRouteService);
+		expect(context.getServiceImpl(IRestApiService.class)).andReturn(restApi);
+		expectNew(GraphDBOperation.class, new Class<?>[] {String.class}, EasyMock.isA(String.class)).andReturn(op);
+	}
+	
+	private IFlowPath createIFlowPathMock(long flowId, String installerID,
+			long srcDpid, int srcPort, long dstDpid, int dstPort) {
+		IFlowPath iFlowPath = createNiceMock(IFlowPath.class);
+		expect(iFlowPath.getFlowId()).andReturn(new FlowId(flowId).toString()).anyTimes();
+		expect(iFlowPath.getInstallerId()).andReturn(installerID).anyTimes();
+		expect(iFlowPath.getSrcSwitch()).andReturn(new Dpid(srcDpid).toString()).anyTimes();
+		expect(iFlowPath.getSrcPort()).andReturn(new Short((short)srcPort)).anyTimes();
+		expect(iFlowPath.getDstSwitch()).andReturn(new Dpid(dstDpid).toString()).anyTimes();
+		expect(iFlowPath.getDstPort()).andReturn(new Short((short)dstPort)).anyTimes();
+		return iFlowPath;
+	}
+	
+	private FlowPath createTestFlowPath(long flowId, String installerId,
+			final long srcDpid, final int srcPort,
+			final long dstDpid, final int dstPort			
+			) {
+		FlowPath flowPath = new FlowPath();
+		flowPath.setFlowId(new FlowId(flowId));
+		flowPath.setInstallerId(new CallerId(installerId));
+		flowPath.setDataPath(new DataPath() {{
+			setSrcPort(new SwitchPort(new Dpid(srcDpid), new Port((short)srcPort)));
+			setDstPort(new SwitchPort(new Dpid(dstDpid), new Port((short)dstPort)));
+		}});
+		flowPath.setFlowEntryMatch(new FlowEntryMatch());
+		return flowPath;
+	}
+	
+	private ArrayList<FlowPath> createTestFlowPaths() {
+		FlowPath flowPath1 = createTestFlowPath(1, "foo caller id", 1, 1, 2, 2); 
+		FlowPath flowPath2 = createTestFlowPath(2, "caller id", 1, 1, 2, 2); 
+		FlowPath flowPath3 = createTestFlowPath(3, "caller id", 1, 5, 2, 2); 
+
+		ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
+		flowPaths.add(flowPath1);
+		flowPaths.add(flowPath2);
+		flowPaths.add(flowPath3);
+		
+		return flowPaths;
+	}
+	
+
+	// IFlowService methods
+
+
+	/**
+	 * Test method for {@link FlowManager#addFlow(FlowPath, FlowId, String)}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testAddFlowFailGraphCreatesNoFlow() throws Exception {
+		// instantiate required objects
+		FlowId flowId = new FlowId(123);
+		FlowPath flowPath = new FlowPath();
+		flowPath.setFlowId(flowId);
+		FlowManager fm = new FlowManager();
+		
+		// setup expectations
+		expectInitWithContext();
+		expect(op.searchFlowPath(flowId)).andReturn(null);
+		expect(op.newFlowPath()).andReturn(null);
+		op.rollback();
+
+		// start the test
+		replayAll();
+
+		fm.init(context);
+		Boolean result = fm.addFlow(flowPath, flowId, "");
+
+		// verify the test
+		verifyAll();
+		assertFalse(result);
+	}
+
+	/**
+	 * Test method for {@link FlowManager#addFlow(FlowPath, FlowId, String)}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testAddFlowSuccessNormally() throws Exception {
+		final String addFlowEntry = "addFlowEntry";
+		// create mock objects
+		IFlowPath createdFlowPath = createNiceMock(IFlowPath.class);
+		IFlowEntry createdFlowEntry1 = createNiceMock(IFlowEntry.class);
+		IFlowEntry createdFlowEntry2 = createNiceMock(IFlowEntry.class);
+		FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, addFlowEntry);
+
+		// instantiate required objects
+		final FlowEntry flowEntry1 = new FlowEntry();
+		final FlowEntry flowEntry2 = new FlowEntry();
+		ArrayList<FlowEntry> flowEntries = new ArrayList<FlowEntry>();
+		flowEntries.add(flowEntry1);
+		flowEntries.add(flowEntry2);
+		
+		DataPath dataPath = new DataPath();
+		dataPath.setSrcPort(new SwitchPort(new Dpid(0x1234), new Port((short)1)));
+		dataPath.setDstPort(new SwitchPort(new Dpid(0x5678), new Port((short)2)));
+		dataPath.setFlowEntries(flowEntries);
+
+		FlowEntryMatch match = new FlowEntryMatch();
+		
+		FlowPath flowPath = new FlowPath();
+		flowPath.setFlowId(new FlowId(0x100));
+		flowPath.setInstallerId(new CallerId("installer id"));
+		flowPath.setDataPath(dataPath);
+		flowPath.setFlowEntryMatch(match);
+		
+		// setup expectations
+		expectInitWithContext();
+		expect(op.searchFlowPath(cmpEq(new FlowId(0x100)))).andReturn(null);
+		expect(op.newFlowPath()).andReturn(createdFlowPath);
+		createdFlowPath.setFlowId("0x100");
+		createdFlowPath.setType("flow");
+		createdFlowPath.setInstallerId("installer id");
+		createdFlowPath.setSrcSwitch("00:00:00:00:00:00:12:34");
+		createdFlowPath.setSrcPort(new Short((short)1));
+		createdFlowPath.setDstSwitch("00:00:00:00:00:00:56:78");
+		createdFlowPath.setDstPort(new Short((short)2));
+		createdFlowPath.setDataPathSummary("data path summary");
+		createdFlowPath.setUserState("FE_USER_ADD");
+		
+		expectPrivate(fm, addFlowEntry, createdFlowPath, flowEntry1)
+			.andReturn(createdFlowEntry1);
+		expectPrivate(fm, addFlowEntry, createdFlowPath, flowEntry2)
+			.andReturn(createdFlowEntry2);
+		
+		op.commit();
+		
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		Boolean result = fm.addFlow(flowPath, new FlowId(0x100), "data path summary");
+
+		// verify the test
+		verifyAll();
+		assertTrue(result);
+	}
+	
+	/**
+	 * Test method for {@link FlowManager#deleteAllFlows()}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testDeleteAllFlowsSuccessNormally() throws Exception {
+		// create mock objects
+		IFlowPath flowPath1 = createNiceMock(IFlowPath.class);
+		IFlowPath flowPath2 = createNiceMock(IFlowPath.class);
+		
+		// instantiate required objects
+		ArrayList<IFlowPath> flowPaths = new ArrayList<IFlowPath>();
+		flowPaths.add(flowPath1);
+		flowPaths.add(flowPath2);
+		FlowManager fm = new FlowManager();
+		
+		// setup expectations
+		expectInitWithContext();
+		expect(op.getAllFlowPaths()).andReturn(flowPaths);
+
+		expect(flowPath1.getFlowId()).andReturn("1").anyTimes();
+		expect(op.searchFlowPath(cmpEq(new FlowId(1)))).andReturn(flowPath1);
+		expect(flowPath1.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>());
+		op.removeFlowPath(flowPath1);
+		
+		expect(flowPath2.getFlowId()).andReturn("2").anyTimes();
+		expect(op.searchFlowPath(cmpEq(new FlowId(2)))).andReturn(flowPath2);
+		expect(flowPath2.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>());
+		op.removeFlowPath(flowPath2);
+
+		op.commit();
+		expectLastCall().anyTimes();
+
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		Boolean result = fm.deleteAllFlows();
+
+		// verify the test
+		verifyAll();
+		assertTrue(result);
+	}
+	
+	/**
+	 * Test method for {@link FlowManager#deleteFlow(FlowId)}.
+	 * @throws Exception
+	 */
+	@Test
+	public final void testDeleteFlowSuccessEmptyFlowPath() throws Exception {
+		// instantiate required objects
+		FlowManager fm = new FlowManager();
+		
+		// create mock objects
+		IFlowPath flowObj = createNiceMock(IFlowPath.class);
+
+		// setup expectations
+		expectInitWithContext();
+		expect(op.searchFlowPath(cmpEq(new FlowId(1)))).andReturn(flowObj);
+		expect(flowObj.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>());
+		op.removeFlowPath(flowObj);
+		op.commit();
+		expectLastCall().anyTimes();
+		
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		Boolean result = fm.deleteFlow(new FlowId(1));
+		
+		// verify the test
+		verifyAll();
+		assertTrue(result);
+	}
+	
+	/**
+	 * Test method for {@link FlowManager#clearAllFlows()}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testClearAllFlowsSuccessNormally() throws Exception {
+		// create mock objects
+		IFlowPath flowPath1 = createNiceMock(IFlowPath.class);
+		IFlowPath flowPath2 = createNiceMock(IFlowPath.class);
+		IFlowPath flowPath3 = createNiceMock(IFlowPath.class);
+		FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, "clearFlow");
+		
+		// instantiate required objects
+		ArrayList<IFlowPath> flowPaths = new ArrayList<IFlowPath>();
+		flowPaths.add(flowPath1);
+		flowPaths.add(flowPath2);
+		flowPaths.add(null);
+		flowPaths.add(flowPath3);
+		
+		// setup expectations
+		expectInitWithContext();
+		expect(op.getAllFlowPaths()).andReturn(flowPaths);
+		expect(flowPath1.getFlowId()).andReturn(new FlowId(1).toString());
+		expect(flowPath2.getFlowId()).andReturn(null);
+		expect(flowPath3.getFlowId()).andReturn(new FlowId(3).toString());
+		expect(fm.clearFlow(cmpEq(new FlowId(1)))).andReturn(true);
+		expect(fm.clearFlow(cmpEq(new FlowId(3)))).andReturn(true);
+		
+		// start the test
+		replayAll();
+
+		fm.init(context);
+		Boolean result = fm.clearAllFlows();
+		
+		//verify the test
+		verifyAll();
+		assertTrue(result);
+	}
+	
+	/**
+	 * Test method for {@link FlowManager#getFlow()}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testGetFlowSuccessNormally() throws Exception {
+		// instantiate required objects
+		FlowManager fm = new FlowManager();
+		IFlowPath iFlowPath = createIFlowPathMock(1, "caller id", 1, 1, 2, 2); 
+
+		// setup expectations
+		expectInitWithContext();
+		expect(op.searchFlowPath(cmpEq(new FlowId(1)))).andReturn(iFlowPath);
+		expect(iFlowPath.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>()).anyTimes();
+		op.commit();
+		
+		// start the test
+		replayAll();
+
+		fm.init(context);
+		String result = fm.getFlow(new FlowId(1)).installerId().toString();
+		
+		//verify the test
+		verifyAll();
+		assertEquals("caller id", result);
+	}
+	
+	/**
+	 * Test method for {@link FlowManager#getAllFlows(CallerId, DataPathEndpoints)}.
+	 * @throws Exception 
+	 */ 
+	@Test
+	public final void testGetAllFlowsWithCallerIdAndDataPathEndpointsSuccessNormally() throws Exception {
+		final String getAllFlows = "getAllFlows";
+		// create mock objects
+		FlowManager fm = createPartialMock(FlowManager.class, getAllFlows,
+				new Class<?>[]{}, new Object[]{});
+
+		// instantiate required objects
+		DataPathEndpoints dataPathEndpoints = new DataPathEndpoints(
+				new SwitchPort(new Dpid(1), new Port((short)1)),
+				new SwitchPort(new Dpid(2), new Port((short)2)));
+
+		ArrayList<FlowPath> obtainedAllFlows = createTestFlowPaths();
+			
+		//setup expectations
+		expectInitWithContext();
+		expectPrivate(fm, getAllFlows).andReturn(obtainedAllFlows);
+		
+		//start the test
+		replayAll();
+		
+		fm.init(context);
+		ArrayList<FlowPath> flows = fm.getAllFlows(new CallerId("caller id"), dataPathEndpoints);
+
+		// verify the test
+		verifyAll();
+		assertEquals(1, flows.size());
+		assertEquals(obtainedAllFlows.get(1), flows.get(0));
+	}
+	
+	/**
+	 * Test method for {@link FlowManager#getAllFlows(DataPathEndpoints)}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testGetAllFlowsWithDataPathEndpointsSuccessNormally() throws Exception {
+		final String getAllFlows = "getAllFlows";
+		// create mock objects
+		FlowManager fm = createPartialMock(FlowManager.class, getAllFlows,
+				new Class<?>[]{}, new Object[]{});
+
+		// instantiate required objects
+		DataPathEndpoints dataPathEndpoints = new DataPathEndpoints(
+				new SwitchPort(new Dpid(1), new Port((short)1)),
+				new SwitchPort(new Dpid(2), new Port((short)2)));
+
+		ArrayList<FlowPath> obtainedAllFlows = createTestFlowPaths();
+			
+		//setup expectations
+		expectInitWithContext();
+		expectPrivate(fm, getAllFlows).andReturn(obtainedAllFlows);
+		
+		//start the test
+		replayAll();
+		
+		fm.init(context);
+		ArrayList<FlowPath> flows = fm.getAllFlows(dataPathEndpoints);
+
+		// verify the test
+		verifyAll();
+		assertEquals(2, flows.size());
+		assertEquals(obtainedAllFlows.get(0), flows.get(0));
+		assertEquals(obtainedAllFlows.get(1), flows.get(1));
+		// TODO: ignore the order of flows in the list
+	}
+	
+	/**
+	 * Test method for {@link FlowManager#getAllFlowsSummary(FlowId, int)}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testGetAllFlowsSummarySuccessNormally() throws Exception {
+		final String getAllFlowsWithoutFlowEntries = "getAllFlowsWithoutFlowEntries";
+		// create mock objects
+		FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, getAllFlowsWithoutFlowEntries);
+		IFlowPath flowPath1 = createIFlowPathMock(1, "", 1, 2, 3, 4);
+		IFlowPath flowPath2 = createIFlowPathMock(5, "", 2, 3, 4, 5);
+		IFlowPath flowPath3 = createIFlowPathMock(10, "", 3, 4, 5, 6);
+
+		// instantiate required objects
+		ArrayList<IFlowPath> flows = new ArrayList<IFlowPath>();
+		flows.add(flowPath3);
+		flows.add(flowPath1);
+		flows.add(flowPath2);
+		
+		// setup expectations
+		expectInitWithContext();
+		expectPrivate(fm, getAllFlowsWithoutFlowEntries).andReturn(flows);
+
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		ArrayList<IFlowPath> returnedFlows = fm.getAllFlowsSummary(null, 0);
+		
+		// verify the test
+		verifyAll();
+		assertEquals(3, returnedFlows.size());
+		assertEquals(1, new FlowId(returnedFlows.get(0).getFlowId()).value());
+		assertEquals(5, new FlowId(returnedFlows.get(1).getFlowId()).value());
+		assertEquals(10, new FlowId(returnedFlows.get(2).getFlowId()).value());
+	}
+
+	/**
+	 * Test method for {@link FlowManager#getAllFlows()}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testGetAllFlowsSuccessNormally() throws Exception {
+		// create mock objects
+		IFlowPath iFlowPath1 = createIFlowPathMock(1, "caller id", 1, 1, 2, 2); 
+		IFlowPath iFlowPath2 = createIFlowPathMock(2, "caller id", 2, 5, 3, 5);
+		
+		// instantiate required objects
+		ArrayList<IFlowPath> flowPaths = new ArrayList<IFlowPath>();
+		flowPaths.add(iFlowPath1);
+		flowPaths.add(iFlowPath2);
+		FlowManager fm = new FlowManager();
+
+		// setup expectations
+		expectInitWithContext();
+		expect(op.getAllFlowPaths()).andReturn(flowPaths);
+		expect(iFlowPath1.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>()).anyTimes();
+		expect(iFlowPath2.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>()).anyTimes();
+		op.commit();
+		
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		ArrayList<FlowPath> flows = fm.getAllFlows();
+
+		// verify the test
+		verifyAll();
+		assertEquals(2, flows.size());
+		assertEquals(new SwitchPort(new Dpid(1), new Port((short)1)).toString(),
+				flows.get(0).dataPath().srcPort().toString());
+		assertEquals(new SwitchPort(new Dpid(2), new Port((short)5)).toString(),
+				flows.get(1).dataPath().srcPort().toString());
+		// TODO: more asserts
+		// TODO: ignore seq. of the list
+	}
+	
+	/**
+	 * Test method for {@link FlowManager#addAndMaintainShortestPathFlow(FlowPath)}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testAddAndMaintainShortestPathFlowSuccessNormally() throws Exception {
+		final String addFlow = "addFlow";
+
+		// create mock objects
+		FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, addFlow);
+
+		// instantiate required objects
+		DataPath dataPath = new DataPath();
+		dataPath.setSrcPort(new SwitchPort(new Dpid(1), new Port((short)3)));
+		dataPath.setDstPort(new SwitchPort(new Dpid(2), new Port((short)4)));
+		FlowEntryMatch match = new FlowEntryMatch();
+		FlowPath paramFlow = new FlowPath();
+		paramFlow.setFlowId(new FlowId(100));
+		paramFlow.setInstallerId(new CallerId("installer id"));
+		paramFlow.setDataPath(dataPath);
+		paramFlow.setFlowEntryMatch(match);
+		
+		// setup expectations
+		expectInitWithContext();
+		expectPrivate(fm, addFlow,
+				EasyMock.anyObject(FlowPath.class),
+				EasyMock.anyObject(FlowId.class),
+				EasyMock.anyObject(String.class)
+				).andAnswer(new IAnswer<Object>() {
+					public Object answer() throws Exception {
+						FlowPath flowPath = (FlowPath)EasyMock.getCurrentArguments()[0];
+						assertEquals(flowPath.flowId().value(), 100);
+						assertEquals(flowPath.installerId().toString(), "installer id");
+						assertEquals(flowPath.dataPath().srcPort().toString(),
+								new SwitchPort(new Dpid(1), new Port((short)3)).toString());
+
+						String dataPathSummary = (String)EasyMock.getCurrentArguments()[2];
+						assertEquals(dataPathSummary, "X");
+						
+						return true;
+					}
+				});
+		
+		// start the test
+		replayAll();
+
+		fm.init(context);
+		FlowPath resultFlow = fm.addAndMaintainShortestPathFlow(paramFlow);
+				
+		// verify the test
+		verifyAll();
+		assertEquals(paramFlow.flowId().value(), resultFlow.flowId().value());
+		assertEquals(paramFlow.installerId().toString(), resultFlow.installerId().toString());
+		assertEquals(paramFlow.dataPath().toString(), resultFlow.dataPath().toString());
+		assertEquals(paramFlow.flowEntryMatch().toString(), resultFlow.flowEntryMatch().toString());
+	}
+		
+	/**
+	 * Test method for {@link FlowManager#measurementStorePathFlow(FlowPath)}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testMeasurementStorePathFlowSuccessNormally() throws Exception {
+		// instantiate required objects
+		FlowPath paramFlow = createTestFlowPath(100, "installer id", 1, 3, 2, 4);
+		Map<Long, Object> shortestPathMap = new HashMap<Long, Object>();
+		FlowManager fm = new FlowManager();
+
+		// setup expectations
+		expectInitWithContext();
+		expect((Map<Long,Object>)topoRouteService.prepareShortestPathTopo()
+				).andReturn(shortestPathMap);
+		expect(topoRouteService.getTopoShortestPath(
+				shortestPathMap,
+				paramFlow.dataPath().srcPort(),
+				paramFlow.dataPath().dstPort())).andReturn(null);
+		
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		FlowPath resultFlowPath = fm.measurementStorePathFlow(paramFlow);
+		
+		// verify the test
+		verifyAll();
+		assertEquals(paramFlow.flowId().value(), resultFlowPath.flowId().value());
+		assertEquals(paramFlow.installerId().toString(), resultFlowPath.installerId().toString());
+		assertEquals(paramFlow.dataPath().toString(), resultFlowPath.dataPath().toString());
+		assertEquals(paramFlow.flowEntryMatch().toString(), resultFlowPath.flowEntryMatch().toString());
+	}
+	
+	/**
+	 * Test method for {@link FlowManager#measurementInstallPaths(Integer)}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testMeasurementInstallPathsSuccessNormally() throws Exception {
+		final String addFlow = "addFlow";
+
+		// create mock objects
+		FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, addFlow);
+
+		// instantiate required objects
+		FlowPath flow1 = createTestFlowPath(1, "installer id", 1, 2, 3, 4);
+		FlowPath flow2 = createTestFlowPath(2, "installer id", 2, 3, 4, 5);
+		FlowPath flow3 = createTestFlowPath(3, "installer id", 3, 4, 5, 6);
+		Map<Long, Object> shortestPathMap = new HashMap<Long, Object>();
+
+		// setup expectations
+		expectInitWithContext();
+		expect((Map<Long,Object>)topoRouteService.prepareShortestPathTopo()
+				).andReturn(shortestPathMap);
+
+		expect(topoRouteService.getTopoShortestPath(
+				shortestPathMap,
+				flow1.dataPath().srcPort(),
+				flow1.dataPath().dstPort())).andReturn(null);
+		
+		expect(topoRouteService.getTopoShortestPath(
+				shortestPathMap,
+				flow2.dataPath().srcPort(),
+				flow2.dataPath().dstPort())).andReturn(null);
+
+		expect(topoRouteService.getTopoShortestPath(
+				shortestPathMap,
+				flow3.dataPath().srcPort(),
+				flow3.dataPath().dstPort())).andReturn(null);
+
+		expectPrivate(fm, addFlow,
+				EasyMock.cmpEq(flow1),
+				EasyMock.anyObject(FlowId.class),
+				EasyMock.anyObject(String.class)).andReturn(true);
+
+		expectPrivate(fm, addFlow,
+				EasyMock.cmpEq(flow2),
+				EasyMock.anyObject(FlowId.class),
+				EasyMock.anyObject(String.class)).andReturn(true);
+
+		expectPrivate(fm, addFlow,
+				EasyMock.cmpEq(flow3),
+				EasyMock.anyObject(FlowId.class),
+				EasyMock.anyObject(String.class)).andReturn(true);
+
+		// start the test
+		replayAll();
+
+		fm.init(context);
+		fm.measurementStorePathFlow(flow1);
+		fm.measurementStorePathFlow(flow2);
+		fm.measurementStorePathFlow(flow3);
+		Boolean result = fm.measurementInstallPaths(3);
+		
+		// verify the test
+		verifyAll();
+		assertTrue(result);
+	}
+	
+	/**
+	 * Test method for {@link FlowManager#measurementGetInstallPathsTimeNsec()}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testMeasurementGetInstallPathsTimeNsecSuccessNormally() throws Exception {
+		final String addFlow = "addFlow";
+
+		// create mock objects
+		FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, addFlow);
+		mockStaticPartial(System.class, "nanoTime");
+
+		// instantiate required objects
+		FlowPath flow1 = createTestFlowPath(1, "installer id", 1, 2, 3, 4);
+		Map<Long, Object> shortestPathMap = new HashMap<Long, Object>();
+
+		// setup expectations
+		expectInitWithContext();
+		expect(System.nanoTime()).andReturn(new Long(100000));
+		expect(System.nanoTime()).andReturn(new Long(110000));
+		expect((Map<Long,Object>)topoRouteService.prepareShortestPathTopo()
+				).andReturn(shortestPathMap);
+		expect(topoRouteService.getTopoShortestPath(
+				shortestPathMap,
+				flow1.dataPath().srcPort(),
+				flow1.dataPath().dstPort())).andReturn(null);
+		expectPrivate(fm, addFlow,
+				EasyMock.cmpEq(flow1),
+				EasyMock.anyObject(FlowId.class),
+				EasyMock.anyObject(String.class)).andReturn(true);
+		
+		// start the test
+		replayAll();
+
+		fm.init(context);
+		fm.measurementStorePathFlow(flow1).toString();
+		fm.measurementInstallPaths(1);
+		Long result = fm.measurementGetInstallPathsTimeNsec();
+		
+		// verify the test
+		verifyAll();
+		assertEquals(new Long(10000), result);
+	}
+
+	/**
+	 * Test method for {@link FlowManager#measurementGetPerFlowInstallTime()}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testMeasurementGetPerFlowInstallTimeSuccessNormally() throws Exception {
+		final String addFlow = "addFlow";
+
+		// create mock objects
+		FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, addFlow);
+		
+		// instantiate required objects
+		FlowPath flow1 = createTestFlowPath(1, "installer id", 1, 2, 3, 4);
+		Map<Long, Object> shortestPathMap = new HashMap<Long, Object>();
+
+		// setup expectations
+		expectInitWithContext();
+		expect((Map<Long,Object>)topoRouteService.prepareShortestPathTopo()
+				).andReturn(shortestPathMap);
+
+		expect(topoRouteService.getTopoShortestPath(
+				shortestPathMap,
+				flow1.dataPath().srcPort(),
+				flow1.dataPath().dstPort())).andReturn(null);
+
+		expectPrivate(fm, addFlow,
+				EasyMock.cmpEq(flow1),
+				EasyMock.anyObject(FlowId.class),
+				EasyMock.anyObject(String.class)).andReturn(true);
+
+
+		// start the test
+		replayAll();
+
+		fm.init(context);
+		fm.measurementStorePathFlow(flow1);
+		fm.measurementInstallPaths(10);
+		String result = fm.measurementGetPerFlowInstallTime();
+				
+		// verify the test
+		verifyAll();
+		assertTrue(result.startsWith("ThreadAndTimePerFlow"));
+	}
+
+	/**
+	 * Test method for {@link FlowManager#measurementClearAllPaths()}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testMeasurementClearAllPathsSuccessNormally() throws Exception {
+		// instantiate required objects
+		FlowPath paramFlow = createTestFlowPath(100, "installer id", 1, 3, 2, 4);
+		Map<Long, Object> shortestPathMap = new HashMap<Long, Object>();
+		FlowManager fm = new FlowManager();
+
+		// setup expectations
+		expectInitWithContext();
+		expect((Map<Long,Object>)topoRouteService.prepareShortestPathTopo()
+				).andReturn(shortestPathMap);
+		expect(topoRouteService.getTopoShortestPath(
+				shortestPathMap,
+				paramFlow.dataPath().srcPort(),
+				paramFlow.dataPath().dstPort())).andReturn(null);
+		topoRouteService.dropShortestPathTopo(shortestPathMap);
+		
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		fm.measurementStorePathFlow(paramFlow);
+		Boolean result = fm.measurementClearAllPaths();
+				
+		// verify the test
+		verifyAll();
+		assertTrue(result);
+		assertEquals(new Long(0), fm.measurementGetInstallPathsTimeNsec());
+		assertEquals("", fm.measurementGetPerFlowInstallTime());
+	}
+	
+		
+	// INetMapStorage methods
+	
+	
+	/**
+	 * Test method for {@link FlowManager#init(String)}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testInitSuccessNormally() throws Exception {
+		// instantiate required objects
+		FlowManager fm = new FlowManager();
+
+		// create mock objects
+		op = createMock(GraphDBOperation.class);
+
+		// setup expectations
+		expectNew(GraphDBOperation.class, "/dummy/path").andReturn(op);
+		
+		// start the test
+		replayAll();
+		
+		fm.init("/dummy/path");
+		
+		// verify the test
+		verifyAll();
+	}
+	
+	/**
+	 * Test method for {@link FlowManager#close()}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testCloseSuccessNormally() throws Exception {
+		// instantiate required objects
+		FlowManager fm = new FlowManager();
+
+		// setup expectations
+		expectInitWithContext();
+		op.close();
+		
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		fm.close();
+		
+		// verify the test
+		verifyAll();
+	}
+	
+	
+	// IFloodlightModule methods
+	
+	
+	/**
+	 * Test method for {@link FlowManager#getModuleServices()}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testGetModuleServicesSuccessNormally() throws Exception {
+		// instantiate required objects
+		FlowManager fm = new FlowManager();
+
+		// setup expectations
+		expectInitWithContext();
+
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		Collection<Class<? extends IFloodlightService>> l = fm.getModuleServices();
+
+		// verify the test
+		verifyAll();
+		assertEquals(1, l.size());
+		assertEquals(IFlowService.class, l.iterator().next());
+	}
+
+	/**
+	 * Test method for {@link FlowManager#getServiceImpls()}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testGetServiceImplsSuccessNormally() throws Exception {
+		// instantiate required objects
+		FlowManager fm = new FlowManager();
+
+		// setup expectations
+		expectInitWithContext();
+
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		Map<Class<? extends IFloodlightService>, IFloodlightService> si = fm.getServiceImpls();
+
+		// verify the test
+		verifyAll();
+		assertEquals(1, si.size());
+		assertTrue(si.containsKey(IFlowService.class));
+		assertEquals(fm, si.get(IFlowService.class));	
+	}
+
+	/**
+	 * Test method for {@link FlowManager#getModuleDependencies()}.
+	 * @throws Exception
+	 */
+	@Test
+	public final void testGetModuleDependenciesSuccessNormally() throws Exception {
+		// instantiate required objects
+		FlowManager fm = new FlowManager();
+
+		// setup expectations
+		expectInitWithContext();
+
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		Collection<Class<? extends IFloodlightService>> md = fm.getModuleDependencies();
+
+		// verify the test
+		verifyAll();
+		assertEquals(3, md.size());
+		assertTrue(md.contains(IFloodlightProviderService.class));
+		assertTrue(md.contains(ITopoRouteService.class));
+		assertTrue(md.contains(IRestApiService.class));
+	}
+
+	/**
+	 * Test method for {@link FlowManager#init(FloodlightModuleContext)}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testInitWithFloodlightModuleContextSuccessNormally() throws Exception {
+		// instantiate required objects
+		FlowManager fm = new FlowManager();
+		
+		// setup expectations
+		expectInitWithContext();
+
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+
+		// verify the test
+		verifyAll();
+	}
+
+	/**
+	 * Test method for {@link FlowManager#startUp(FloodlightModuleContext)}.
+	 * @throws Exception
+	 */
+	@Test
+	public final void testStartupSuccessNormally() throws Exception {
+		// create mock objects
+		mockStaticPartial(Executors.class, "newScheduledThreadPool");
+		ScheduledExecutorService scheduler = createMock(ScheduledExecutorService.class);
+
+		// instantiate required objects
+		FlowManager fm = new FlowManager();
+		
+		// setup expectations
+		expectInitWithContext();
+		expect(Executors.newScheduledThreadPool(1)).andReturn(scheduler);
+		expect(Executors.newScheduledThreadPool(1)).andReturn(scheduler);
+		expect(scheduler.scheduleAtFixedRate(
+				EasyMock.anyObject(Runnable.class),
+				EasyMock.anyLong(),
+				EasyMock.anyLong(),
+				EasyMock.anyObject(TimeUnit.class))).andReturn(null).times(2);
+		restApi.addRestletRoutable(EasyMock.anyObject(FlowWebRoutable.class));
+
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		fm.startUp(context);
+
+		// verify the test
+		verifyAll();
+	}
+	
+	
+	// other methods
+	
+	
+	/**
+	 * Test method for {@link FlowManager#clearFlow(FlowId)}.
+	 * @throws Exception
+	 */
+	@Test
+	public final void testClearFlowSuccessNormally() throws Exception {
+		// create mock objects
+		IFlowPath flowPath = createIFlowPathMock(123, "id", 1, 2, 3, 4);
+		IFlowEntry flowEntry1 = createMock(IFlowEntry.class);
+		IFlowEntry flowEntry2 = createMock(IFlowEntry.class);
+		IFlowEntry flowEntry3 = createMock(IFlowEntry.class);
+		
+		// instantiate required objects
+		FlowManager fm = new FlowManager();
+		FlowId flowId = new FlowId(123);
+		ArrayList<IFlowEntry> flowEntries = new ArrayList<IFlowEntry>();
+		flowEntries.add(flowEntry1);
+		flowEntries.add(flowEntry2);
+		flowEntries.add(flowEntry3);
+
+		// setup expectations
+		expectInitWithContext();
+		expect(op.searchFlowPath(cmpEq(flowId))).andReturn(flowPath);
+		expect(flowPath.getFlowEntries()).andReturn(flowEntries);
+		flowPath.removeFlowEntry(flowEntry1);
+		flowPath.removeFlowEntry(flowEntry2);
+		flowPath.removeFlowEntry(flowEntry3);
+		op.removeFlowEntry(flowEntry1);
+		op.removeFlowEntry(flowEntry2);
+		op.removeFlowEntry(flowEntry3);
+		op.removeFlowPath(flowPath);
+		op.commit();
+
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		fm.clearFlow(flowId);
+
+		// verify the test
+		verifyAll();
+	}
+	
+	/**
+	 * Test method for {@link FlowManager#getAllFlowsWithoutFlowEntries()}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testGetAllFlowsWithoutFlowEntriesSuccessNormally() throws Exception {
+		// create mock objects
+		IFlowPath iFlowPath1 = createIFlowPathMock(1, "caller id", 1, 1, 2, 2); 
+		IFlowPath iFlowPath2 = createIFlowPathMock(2, "caller id", 2, 5, 3, 5);
+		
+		// instantiate required objects
+		ArrayList<IFlowPath> flowPaths = new ArrayList<IFlowPath>();
+		flowPaths.add(iFlowPath1);
+		flowPaths.add(iFlowPath2);
+		FlowManager fm = new FlowManager();
+		
+		// setup expectations
+		expectInitWithContext();
+		op.commit();
+		expect(op.getAllFlowPaths()).andReturn(flowPaths);
+		
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		ArrayList<IFlowPath> result = fm.getAllFlowsWithoutFlowEntries();
+		
+		// verify the test
+		verifyAll();
+		assertEquals(iFlowPath1, result.get(0));
+		assertEquals(iFlowPath2, result.get(1));
+		
+		// TODO: does this method just return the replica of the flow paths?
+	}
+	
+	/**
+	 * Test method for {@link FlowManager#reconcileFlow(IFlowPath, DataPath)}.
+	 * @throws Exception
+	 */
+	@Test
+	public final void testReconcileFlowWithFlowPathAndDataPathSuccessNormally() throws Exception {
+		final String addFlowEntry = "addFlowEntry";
+		
+		// create mock objects
+		IFlowPath iFlowPath1 = createIFlowPathMock(1, "caller id", 1, 1, 2, 2);
+		IFlowEntry iFlowEntry1 = createMock(IFlowEntry.class);
+		IFlowEntry iFlowEntry2 = createMock(IFlowEntry.class);
+		FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, addFlowEntry);
+		
+		// instantiate required objects
+		FlowEntry flowEntry1 = new FlowEntry();
+		flowEntry1.setDpid(new Dpid(1));
+		flowEntry1.setFlowId(new FlowId(1));
+		flowEntry1.setInPort(new Port((short) 1));
+		flowEntry1.setOutPort(new Port((short) 11));
+		flowEntry1.setFlowEntryId(new FlowEntryId(1));
+		flowEntry1.setFlowEntryMatch(new FlowEntryMatch());
+		flowEntry1.setFlowEntryActions(new ArrayList<FlowEntryAction>());
+		flowEntry1.setFlowEntryErrorState(new FlowEntryErrorState());
+		
+		FlowEntry flowEntry2 = new FlowEntry();
+		flowEntry2.setDpid(new Dpid(2));
+		flowEntry2.setFlowId(new FlowId(2));
+		flowEntry2.setInPort(new Port((short) 22)); 
+		flowEntry2.setOutPort(new Port((short) 2));
+		flowEntry2.setFlowEntryId(new FlowEntryId(2));
+		flowEntry2.setFlowEntryMatch(new FlowEntryMatch());
+		flowEntry2.setFlowEntryActions(new ArrayList<FlowEntryAction>());
+		flowEntry2.setFlowEntryErrorState(new FlowEntryErrorState());
+		
+		DataPath dataPath = new DataPath();
+		ArrayList<FlowEntry> flowEntries = new ArrayList<FlowEntry>();
+		flowEntries.add(flowEntry1);
+		flowEntries.add(flowEntry2);
+		dataPath.setFlowEntries(flowEntries);
+		
+		ArrayList<IFlowEntry> oldFlowEntries = new ArrayList<IFlowEntry>();
+		oldFlowEntries.add(iFlowEntry1);
+		oldFlowEntries.add(iFlowEntry2);
+
+		// setup expectations
+		expectInitWithContext();
+		expect(floodlightProvider.getSwitches()).andReturn(null); // TODO: why is this needed?
+		expect(iFlowPath1.getFlowEntries()).andReturn(oldFlowEntries);
+		iFlowEntry1.setUserState("FE_USER_DELETE");
+		iFlowEntry1.setSwitchState("FE_SWITCH_NOT_UPDATED");
+		iFlowEntry2.setUserState("FE_USER_DELETE");
+		iFlowEntry2.setSwitchState("FE_SWITCH_NOT_UPDATED");
+		expectPrivate(fm, addFlowEntry, iFlowPath1, flowEntry1).andReturn(null);
+		expectPrivate(fm, addFlowEntry, iFlowPath1, flowEntry2).andReturn(null);
+
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		Boolean result = fm.reconcileFlow(iFlowPath1, dataPath);
+		
+		// verify the test
+		verifyAll();
+		assertTrue(result);
+		// TODO: write more asserts
+	}
+	
+	/**
+	 * Test method for {@link FlowManager#installFlowEntry(net.floodlightcontroller.core.IOFSwitch, IFlowPath, IFlowEntry)}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testInstallFlowEntryWithIFlowPathSuccessNormally() throws Exception {
+		// create mock object
+		IOFSwitch iofSwitch = createNiceMock(IOFSwitch.class);
+		IFlowPath iFlowPath = createIFlowPathMock(1, "id", 1, 2, 3, 4); 
+		IFlowEntry iFlowEntry = createMock(IFlowEntry.class);
+		BasicFactory basicFactory = createMock(BasicFactory.class);
+		
+		// instantiate required objects
+		FlowManager fm = new FlowManager();
+		
+		// setup expectations
+		expectInitWithContext();
+		expect(iFlowEntry.getFlowEntryId()).andReturn(new FlowEntryId(123).toString());
+		expect(iFlowEntry.getUserState()).andReturn("FE_USER_ADD");
+		iFlowEntry.setSwitchState("FE_SWITCH_UPDATED");
+		expect(iFlowEntry.getMatchInPort()).andReturn(new Short((short) 1));
+		expect(iFlowEntry.getMatchEthernetFrameType()).andReturn(new Short((short)0x0800));
+		expect(iFlowEntry.getMatchSrcIPv4Net()).andReturn("192.168.0.1");
+		expect(iFlowEntry.getMatchDstIPv4Net()).andReturn("192.168.0.2");
+		expect(iFlowEntry.getMatchSrcMac()).andReturn("01:23:45:67:89:01");
+		expect(iFlowEntry.getMatchDstMac()).andReturn("01:23:45:67:89:02");
+		expect(iFlowEntry.getActionOutput()).andReturn(new Short((short) 2));
+		expect(floodlightProvider.getOFMessageFactory()).andReturn(basicFactory);
+		expect(basicFactory.getMessage(OFType.FLOW_MOD)).andReturn(new OFFlowMod());
+		expect(iofSwitch.getStringId()).andReturn(new Dpid(100).toString());
+
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		Boolean result = fm.installFlowEntry(iofSwitch, iFlowPath, iFlowEntry);
+		
+		// verify the test
+		verifyAll();
+		assertTrue(result);
+		// TODO: write more asserts
+	}
+
+	/**
+	 * Test method for {@link FlowManager#installFlowEntry(net.floodlightcontroller.core.IOFSwitch, FlowPath, FlowEntry)}.
+	 * The method seems to be not used for now.
+	 */
+	@Ignore @Test
+	public final void testInstallFlowEntryWithFlowPathSuccessNormally() {
+		fail("not yet implemented");
+	}
+
+	/**
+	 * Test method for {@link FlowManager#removeFlowEntry(net.floodlightcontroller.core.IOFSwitch, FlowPath, FlowEntry)}.
+	 * The method seems to be not implemented and not used for now.
+	 */
+	@Ignore @Test
+	public final void testRemoveFlowEntrySuccessNormally() {
+		fail("not yet implemented");
+	}
+
+	/**
+	 * Test method for {@link FlowManager#installRemoteFlowEntry(FlowPath, FlowEntry)}.
+	 * The method seems to be not implemented and not used for now.
+	 */
+	@Ignore @Test
+	public final void testInstallRemoteFlowEntrySuccessNormally() {
+		fail("not yet implemented");
+	}
+
+	/**
+	 * Test method for {@link FlowManager#removeRemoteFlowEntry(FlowPath, FlowEntry)}.
+	 * The method seems to be not implemented and not used for now.
+	 */
+	@Ignore @Test
+	public final void testRemoveRemoteFlowEntrySuccessNormally() {
+		fail("not yet implemented");
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/net/onrc/onos/ofcontroller/routing/TopoRouteServiceTest.java b/src/test/java/net/onrc/onos/ofcontroller/routing/TopoRouteServiceTest.java
new file mode 100644
index 0000000..e6d7d16
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/routing/TopoRouteServiceTest.java
@@ -0,0 +1,234 @@
+package net.onrc.onos.ofcontroller.routing;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.easymock.EasyMock;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine;
+import com.tinkerpop.gremlin.java.GremlinPipeline;
+import com.tinkerpop.pipes.PipeFunction;
+import com.tinkerpop.pipes.branch.LoopPipe.LoopBundle;
+
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
+import net.onrc.onos.ofcontroller.routing.TopoRouteService;
+import net.onrc.onos.ofcontroller.util.DataPath;
+import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.Port;
+import net.onrc.onos.ofcontroller.util.SwitchPort;
+
+/**
+ * A class for testing the TopoRouteService class.
+ * @see net.onrc.onos.ofcontroller.routing.TopoRouteService
+ * @author Pavlin Radoslavov (pavlin@onlab.us)
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, TopoRouteService.class})
+public class TopoRouteServiceTest {
+    String conf;
+    private GraphDBConnection conn = null;
+    private GraphDBOperation oper = null;
+    private TitanGraph titanGraph = null;
+    private TopoRouteService topoRouteService = null;
+
+    /**
+     * Setup the tests.
+     */
+    @Before
+    public void setUp() throws Exception {
+	conf = "/dummy/path/to/db";
+
+	//
+	// Make mock database.
+	// Replace TitanFactory.open() to return the mock database.
+	//
+	titanGraph = TestDatabaseManager.getTestDatabase();
+	PowerMock.mockStatic(TitanFactory.class);
+	EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
+	PowerMock.replay(TitanFactory.class);
+
+	// Create the connection to the database
+	conn = GraphDBConnection.getInstance(conf);
+	oper = new GraphDBOperation(conn);
+
+	// Populate the database
+	TestDatabaseManager.populateTestData(titanGraph);
+
+	// Prepare the TopoRouteService instance
+	topoRouteService = new TopoRouteService();
+	topoRouteService.setDbOperationHandler(oper);
+    }
+
+    /**
+     * Cleanup after the tests.
+     */
+    @After
+    public void tearDown() throws Exception {
+	titanGraph.shutdown();
+	TestDatabaseManager.deleteTestDatabase();
+    }
+
+    /**
+     * Test method TopoRouteService.getTopoShortestPath()
+     *
+     * @see net.onrc.onos.ofcontroller.routing.TopoRouteService#getTopoShortestPath
+     */
+    @Test
+    public void test_getTopoShortestPath() {
+	DataPath dataPath = null;
+	String srcDpidStr = "00:00:00:00:00:00:0a:01";
+	String dstDpidStr = "00:00:00:00:00:00:0a:06";
+	short srcPortShort = 1;
+	short dstPortShort = 1;
+
+	//
+	// Initialize the source and destination points
+	//
+	Dpid srcDpid = new Dpid(srcDpidStr);
+	Port srcPort = new Port(srcPortShort);
+	Dpid dstDpid = new Dpid(dstDpidStr);
+	Port dstPort = new Port(dstPortShort);
+	SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
+	SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
+
+	//
+	// Test a valid Shortest-Path computation
+	//
+	Map<Long, ?> shortestPathTopo =
+	    topoRouteService.prepareShortestPathTopo();
+	dataPath = topoRouteService.getTopoShortestPath(shortestPathTopo,
+							srcSwitchPort,
+							dstSwitchPort);
+	assertTrue(dataPath != null);
+	String dataPathSummaryStr = dataPath.dataPathSummary();
+	// System.out.println(dataPathSummaryStr);
+	String expectedResult = "1/00:00:00:00:00:00:0a:01/2;1/00:00:00:00:00:00:0a:03/2;2/00:00:00:00:00:00:0a:04/3;1/00:00:00:00:00:00:0a:06/1;";
+	assertEquals(dataPathSummaryStr, expectedResult);
+
+	//
+	// Test Shortest-Path computation to non-existing destination
+	//
+	String noSuchDpidStr = "ff:ff:00:00:00:00:0a:06";
+	Dpid noSuchDstDpid = new Dpid(noSuchDpidStr);
+	SwitchPort noSuchDstSwitchPort = new SwitchPort(noSuchDstDpid, dstPort);
+	dataPath = topoRouteService.getTopoShortestPath(shortestPathTopo,
+							srcSwitchPort,
+							noSuchDstSwitchPort);
+	assertTrue(dataPath == null);
+
+	topoRouteService.dropShortestPathTopo(shortestPathTopo);
+    }
+
+    /**
+     * Test method TopoRouteService.getShortestPath()
+     *
+     * @see net.onrc.onos.ofcontroller.routing.TopoRouteService#getShortestPath
+     */
+    @Test
+    public void test_getShortestPath() {
+	DataPath dataPath = null;
+	String srcDpidStr = "00:00:00:00:00:00:0a:01";
+	String dstDpidStr = "00:00:00:00:00:00:0a:06";
+	short srcPortShort = 1;
+	short dstPortShort = 1;
+
+	//
+	// Initialize the source and destination points
+	//
+	Dpid srcDpid = new Dpid(srcDpidStr);
+	Port srcPort = new Port(srcPortShort);
+	Dpid dstDpid = new Dpid(dstDpidStr);
+	Port dstPort = new Port(dstPortShort);
+	SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
+	SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
+
+	//
+	// Test a valid Shortest-Path computation
+	//
+	dataPath = topoRouteService.getShortestPath(srcSwitchPort,
+						dstSwitchPort);
+	assertTrue(dataPath != null);
+	String dataPathSummaryStr = dataPath.dataPathSummary();
+	// System.out.println(dataPathSummaryStr);
+	String expectedResult = "1/00:00:00:00:00:00:0a:01/2;1/00:00:00:00:00:00:0a:03/2;2/00:00:00:00:00:00:0a:04/3;1/00:00:00:00:00:00:0a:06/1;";
+	assertEquals(dataPathSummaryStr, expectedResult);
+
+	//
+	// Test Shortest-Path computation to non-existing destination
+	//
+	String noSuchDpidStr = "ff:ff:00:00:00:00:0a:06";
+	Dpid noSuchDstDpid = new Dpid(noSuchDpidStr);
+	SwitchPort noSuchDstSwitchPort = new SwitchPort(noSuchDstDpid, dstPort);
+
+	dataPath = topoRouteService.getShortestPath(srcSwitchPort,
+						    noSuchDstSwitchPort);
+	assertTrue(dataPath == null);
+    }
+
+    /**
+     * Test method TopoRouteService.routeExists()
+     *
+     * @see net.onrc.onos.ofcontroller.routing.TopoRouteService#routeExists
+     */
+    @Test
+    public void test_routeExists() {
+	Boolean result;
+	String srcDpidStr = "00:00:00:00:00:00:0a:01";
+	String dstDpidStr = "00:00:00:00:00:00:0a:06";
+	short srcPortShort = 1;
+	short dstPortShort = 1;
+
+	//
+	// Initialize the source and destination points
+	//
+	Dpid srcDpid = new Dpid(srcDpidStr);
+	Port srcPort = new Port(srcPortShort);
+	Dpid dstDpid = new Dpid(dstDpidStr);
+	Port dstPort = new Port(dstPortShort);
+	SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
+	SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
+
+	//
+	// Test a valid route
+	//
+	result = topoRouteService.routeExists(srcSwitchPort, dstSwitchPort);
+	assertTrue(result == true);
+
+	//
+	// Test a non-existing route
+	//
+	String noSuchDpidStr = "ff:ff:00:00:00:00:0a:06";
+	Dpid noSuchDstDpid = new Dpid(noSuchDpidStr);
+	SwitchPort noSuchDstSwitchPort = new SwitchPort(noSuchDstDpid, dstPort);
+	result = topoRouteService.routeExists(srcSwitchPort,
+					      noSuchDstSwitchPort);
+	assertTrue(result != true);
+    }
+}
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..7c4a1a0
--- /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 {@link StandaloneRegistry}.
+ * @author Naoki Shiota
+ *
+ */
+public class StandaloneRegistryTest {
+	protected static final long TIMEOUT_MSEC = 1000;
+	
+	protected StandaloneRegistry registry;
+	
+	/**
+	 * Implementation of {@link ControlChangeCallback} which defines callback interfaces called by Registry.
+	 * This class remembers past callback parameters and provides methods to access them.
+	 * This class also provides CountDownLatch so one can wait until the callback be called
+	 * specific times (specified by constructor parameter). Particularly, the first time callback
+	 * called is supposed for registration, this class has an independent latch to wait for
+	 * the first callback.
+	 * @author Naoki Shiota
+	 */
+	public static class LoggingCallback implements ControlChangeCallback {
+		private LinkedList<Long> dpidsCalledback = new LinkedList<Long>();
+		private LinkedList<Boolean> controlsCalledback = new LinkedList<Boolean>();
+		private CountDownLatch lock = null, registerLock = null;;
+		
+		/**
+		 * Constructor with number of times callback to be called.
+		 * @param numberToCall Number of times expected callback to be called
+		 */
+		public LoggingCallback(int numberToCall) {
+			lock = new CountDownLatch(numberToCall);
+			registerLock = new CountDownLatch(1);
+		}
+
+		/**
+		 * Wait until registration is finished (callback is called for the first time).
+		 * @throws InterruptedException
+		 */
+		public void waitForRegistration() throws InterruptedException {
+			registerLock.await();
+		}
+		
+		/**
+		 * Wait for registration specifying timeout.
+		 * @param msec Milliseconds to timeout
+		 * @throws InterruptedException
+		 */
+		public void waitForRegistration(long msec) throws InterruptedException {
+			registerLock.await(msec, TimeUnit.MILLISECONDS);
+		}
+
+		/**
+		 * Wait until callback is called specific times.
+		 * @throws InterruptedException
+		 */
+		public void waitUntilCalled() throws InterruptedException {
+			lock.await();
+		}
+		
+		/**
+		 * Wait until callback is called specific times, specifying timeout.
+		 * @param msec Milliseconds to timeout
+		 * @throws InterruptedException
+		 */
+		public void waitUntilCalled(long msec) throws InterruptedException {
+			lock.await(msec, TimeUnit.MILLISECONDS);
+		}
+		
+		/**
+		 * Get DPID parameter given by specific callback time.
+		 * @param index Specify which time to get parameter
+		 * @return DPID value by number.
+		 */
+		public Long getDpid(int index) { return dpidsCalledback.get(index); }
+		
+		/**
+		 * Get hasControl parameter given by specific callback time.
+		 * @param index Specify which time to get parameter
+		 * @return hasControl value
+		 */
+		public Boolean getControl(int index) { return controlsCalledback.get(index); }
+		
+		/**
+		 * Get DPID parameter given by latest call.
+		 * @return DPID value by number
+		 */
+		public Long getLatestDpid() { return dpidsCalledback.peekLast(); }
+		
+		/**
+		 * Get hasControl parameter given by latest call
+		 * @return hasControl value
+		 */
+		public Boolean getLatestControl() { return controlsCalledback.peekLast(); }
+		
+		@Override
+		public void controlChanged(long dpid, boolean hasControl) {
+			dpidsCalledback.addLast(dpid);
+			controlsCalledback.addLast(hasControl);
+			
+			lock.countDown();
+			registerLock.countDown();
+		}
+	};
+	
+	@Before
+	public void setUp() throws Exception {
+        FloodlightModuleContext fmc = new FloodlightModuleContext();
+		registry = new StandaloneRegistry();
+		registry.init(fmc);
+	}
+
+	@After
+	public void tearDown() {
+	}
+	
+	/**
+	 * Test if {@link StandaloneRegistry#registerController(String)} can run without error.
+	 */
+	@Test
+	public void testRegisterController() {
+		String controllerIdToRegister = "test";
+		try {
+			registry.registerController(controllerIdToRegister);
+		} catch (RegistryException e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		}
+		
+		// Register Controller ID doubly 
+		try {
+			registry.registerController(controllerIdToRegister);
+			fail("Double registration goes through without exception");
+		} catch (RegistryException e) {
+			// expected behavior
+		}
+	}
+	
+	/**
+	 * Test if {@link StandaloneRegistry#getControllerId()} can return correct ID.
+	 * @throws RegistryException
+	 */
+	@Test
+	public void testGetControllerId() throws RegistryException {
+		String controllerIdToRegister = "test";
+		
+		// try before controller is registered
+		String controllerId = registry.getControllerId();
+		assertNull(controllerId);
+		
+		// register
+		registry.registerController(controllerIdToRegister);
+
+		// call getControllerId and verify
+		controllerId = registry.getControllerId();
+		assertNotNull(controllerId);
+		assertEquals(controllerIdToRegister, controllerId);
+	}
+
+	/**
+	 * Test if {@link StandaloneRegistry#getAllControllers()} can return correct list of controllers.
+	 * @throws RegistryException
+	 */
+	@Test
+	public void testGetAllControllers() throws RegistryException {
+		String controllerIdToRegister = "test";
+		
+		// Test before register controller
+		try {
+			Collection<String> ctrls = registry.getAllControllers();
+			assertFalse(ctrls.contains(controllerIdToRegister));
+		} catch (RegistryException e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		}
+		
+		// register
+		registry.registerController(controllerIdToRegister);
+
+		// Test after register controller
+		try {
+			Collection<String> ctrls = registry.getAllControllers();
+			assertTrue(ctrls.contains(controllerIdToRegister));
+		} catch (RegistryException e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		}
+	}
+
+	/**
+	 * Test if {@link StandaloneRegistry#requestControl(long, ControlChangeCallback)} can correctly take control for switch so that callback is called.
+	 * @throws RegistryException
+	 * @throws InterruptedException
+	 */
+	@Test
+	public void testRequestControl() throws InterruptedException, RegistryException {
+		String controllerId = "test";
+		registry.registerController(controllerId);
+
+		LoggingCallback callback = new LoggingCallback(1);
+		long dpidToRequest = 1000L;
+
+		try {
+			registry.requestControl(dpidToRequest, callback);
+		} catch (RegistryException e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		}
+		
+		callback.waitForRegistration();
+		
+		long dpidCallback = callback.getLatestDpid();
+		boolean controlCallback = callback.getLatestControl();
+		
+		assertEquals(dpidToRequest, dpidCallback);
+		assertTrue(controlCallback);
+	}
+
+	/**
+	 * Test if {@link StandaloneRegistry#releaseControl(long)} can correctly release the control so that callback is called.
+	 * @throws InterruptedException
+	 * @throws RegistryException
+	 */
+	@Test
+	public void testReleaseControl() throws InterruptedException, RegistryException {
+		String controllerId = "test";
+		registry.registerController(controllerId);
+		
+		long dpidToRequest = 1000L;
+		LoggingCallback callback = new LoggingCallback(2);
+		
+		// to request and wait to take control
+		registry.requestControl(dpidToRequest, callback);
+		callback.waitForRegistration();
+		
+		registry.releaseControl(dpidToRequest);
+		
+		// verify
+		callback.waitUntilCalled();
+		assertEquals(dpidToRequest, (long)callback.getLatestDpid());
+		assertFalse(callback.getLatestControl());
+	}
+
+	/**
+	 * Test if {@link StandaloneRegistry#hasControl(long)} returns correct status.
+	 * @throws InterruptedException
+	 * @throws RegistryException
+	 */
+	@Test
+	public void testHasControl() throws InterruptedException, RegistryException {
+		String controllerId = "test";
+		registry.registerController(controllerId);
+		
+		long dpidToRequest = 1000L;
+		LoggingCallback callback = new LoggingCallback(2);
+		
+		// Test before request control
+		assertFalse(registry.hasControl(dpidToRequest));
+		
+		registry.requestControl(dpidToRequest, callback);
+		callback.waitForRegistration();
+		
+		// Test after take control
+		assertTrue(registry.hasControl(dpidToRequest));
+		
+		registry.releaseControl(dpidToRequest);
+		
+		callback.waitUntilCalled();
+
+		// Test after release control
+		assertFalse(registry.hasControl(dpidToRequest));
+	}
+
+	/**
+	 * Test if {@link StandaloneRegistry#getControllerForSwitch(long)} returns correct controller ID.
+	 * @throws InterruptedException
+	 * @throws RegistryException
+	 */
+	@Test
+	public void testGetControllerForSwitch() throws InterruptedException, RegistryException {
+		String controllerId = "test";
+		registry.registerController(controllerId);
+		
+		long dpidToRequest = 1000L;
+		LoggingCallback callback = new LoggingCallback(2);
+		
+		// Test before request control
+		try {
+			String controllerForSw = registry.getControllerForSwitch(dpidToRequest);
+			assertNotEquals(controllerId,controllerForSw);
+		} catch (RegistryException e) {
+			fail("Failed before request control : " + e.getMessage());
+			e.printStackTrace();
+		}
+
+		registry.requestControl(dpidToRequest, callback);
+		callback.waitForRegistration();
+
+		// Test after take control
+		try {
+			String controllerForSw = registry.getControllerForSwitch(dpidToRequest);
+			assertEquals(controllerId,controllerForSw);
+		} catch (RegistryException e) {
+			fail("Failed after take control : " + e.getMessage());
+			e.printStackTrace();
+		}
+
+		registry.releaseControl(dpidToRequest);
+		callback.waitUntilCalled();
+
+		// Test after release control
+		try {
+			String controllerForSw = registry.getControllerForSwitch(dpidToRequest);
+			assertNotEquals(controllerId,controllerForSw);
+		} catch (RegistryException e) {
+			fail("Failed after release control : " + e.getMessage());
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Test if {@link StandaloneRegistry#getAllSwitches()} returns correct list of switches.
+	 * @throws InterruptedException
+	 * @throws RegistryException
+	 */
+	@Test
+	public void testGetAllSwitches() throws InterruptedException, RegistryException {
+		String controllerId = "test";
+		registry.registerController(controllerId);
+
+		long dpidToRequest = 1000L;
+		String dpidToRequestStr = HexString.toHexString(dpidToRequest);
+		LoggingCallback callback = new LoggingCallback(2);
+
+		// Test before request control
+		Map<String, List<ControllerRegistryEntry>> switches = registry.getAllSwitches();
+		assertNotNull(switches);
+		assertFalse(switches.keySet().contains(dpidToRequestStr));
+
+		registry.requestControl(dpidToRequest, callback);
+		callback.waitForRegistration();
+
+		// Test after take control
+		switches = registry.getAllSwitches();
+		assertNotNull(switches);
+		assertTrue(switches.keySet().contains(dpidToRequestStr));
+		int count = 0;
+		for(ControllerRegistryEntry ctrl : switches.get(dpidToRequestStr)) {
+			if(ctrl.getControllerId().equals(controllerId)) {
+				++count;
+			}
+		}
+		assertEquals(1,count);
+		
+		registry.releaseControl(dpidToRequest);
+		callback.waitUntilCalled();
+
+		// Test after release control
+		switches = registry.getAllSwitches();
+		assertNotNull(switches);
+		assertFalse(switches.keySet().contains(dpidToRequestStr));
+	}
+
+	/**
+	 * Test if {@link StandaloneRegistry#getSwitchesControlledByController(String)} returns correct list of switches.
+	 * @throws InterruptedException
+	 * @throws RegistryException
+	 */
+	// TODO: remove @Ignore after implement StandaloneRegistry#getSwitchesControlledByController
+	@Ignore @Test
+	public void testGetSwitchesControlledByController() throws InterruptedException, RegistryException {
+		String controllerId = "test";
+		registry.registerController(controllerId);
+
+		long dpidToRequest = 1000L;
+		String dpidToRequestStr = HexString.toHexString(dpidToRequest);
+		LoggingCallback callback = new LoggingCallback(2);
+
+		// Test before request control
+		Collection<Long> switches = registry.getSwitchesControlledByController(controllerId);
+		assertNotNull(switches);
+		assertFalse(switches.contains(dpidToRequestStr));
+
+		registry.requestControl(dpidToRequest, callback);
+		callback.waitForRegistration();
+
+		// Test after take control
+		switches = registry.getSwitchesControlledByController(controllerId);
+		assertNotNull(switches);
+		assertTrue(switches.contains(dpidToRequestStr));
+		int count = 0;
+		for(Long dpid : switches) {
+			if((long)dpid == dpidToRequest) {
+				++count;
+			}
+		}
+		assertEquals(1, count);
+		
+		registry.releaseControl(dpidToRequest);
+		callback.waitUntilCalled();
+
+		// Test after release control
+		switches = registry.getSwitchesControlledByController(controllerId);
+		assertNotNull(switches);
+		assertFalse(switches.contains(dpidToRequestStr));
+	}
+
+	/**
+	 * Test if {@link StandaloneRegistry#allocateUniqueIdBlock()} returns appropriate object.
+	 * Get bulk of IdBlocks and check if they do have unique range of IDs.
+	 */
+	@Test
+	public void testAllocateUniqueIdBlock() {
+		// Number of blocks to be verified that any of them has unique block
+		final int NUM_BLOCKS = 100;
+		ArrayList<IdBlock> blocks = new ArrayList<IdBlock>(NUM_BLOCKS);
+		
+		for(int i = 0; i < NUM_BLOCKS; ++i) {
+			blocks.add(registry.allocateUniqueIdBlock());
+		}
+		
+		for(int i = 0; i < NUM_BLOCKS; ++i) {
+			IdBlock block1 = blocks.get(i);
+			for(int j = i + 1; j < NUM_BLOCKS; ++j) {
+				IdBlock block2 = blocks.get(j);
+				IdBlock lower,higher;
+				
+				if(block1.getStart() < block2.getStart()) {
+					lower = block1;
+					higher = block2;
+				} else {
+					lower = block2;
+					higher = block1;
+				}
+				
+				assertTrue(lower.getSize() > 0L);
+				assertTrue(higher.getSize() > 0L);
+				assertTrue(lower.getEnd() < higher.getStart());
+			}
+		}
+	}
+}
diff --git a/src/test/java/net/onrc/onos/registry/controller/ZookeeperRegistryTest.java b/src/test/java/net/onrc/onos/registry/controller/ZookeeperRegistryTest.java
new file mode 100644
index 0000000..3314ad2
--- /dev/null
+++ b/src/test/java/net/onrc/onos/registry/controller/ZookeeperRegistryTest.java
@@ -0,0 +1,597 @@
+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 {@link ZookeeperRegistry}.
+ * NOTE: {@link FloodlightTestCase} conflicts with PowerMock. If FloodLight-related methods need to be tested,
+ *       implement another test class to test them.
+ * @author Naoki Shiota
+ *
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({ZookeeperRegistry.class, CuratorFramework.class, CuratorFrameworkFactory.class,
+	ServiceDiscoveryBuilder.class, ServiceDiscovery.class, ServiceCache.class, PathChildrenCache.class,
+	ZookeeperRegistry.SwitchPathCacheListener.class})
+public class ZookeeperRegistryTest extends FloodlightTestCase {
+	private final static Long ID_BLOCK_SIZE = 0x100000000L;
+	
+	protected ZookeeperRegistry registry;
+	protected CuratorFramework client;
+	
+	protected PathChildrenCacheListener pathChildrenCacheListener;
+	protected final String CONTROLLER_ID = "controller2013";
+
+	/**
+	 * Initialize {@link ZookeeperRegistry} Object and inject initial value with {@link ZookeeperRegistry#init(FloodlightModuleContext)} method.
+	 * This setup code also tests {@link ZookeeperRegistry#init(FloodlightModuleContext)} method itself.
+	 */
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		
+		pathChildrenCacheListener = null;
+		
+		// Mock of CuratorFramework
+		client = createCuratorFrameworkMock();
+		
+		// Mock of CuratorFrameworkFactory
+		PowerMock.mockStatic(CuratorFrameworkFactory.class);
+		EasyMock.expect(CuratorFrameworkFactory.newClient((String)EasyMock.anyObject(),
+				EasyMock.anyInt(), EasyMock.anyInt(), (RetryPolicy)EasyMock.anyObject())).andReturn(client);
+		PowerMock.replay(CuratorFrameworkFactory.class);
+
+		FloodlightModuleContext fmc = new FloodlightModuleContext();
+		registry = new ZookeeperRegistry();
+		fmc.addService(ZookeeperRegistry.class, registry);
+		
+		registry.init(fmc);
+		
+		PowerMock.verify(client, CuratorFrameworkFactory.class);
+	}
+
+	/**
+	 * Clean up member variables (empty for now).
+	 */
+	@After
+	public void tearDown() throws Exception {
+		super.tearDown();
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#registerController(String)} method can go through without exception.
+	 * (Exceptions are usually out of test target, but {@link ZookeeperRegistry#registerController(String)} throws an exception in case of invalid registration.)
+	 */
+	@Test
+	public void testRegisterController() {
+		String controllerIdToRegister = "controller2013";
+		
+		try {
+			registry.registerController(controllerIdToRegister);
+		} catch (RegistryException e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		}
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#getControllerId()} correctly returns registered ID.
+	 * @throws Exception
+	 */
+	@Test
+	public void testGetControllerId() throws Exception {
+		String controllerIdToRegister = "controller1";
+		
+		// try before controller is registered
+		String controllerId = registry.getControllerId();
+		assertNull(controllerId);
+		
+		// register
+		registry.registerController(controllerIdToRegister);
+	
+		// call getControllerId and verify
+		controllerId = registry.getControllerId();
+		assertNotNull(controllerId);
+		assertEquals(controllerIdToRegister, controllerId);
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#getAllControllers()} returns all controllers.
+	 * Controllers to be returned are injected while setup. See {@link ZookeeperRegistryTest#createCuratorFrameworkMock()}
+	 * to what controllers are injected using mock {@link ServiceCache}.
+	 * @throws Exception
+	 */
+	@Test
+	public void testGetAllControllers() throws Exception {
+		String controllerIdRegistered = "controller1";
+		String controllerIdNotRegistered = "controller2013";
+
+		try {
+			Collection<String> ctrls = registry.getAllControllers();
+			assertTrue(ctrls.contains(controllerIdRegistered));
+			assertFalse(ctrls.contains(controllerIdNotRegistered));
+		} catch (RegistryException e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		}
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#requestControl(long, net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback)}
+	 * correctly take control of specific switch. Because {@link ZookeeperRegistry#requestControl(long, net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback)}
+	 * doesn't return values, inject mock {@link LeaderLatch} object and verify latch is correctly set up.
+	 * @throws Exception
+	 */
+	@Test
+	public void testRequestControl() throws Exception {
+		// Mock LeaderLatch
+		LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
+		latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
+		EasyMock.expectLastCall().once();
+		latch.start();
+		EasyMock.expectLastCall().once();
+		EasyMock.replay(latch);
+		
+		PowerMock.expectNew(LeaderLatch.class,
+				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(String.class))
+				.andReturn(latch).once();
+		PowerMock.replay(LeaderLatch.class);
+		
+		String controllerId = "controller2013";
+		registry.registerController(controllerId);
+
+		LoggingCallback callback = new LoggingCallback(1);
+		long dpidToRequest = 2000L;
+
+		try {
+			registry.requestControl(dpidToRequest, callback);
+		} catch (RegistryException e) {
+			e.printStackTrace();
+			fail(e.getMessage());
+		}
+		
+		EasyMock.verify(latch);
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#releaseControl(long)} correctly release control of specific switch.
+	 * Because {@link ZookeeperRegistry#releaseControl(long)} doesn't return values, inject mock
+	 * {@link LeaderLatch} object and verify latch is correctly set up.
+	 * @throws Exception
+	 */
+	@Test
+	public void testReleaseControl() throws Exception {
+		// Mock of LeaderLatch
+		LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
+		latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
+		EasyMock.expectLastCall().once();
+		latch.start();
+		EasyMock.expectLastCall().once();
+		latch.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).once();
+		PowerMock.replay(LeaderLatch.class);
+		
+		String controllerId = "controller2013";
+		registry.registerController(controllerId);
+		
+		long dpidToRequest = 2000L;
+		LoggingCallback callback = new LoggingCallback(1);
+		
+		registry.requestControl(dpidToRequest, callback);
+		registry.releaseControl(dpidToRequest);
+		
+		EasyMock.verify(latch);
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#hasControl(long)} returns correct status whether controller has control of specific switch.
+	 * @throws Exception
+	 */
+	@Test
+	public void testHasControl() throws Exception {
+		// Mock of LeaderLatch
+		LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
+		latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
+		EasyMock.expectLastCall().once();
+		latch.start();
+		EasyMock.expectLastCall().once();
+		EasyMock.expect(latch.hasLeadership()).andReturn(true).anyTimes();
+		latch.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 {@link ZookeeperRegistry#getControllerForSwitch(long)} correctly returns controller ID of specific switch.
+	 * Relation between controllers and switches are defined by {@link ZookeeperRegistryTest#setPathChildrenCache()} function.
+	 * @throws Throwable
+	 */
+	@Test
+	public void testGetControllerForSwitch() throws Throwable {
+		long dpidRegistered = 1000L;
+		long dpidNotRegistered = 2000L;
+		
+		setPathChildrenCache();
+		
+		String controllerForSw = registry.getControllerForSwitch(dpidRegistered);
+		assertEquals("controller1",controllerForSw);
+
+		controllerForSw = registry.getControllerForSwitch(dpidNotRegistered);
+		assertEquals(null, controllerForSw);
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#getSwitchesControlledByController(String)} returns correct list of
+	 * switches controlled by a controller.
+	 * @throws Exception
+	 */
+	// TODO: Test after getSwitchesControlledByController() is implemented.
+	@Ignore @Test
+	public void testGetSwitchesControlledByController() throws Exception {
+		String controllerIdRegistered = "controller1";
+		String dpidRegistered = HexString.toHexString(1000L);
+		String controllerIdNotRegistered = CONTROLLER_ID;
+		
+		Collection<Long> switches = registry.getSwitchesControlledByController(controllerIdRegistered);
+		assertNotNull(switches);
+		assertTrue(switches.contains(dpidRegistered));
+
+		switches = registry.getSwitchesControlledByController(controllerIdNotRegistered);
+		assertNotNull(switches);
+		assertEquals(0, switches.size());
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#getAllSwitches()} returns correct list of all switches.
+	 * Switches are injected in {@link ZookeeperRegistryTest#setPathChildrenCache()} function.
+	 * @throws Exception
+	 */
+	@Test
+	public void testGetAllSwitches() throws Exception {
+		String [] dpids = {
+				HexString.toHexString(1000L),
+				HexString.toHexString(1001L),
+				HexString.toHexString(1002L),
+		};
+		
+		setPathChildrenCache();
+
+		Map<String, List<ControllerRegistryEntry>> switches = registry.getAllSwitches();
+		assertNotNull(switches);
+		assertEquals(dpids.length, switches.size());
+		for(String dpid : dpids) {
+			assertTrue(switches.keySet().contains(dpid));
+		}
+	}
+
+	/**
+	 * Test if {@link ZookeeperRegistry#allocateUniqueIdBlock()} can assign IdBlock without duplication.
+	 */
+	@Test
+	public void testAllocateUniqueIdBlock() {
+		// Number of blocks to be verified that any of them has unique block
+		final int NUM_BLOCKS = 100;
+		ArrayList<IdBlock> blocks = new ArrayList<IdBlock>(NUM_BLOCKS);
+		
+		for(int i = 0; i < NUM_BLOCKS; ++i) {
+			IdBlock block = registry.allocateUniqueIdBlock();
+			assertNotNull(block);
+			blocks.add(block);
+		}
+		
+		for(int i = 0; i < NUM_BLOCKS; ++i) {
+			IdBlock block1 = blocks.get(i);
+			for(int j = i + 1; j < NUM_BLOCKS; ++j) {
+				IdBlock block2 = blocks.get(j);
+				IdBlock lower,higher;
+				
+				if(block1.getStart() < block2.getStart()) {
+					lower = block1;
+					higher = block2;
+				} else {
+					lower = block2;
+					higher = block1;
+				}
+				
+				assertTrue(lower.getSize() > 0L);
+				assertTrue(higher.getSize() > 0L);
+				assertTrue(lower.getEnd() <= higher.getStart());
+			}
+		}
+	}
+	
+	
+	//-------------------------- Creation of mock objects --------------------------
+	/**
+	 * Create mock {@link CuratorFramework} object with initial value below.<br>
+	 *   [Ctrl ID]    : [DPID]<br>
+	 * controller1    :  1000<br>
+	 * controller2    :  1001<br>
+	 * controller2    :  1002<br>
+	 * controller2013 : nothing
+	 * @return Created mock object
+	 * @throws Exception
+	 */
+	@SuppressWarnings({ "serial", "unchecked" })
+	private CuratorFramework createCuratorFrameworkMock() throws Exception {
+		// Mock of AtomicValue
+		AtomicValue<Long> atomicValue = EasyMock.createMock(AtomicValue.class);
+		EasyMock.expect(atomicValue.succeeded()).andReturn(true).anyTimes();
+		EasyMock.expect(atomicValue.preValue()).andAnswer(new IAnswer<Long>() {
+			private long value = 0;
+			@Override
+			public Long answer() throws Throwable {
+				value += ID_BLOCK_SIZE;
+				return value;
+			}
+		}).anyTimes();
+		EasyMock.expect(atomicValue.postValue()).andAnswer(new IAnswer<Long>() {
+			private long value = ID_BLOCK_SIZE;
+			@Override
+			public Long answer() throws Throwable {
+				value += ID_BLOCK_SIZE;
+				return value;
+			}
+		}).anyTimes();
+		EasyMock.replay(atomicValue);
+		
+		// Mock DistributedAtomicLong
+		DistributedAtomicLong daLong = EasyMock.createMock(DistributedAtomicLong.class);
+		EasyMock.expect(daLong.add(EasyMock.anyLong())).andReturn(atomicValue).anyTimes();
+		EasyMock.replay(daLong);
+		PowerMock.expectNew(DistributedAtomicLong.class,
+				new Class<?> [] {CuratorFramework.class, String.class, RetryPolicy.class},
+				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(RetryPolicy.class)).
+				andReturn(daLong).anyTimes();
+		PowerMock.replay(DistributedAtomicLong.class);
+		
+		// Mock ListenerContainer
+		ListenerContainer<PathChildrenCacheListener> listenerContainer = EasyMock.createMock(ListenerContainer.class);
+		listenerContainer.addListener(EasyMock.anyObject(PathChildrenCacheListener.class));
+		EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+			@Override
+			public Object answer() throws Throwable {
+				pathChildrenCacheListener = (PathChildrenCacheListener)EasyMock.getCurrentArguments()[0];
+				return null;
+			}
+		}).once();
+		EasyMock.replay(listenerContainer);
+
+		// Mock PathChildrenCache
+		PathChildrenCache pathChildrenCacheMain = createPathChildrenCacheMock(CONTROLLER_ID, new String[] {"/switches"}, listenerContainer);
+		PathChildrenCache pathChildrenCache1 = createPathChildrenCacheMock("controller1", new String[] {HexString.toHexString(1000L)}, listenerContainer);
+		PathChildrenCache pathChildrenCache2 = createPathChildrenCacheMock("controller2", new String[] { 
+			HexString.toHexString(1001L), HexString.toHexString(1002L) },listenerContainer);
+		
+		// Mock PathChildrenCache constructor
+		PowerMock.expectNew(PathChildrenCache.class,
+				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
+				andReturn(pathChildrenCacheMain).once();
+		PowerMock.expectNew(PathChildrenCache.class,
+				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
+				andReturn(pathChildrenCache1).once();
+		PowerMock.expectNew(PathChildrenCache.class,
+				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
+				andReturn(pathChildrenCache2).anyTimes();
+		PowerMock.replay(PathChildrenCache.class);
+		
+		// Mock ServiceCache
+		ServiceCache<ControllerService> serviceCache = EasyMock.createMock(ServiceCache.class);
+		serviceCache.start();
+		EasyMock.expectLastCall().once();
+		EasyMock.expect(serviceCache.getInstances()).andReturn(new ArrayList<ServiceInstance<ControllerService> > () {{
+			add(createServiceInstanceMock("controller1"));
+			add(createServiceInstanceMock("controller2"));
+		}}).anyTimes();
+		EasyMock.replay(serviceCache);
+		
+		// Mock ServiceCacheBuilder
+		ServiceCacheBuilder<ControllerService> serviceCacheBuilder = EasyMock.createMock(ServiceCacheBuilder.class);
+		EasyMock.expect(serviceCacheBuilder.name(EasyMock.anyObject(String.class))).andReturn(serviceCacheBuilder).once();
+		EasyMock.expect(serviceCacheBuilder.build()).andReturn(serviceCache).once();
+		EasyMock.replay(serviceCacheBuilder);
+
+		// Mock ServiceDiscovery
+		ServiceDiscovery<ControllerService> serviceDiscovery = EasyMock.createMock(ServiceDiscovery.class);
+		serviceDiscovery.start();
+		EasyMock.expectLastCall().once();
+		EasyMock.expect(serviceDiscovery.serviceCacheBuilder()).andReturn(serviceCacheBuilder).once();
+		serviceDiscovery.registerService(EasyMock.anyObject(ServiceInstance.class));
+		EasyMock.expectLastCall().once();
+		EasyMock.replay(serviceDiscovery);
+		
+		// Mock CuratorFramework
+		CuratorFramework client = EasyMock.createMock(CuratorFramework.class);
+		client.start();
+		EasyMock.expectLastCall().once();
+		EasyMock.expect(client.usingNamespace(EasyMock.anyObject(String.class))).andReturn(client);
+		EasyMock.replay(client);
+
+		// Mock ServiceDiscoveryBuilder
+		ServiceDiscoveryBuilder<ControllerService> builder = EasyMock.createMock(ServiceDiscoveryBuilder.class);
+		EasyMock.expect(builder.client(client)).andReturn(builder).once();
+		EasyMock.expect(builder.basePath(EasyMock.anyObject(String.class))).andReturn(builder);
+		EasyMock.expect(builder.build()).andReturn(serviceDiscovery);
+		EasyMock.replay(builder);
+		
+		PowerMock.mockStatic(ServiceDiscoveryBuilder.class);
+		EasyMock.expect(ServiceDiscoveryBuilder.builder(ControllerService.class)).andReturn(builder).once();
+		PowerMock.replay(ServiceDiscoveryBuilder.class);
+
+		return client;
+	}
+	
+	/**
+	 * Create mock {@link ServiceInstance} object using given controller ID.
+	 * @param controllerId Controller ID to represent instance's payload (ControllerService).
+	 * @return Mock ServiceInstance object
+	 */
+	private ServiceInstance<ControllerService> createServiceInstanceMock(String controllerId) {
+		ControllerService controllerService = EasyMock.createMock(ControllerService.class);
+		EasyMock.expect(controllerService.getControllerId()).andReturn(controllerId).anyTimes();
+		EasyMock.replay(controllerService);
+		
+		@SuppressWarnings("unchecked")
+		ServiceInstance<ControllerService> serviceInstance = EasyMock.createMock(ServiceInstance.class);
+		EasyMock.expect(serviceInstance.getPayload()).andReturn(controllerService).anyTimes();
+		EasyMock.replay(serviceInstance);
+
+		return serviceInstance;
+	}
+	
+	/**
+	 * Create mock {@link PathChildrenCache} using given controller ID and DPIDs.
+	 * @param controllerId Controller ID to represent current data.
+	 * @param paths List of HexString indicating switch's DPID.
+	 * @param listener Callback object to be set as Listenable.
+	 * @return Mock PathChildrenCache object
+	 * @throws Exception
+	 */
+	private PathChildrenCache createPathChildrenCacheMock(final String controllerId, final String [] paths,
+			ListenerContainer<PathChildrenCacheListener> listener) throws Exception {
+		PathChildrenCache pathChildrenCache = EasyMock.createMock(PathChildrenCache.class);
+		
+		EasyMock.expect(pathChildrenCache.getListenable()).andReturn(listener).anyTimes();
+		
+		pathChildrenCache.start(EasyMock.anyObject(StartMode.class));
+		EasyMock.expectLastCall().anyTimes();
+		
+		List<ChildData> childs = new ArrayList<ChildData>();
+		for(String path : paths) {
+			childs.add(createChildDataMockForCurrentData(controllerId,path));
+		}
+		EasyMock.expect(pathChildrenCache.getCurrentData()).andReturn(childs).anyTimes();
+		
+		pathChildrenCache.rebuild();
+		EasyMock.expectLastCall().anyTimes();
+		
+		EasyMock.replay(pathChildrenCache);
+
+		return pathChildrenCache;
+	}
+	
+	/**
+	 * Create mock {@link ChildData} for {@link PathChildrenCache#getCurrentData()} return value.
+	 * This object need to include 'sequence number' in tail of path string. ("-0" means 0th sequence)
+	 * @param controllerId Controller ID
+	 * @param path HexString indicating switch's DPID
+	 * @return Mock ChildData object
+	 */
+	private ChildData createChildDataMockForCurrentData(String controllerId, String path) {
+		ChildData data = EasyMock.createMock(ChildData.class);
+		EasyMock.expect(data.getPath()).andReturn(path + "-0").anyTimes();
+		EasyMock.expect(data.getData()).andReturn(controllerId.getBytes()).anyTimes();
+		EasyMock.replay(data);
+		
+		return data;
+	}
+
+	/**
+	 * Inject relations between controllers and switches using callback object.
+	 * @throws Exception
+	 */
+	private void setPathChildrenCache() throws Exception {
+		pathChildrenCacheListener.childEvent(client,
+				createChildrenCacheEventMock("controller1", HexString.toHexString(1000L), PathChildrenCacheEvent.Type.CHILD_ADDED));
+		pathChildrenCacheListener.childEvent(client,
+				createChildrenCacheEventMock("controller2", HexString.toHexString(1001L), PathChildrenCacheEvent.Type.CHILD_ADDED));
+		pathChildrenCacheListener.childEvent(client,
+				createChildrenCacheEventMock("controller2", HexString.toHexString(1002L), PathChildrenCacheEvent.Type.CHILD_ADDED));
+	}
+
+	/**
+	 * Create mock {@link PathChildrenCacheEvent} object using given controller ID and DPID.
+	 * @param controllerId Controller ID.
+	 * @param path HexString of DPID.
+	 * @param type Event type to be set to mock object.
+	 * @return Mock PathChildrenCacheEvent object
+	 */
+	private PathChildrenCacheEvent createChildrenCacheEventMock(String controllerId, String path,
+			PathChildrenCacheEvent.Type type) {
+		PathChildrenCacheEvent event = EasyMock.createMock(PathChildrenCacheEvent.class);
+		ChildData data = EasyMock.createMock(ChildData.class);
+		
+		EasyMock.expect(data.getPath()).andReturn(path).anyTimes();
+		EasyMock.expect(data.getData()).andReturn(controllerId.getBytes()).anyTimes();
+		EasyMock.replay(data);
+		
+		EasyMock.expect(event.getType()).andReturn(type).anyTimes();
+		EasyMock.expect(event.getData()).andReturn(data).anyTimes();
+		EasyMock.replay(event);
+		
+		return event;
+	}
+}
diff --git a/start-cassandra.sh b/start-cassandra.sh
index 3bc62e4..426fa60 100755
--- a/start-cassandra.sh
+++ b/start-cassandra.sh
@@ -3,8 +3,8 @@
 # Set paths
 ONOS_HOME=`dirname $0`
 CASSANDRA_DIR=${HOME}/apache-cassandra-1.2.4
-LOGDIR=${HOME}/ONOS/onos-logs
-CASSANDRA_LOG=$LOGDIR/cassandara.`hostname`.log
+LOGDIR=${ONOS_HOME}/ONOS/onos-logs
+CASSANDRA_LOG=${LOGDIR}/cassandara.`hostname`.log
 
 function lotate {
     logfile=$1
@@ -30,7 +30,11 @@
 
   # Run cassandra 
   echo "Starting cassandra"
-  cp ${ONOS_HOME}/conf/cassandra.yaml $CASSANDRA_DIR/conf
+#  echo "[WARNING] This script copies conf/cassandra.yaml to $CASSANDRA_DIR/conf/cassandra.yaml (overwrites)"
+#  echo "original cassandra.yaml was backed up as cassandra.yaml.backup"
+#  id=`hostid`
+#  cp ${CASSANDRA_DIR}/conf/cassandra.yaml $CASSANDRA_DIR/conf/cassandra.yaml.backup
+#  cp ${ONOS_HOME}/conf/cassandra.yaml.${id} $CASSANDRA_DIR/conf
   $CASSANDRA_DIR/bin/cassandra > $CASSANDRA_LOG 2>&1 
 }
 
diff --git a/start-onos-embedded.sh b/start-onos-embedded.sh
index 5da4d9b..dac0331 100755
--- a/start-onos-embedded.sh
+++ b/start-onos-embedded.sh
@@ -14,9 +14,14 @@
 JVM_OPTS=""
 JVM_OPTS="$JVM_OPTS -server -d64"
 JVM_OPTS="$JVM_OPTS -Xmx2g -Xms2g -Xmn800m"
-JVM_OPTS="$JVM_OPTS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
+#JVM_OPTS="$JVM_OPTS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
+JVM_OPTS="$JVM_OPTS -XX:+UseConcMarkSweepGC -XX:+UseAdaptiveSizePolicy -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
 JVM_OPTS="$JVM_OPTS -XX:MaxInlineSize=8192 -XX:FreqInlineSize=8192"
 JVM_OPTS="$JVM_OPTS -XX:CompileThreshold=1500 -XX:PreBlockSpin=8 \
+		-XX:+UseThreadPriorities \
+		-XX:ThreadPriorityPolicy=42 \
+                 -XX:+UseCompressedOops \
+		-Dcassandra.compaction.priority=1 \
             -Dcom.sun.management.jmxremote.port=7199 \
               -Dcom.sun.management.jmxremote.ssl=false \
               -Dcom.sun.management.jmxremote.authenticate=false"
diff --git a/start-onos.sh b/start-onos.sh
index 667fd31..c356c87 100755
--- a/start-onos.sh
+++ b/start-onos.sh
@@ -4,6 +4,7 @@
 if [ -z "${ONOS_HOME}" ]; then
         ONOS_HOME=`dirname $0`
 fi
+
 ONOS_LOGBACK="${ONOS_HOME}/logback.xml"
 LOGDIR=${ONOS_HOME}/onos-logs
 ONOS_LOG="${LOGDIR}/onos.`hostname`.log"
@@ -16,17 +17,24 @@
 #JVM_OPTS="$JVM_OPTS -Xmx2g -Xms2g -Xmn800m"
 JVM_OPTS="$JVM_OPTS -Xmx1g -Xms1g -Xmn800m"
 #JVM_OPTS="$JVM_OPTS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
-JVM_OPTS="$JVM_OPTS -XX:+UseConcMarkSweepGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
+JVM_OPTS="$JVM_OPTS -XX:+UseConcMarkSweepGC -XX:+UseAdaptiveSizePolicy -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
 JVM_OPTS="$JVM_OPTS -XX:MaxInlineSize=8192 -XX:FreqInlineSize=8192"
 JVM_OPTS="$JVM_OPTS -XX:CompileThreshold=1500 -XX:PreBlockSpin=8"
 JVM_OPTS="$JVM_OPTS -XX:OnError=crash-logger" ;# For dumping core
 #JVM_OPTS="$JVM_OPTS -Dpython.security.respectJavaAccessibility=false"
+JVM_OPTS="$JVM_OPTS -XX:CompileThreshold=1500 -XX:PreBlockSpin=8 \
+		-XX:+UseThreadPriorities \
+		-XX:ThreadPriorityPolicy=42 \
+                 -XX:+UseCompressedOops \
+            -Dcom.sun.management.jmxremote.port=7189 \
+              -Dcom.sun.management.jmxremote.ssl=false \
+              -Dcom.sun.management.jmxremote.authenticate=false"
 
 # Set ONOS core main class
 MAIN_CLASS="net.onrc.onos.ofcontroller.core.Main"
 
 if [ -z "${MVN}" ]; then
-    MVN="mvn"
+    MVN="mvn -o"
 fi
 
 #<logger name="net.floodlightcontroller.linkdiscovery.internal" level="TRACE"/>
@@ -89,7 +97,8 @@
 
   # XXX : MVN has to run at the project top dir 
   cd ${ONOS_HOME}
-  ${MVN} exec:exec -Dexec.executable="java" -Dexec.args="${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -cp %classpath ${MAIN_CLASS} -cf ${ONOS_HOME}/conf/onos.properties" > ${LOGDIR}/onos.stdout 2>${LOGDIR}/onos.stderr &
+  echo "${MVN} exec:exec -Dexec.executable=\"java\" -Dexec.args=\"${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -cp %classpath ${MAIN_CLASS} -cf ${ONOS_HOME}/conf/onos.properties\""
+  ${MVN} exec:exec -Dexec.executable="java" -Dexec.args="${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -cp %classpath ${MAIN_CLASS} -cf ${ONOS_HOME}/conf/onos.properties" > ${LOGDIR}/onos.`hostname`.stdout 2>${LOGDIR}/onos.`hostname`.stderr &
 
   echo "Waiting for ONOS to start..."
   COUNT=0
@@ -117,7 +126,7 @@
   for p in ${pids}; do
     if [ x$p != "x" ]; then
       kill -KILL $p
-      echo "Killed existing prosess (pid: $p)"
+      echo "Killed existing process (pid: $p)"
     fi
   done
 }
diff --git a/start-zk.sh b/start-zk.sh
index 4e1134e..0853a96 100755
--- a/start-zk.sh
+++ b/start-zk.sh
@@ -3,13 +3,19 @@
 
 ONOS_HOME=`dirname $0`
 ZK_DIR=${HOME}/zookeeper-3.4.5
-ZK_CONF=${ONOS_HOME}/conf/zoo.cfg
+#ZK_CONF=${ONOS_HOME}/conf/zoo.cfg
 
 function start {
   # Run Zookeeper with our configuration
   echo "Starting Zookeeper"
-  cp $ZK_CONF $ZK_DIR/conf
-  echo "cp $ZK_CONF $ZK_DIR/conf"
+#  echo "[WARNING] This script copies conf/zoo.cfg to $ZK_DIR/conf/zoo.cfg (overwrites)"
+#  echo "original zoo.cfg was backed up as zoo.cfg.backup"
+#  if [ $ZK_DIR/conf/zoo.cfg ]; then
+#    cp $ZK_DIR/conf/zoo.cfg $ZK_DIR/conf/zoo.cfg.backup
+#  fi
+#  hostid > /var/lib/zookeeper/myid
+#  cp $ZK_CONF $ZK_DIR/conf
+#  echo "cp $ZK_CONF $ZK_DIR/conf"
   $ZK_DIR/bin/zkServer.sh start
 }
 
@@ -24,7 +30,7 @@
   done
 }
 function status {
-  $ZK_DIR/bin/zkServer.sh status $ZK_CONF
+  $ZK_DIR/bin/zkServer.sh status
 }
 
 case "$1" in
diff --git a/titan/schema/test-network.xml b/titan/schema/test-network.xml
index 5c63d90..630c5da 100644
--- a/titan/schema/test-network.xml
+++ b/titan/schema/test-network.xml
@@ -3,6 +3,7 @@
 
     <key id="id" for="node" attr.name="id" attr.type="string"></key>
     <key id="type" for="node" attr.name="type" attr.type="string"></key>
+    <key id="state" for="node" attr.name="state" attr.type="string"></key>
     <key id="dpid" for="node" attr.name="dpid" attr.type="string"></key>
     <key id="desc" for="node" attr.name="desc" attr.type="string"></key>
     <key id="number" for="node" attr.name="number" attr.type="int"></key>
@@ -17,31 +18,37 @@
         <node id="1">
             <data key="type">switch</data>
             <data key="dpid">00:00:00:00:00:00:0a:01</data>
+            <data key="state">ACTIVE</data>
             <data key="desc">OpenFlow Switch at SEA</data>
         </node>
         <node id="2">
             <data key="type">switch</data>
             <data key="dpid">00:00:00:00:00:00:0a:02</data>
+            <data key="state">ACTIVE</data>
             <data key="desc">OpenFlow Switch at LAX</data>
         </node>
         <node id="3">
             <data key="type">switch</data>
             <data key="dpid">00:00:00:00:00:00:0a:03</data>
+            <data key="state">ACTIVE</data>
             <data key="desc">OpenFlow Switch at CHI</data>
         </node>
         <node id="4">
             <data key="type">switch</data>
             <data key="dpid">00:00:00:00:00:00:0a:04</data>
+            <data key="state">ACTIVE</data>
             <data key="desc">OpenFlow Switch at IAH</data>
         </node>
         <node id="5">
             <data key="type">switch</data>
             <data key="dpid">00:00:00:00:00:00:0a:05</data>
+            <data key="state">ACTIVE</data>
             <data key="desc">OpenFlow Switch at NYC</data>
         </node>
         <node id="6">
             <data key="type">switch</data>
             <data key="dpid">00:00:00:00:00:00:0a:06</data>
+            <data key="state">ACTIVE</data>
             <data key="desc">OpenFlow Switch at ATL</data>
         </node>
 
diff --git a/web/config.json.devA b/web/config.json.devA
new file mode 100644
index 0000000..b20639e
--- /dev/null
+++ b/web/config.json.devA
@@ -0,0 +1,22 @@
+{
+    "LB": false, 
+    "TESTBED": "sw",
+    "ONOS_DEFAULT_HOST": "localhost",
+    "ONOS_GUI3_CONTROL_HOST": "http://10.128.4.51:9000", 
+    "ONOS_GUI3_HOST": "http://10.128.4.51:9000", 
+    "cluster_basename": "ONOS", 
+    "controllers": [
+        "DevA-ONOS1", 
+        "DevA-ONOS2", 
+        "DevA-ONOS3", 
+        "DevA-ONOS4" 
+    ], 
+ "core_switches": [
+        "00:00:00:00:ba:5e:ba:11", 
+        "00:00:00:00:00:00:ba:12", 
+        "00:00:20:4e:7f:51:8a:35", 
+        "00:00:00:00:ba:5e:ba:13", 
+        "00:00:00:08:a2:08:f9:01", 
+        "00:00:00:16:97:08:9a:46"
+    ]
+}
diff --git a/web/ons-demo/data/configuration.json.devA b/web/ons-demo/data/configuration.json.devA
new file mode 100644
index 0000000..f8a6e63
--- /dev/null
+++ b/web/ons-demo/data/configuration.json.devA
@@ -0,0 +1,78 @@
+{
+	"core": [
+		"00:00:00:08:a2:08:f9:01",
+		"00:00:00:00:ba:5e:ba:11",
+		"00:00:20:4e:7f:51:8a:35",
+		"00:00:00:00:00:00:ba:12",
+		"00:00:00:00:ba:5e:ba:13",
+		"00:00:00:16:97:08:9a:46"
+	],
+	"aggregation": [
+		"00:00:00:00:00:00:02:01",
+		"00:00:00:00:00:00:03:01",
+		"00:00:00:00:00:00:04:01",
+		"00:00:00:00:00:00:05:01",
+		"00:00:00:00:00:00:06:01",
+		"00:00:00:00:00:00:07:01",
+		"00:00:00:00:00:00:08:01"
+	],
+	"association": {
+		"00:00:20:4e:7f:51:8a:35": [
+			"00:00:00:00:00:00:07:01"
+		],
+		"00:00:00:00:ba:5e:ba:13": [
+			"00:00:00:00:00:00:06:01"
+		],
+		"00:00:00:08:a2:08:f9:01": [
+			"00:00:00:00:00:00:03:01"
+		],
+		"00:00:00:00:00:00:ba:12": [
+			"00:00:00:00:00:00:04:01",
+			"00:00:00:00:00:00:05:01"
+		],
+		"00:00:00:00:ba:5e:ba:11": [
+			"00:00:00:00:00:00:02:01"
+		],
+		"00:00:00:16:97:08:9a:46": [
+			"00:00:00:00:00:00:08:01"
+		]
+	},
+	"geo": {
+		"00:00:20:4e:7f:51:8a:35": {
+			"lat": 41.891033,
+			"lng": -87.628326,
+			"label": "CHI",
+			"fanOutAngle": 180
+		},
+		"00:00:00:00:ba:5e:ba:13": {
+			"lat": 47.611024,
+			"lng": -122.33242,
+			"label": "SEA",
+			"fanOutAngle": 270
+		},
+		"00:00:00:08:a2:08:f9:01": {
+			"lat": 33.758599,
+			"lng": -84.387360,
+			"label": "ATL",
+			"fanOutAngle": 5
+		},
+		"00:00:00:16:97:08:9a:46": {
+			"lat": 41.225925,
+			"lng": -74.00528,
+			"label": "NYC",
+			"fanOutAngle": 150
+		},
+		"00:00:00:00:ba:5e:ba:11": {
+			"lat": 37.901187,
+			"lng": -76.037163,
+			"label": "DC",
+			"fanOutAngle": 45
+		},
+		"00:00:00:00:00:00:ba:12": {
+			"lat": 34.102708,
+			"lng": -118.238983,
+			"label": "LA",
+			"fanOutAngle": 315
+		}
+	}
+}