diff --git a/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java b/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
index 6483121..c195f82 100644
--- a/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
+++ b/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
@@ -21,10 +21,12 @@
 import net.onrc.onos.ofcontroller.proxyarp.ArpMessage;
 import net.onrc.onos.ofcontroller.proxyarp.IArpEventHandler;
 import net.onrc.onos.ofcontroller.topology.TopologyElement;
+import net.onrc.onos.ofcontroller.util.Dpid;
 import net.onrc.onos.ofcontroller.util.FlowEntry;
 import net.onrc.onos.ofcontroller.util.FlowEntryId;
 import net.onrc.onos.ofcontroller.util.FlowId;
 import net.onrc.onos.ofcontroller.util.FlowPath;
+import net.onrc.onos.ofcontroller.util.Pair;
 import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
 
 import org.slf4j.Logger;
@@ -73,12 +75,24 @@
     private MapFlowEntryListener mapFlowEntryListener = null;
     private String mapFlowEntryListenerId = null;
 
+    // State related to the Flow ID map
+    protected static final String mapFlowIdName = "mapFlowId";
+    private IMap<Long, byte[]> mapFlowId = null;
+    private MapFlowIdListener mapFlowIdListener = null;
+    private String mapFlowIdListenerId = null;
+
+    // State related to the Flow Entry ID map
+    protected static final String mapFlowEntryIdName = "mapFlowEntryId";
+    private IMap<Long, byte[]> mapFlowEntryId = null;
+    private MapFlowEntryIdListener mapFlowEntryIdListener = null;
+    private String mapFlowEntryIdListenerId = null;
+
     // State related to the Network Topology map
     protected static final String mapTopologyName = "mapTopology";
     private IMap<String, byte[]> mapTopology = null;
     private MapTopologyListener mapTopologyListener = null;
     private String mapTopologyListenerId = null;
-    
+
     // State related to the ARP map
     protected static final String arpMapName = "arpMap";
     private IMap<ArpMessage, byte[]> arpMap = null;
@@ -98,8 +112,9 @@
 	 *
 	 * @param event the notification event for the entry.
 	 */
+	@Override
 	public void entryAdded(EntryEvent<Long, byte[]> event) {
-	    byte[] valueBytes = (byte[])event.getValue();
+	    byte[] valueBytes = event.getValue();
 
 	    //
 	    // Decode the value and deliver the notification
@@ -116,8 +131,9 @@
 	 *
 	 * @param event the notification event for the entry.
 	 */
+	@Override
 	public void entryRemoved(EntryEvent<Long, byte[]> event) {
-	    byte[] valueBytes = (byte[])event.getValue();
+	    byte[] valueBytes = event.getValue();
 
 	    //
 	    // Decode the value and deliver the notification
@@ -134,8 +150,9 @@
 	 *
 	 * @param event the notification event for the entry.
 	 */
+	@Override
 	public void entryUpdated(EntryEvent<Long, byte[]> event) {
-	    byte[] valueBytes = (byte[])event.getValue();
+	    byte[] valueBytes = event.getValue();
 
 	    //
 	    // Decode the value and deliver the notification
@@ -152,6 +169,7 @@
 	 *
 	 * @param event the notification event for the entry.
 	 */
+	@Override
 	public void entryEvicted(EntryEvent<Long, byte[]> event) {
 	    // NOTE: We don't use eviction for this map
 	}
@@ -170,8 +188,9 @@
 	 *
 	 * @param event the notification event for the entry.
 	 */
+	@Override
 	public void entryAdded(EntryEvent<Long, byte[]> event) {
-	    byte[] valueBytes = (byte[])event.getValue();
+	    byte[] valueBytes = event.getValue();
 
 	    //
 	    // Decode the value and deliver the notification
@@ -188,8 +207,9 @@
 	 *
 	 * @param event the notification event for the entry.
 	 */
+	@Override
 	public void entryRemoved(EntryEvent<Long, byte[]> event) {
-	    byte[] valueBytes = (byte[])event.getValue();
+	    byte[] valueBytes = event.getValue();
 
 	    //
 	    // Decode the value and deliver the notification
@@ -206,8 +226,9 @@
 	 *
 	 * @param event the notification event for the entry.
 	 */
+	@Override
 	public void entryUpdated(EntryEvent<Long, byte[]> event) {
-	    byte[] valueBytes = (byte[])event.getValue();
+	    byte[] valueBytes = event.getValue();
 
 	    //
 	    // Decode the value and deliver the notification
@@ -224,6 +245,169 @@
 	 *
 	 * @param event the notification event for the entry.
 	 */
+	@Override
+	public void entryEvicted(EntryEvent<Long, byte[]> event) {
+	    // NOTE: We don't use eviction for this map
+	}
+    }
+
+    /**
+     * Class for receiving notifications for FlowId state.
+     *
+     * The datagrid map is:
+     *  - Key : FlowId (Long)
+     *  - Value : Serialized Switch Dpid (byte[])
+     */
+    class MapFlowIdListener implements EntryListener<Long, byte[]> {
+	/**
+	 * Receive a notification that an entry is added.
+	 *
+	 * @param event the notification event for the entry.
+	 */
+	public void entryAdded(EntryEvent<Long, byte[]> event) {
+	    Long keyLong = event.getKey();
+	    FlowId flowId = new FlowId(keyLong);
+
+	    byte[] valueBytes = event.getValue();
+
+	    //
+	    // Decode the value and deliver the notification
+	    //
+	    Kryo kryo = kryoFactory.newKryo();
+	    Input input = new Input(valueBytes);
+	    Dpid dpid = kryo.readObject(input, Dpid.class);
+	    kryoFactory.deleteKryo(kryo);
+	    flowEventHandlerService.notificationRecvFlowIdAdded(flowId, dpid);
+	}
+
+	/**
+	 * Receive a notification that an entry is removed.
+	 *
+	 * @param event the notification event for the entry.
+	 */
+	public void entryRemoved(EntryEvent<Long, byte[]> event) {
+	    Long keyLong = event.getKey();
+	    FlowId flowId = new FlowId(keyLong);
+
+	    byte[] valueBytes = event.getValue();
+
+	    //
+	    // Decode the value and deliver the notification
+	    //
+	    Kryo kryo = kryoFactory.newKryo();
+	    Input input = new Input(valueBytes);
+	    Dpid dpid = kryo.readObject(input, Dpid.class);
+	    kryoFactory.deleteKryo(kryo);
+	    flowEventHandlerService.notificationRecvFlowIdRemoved(flowId, dpid);
+	}
+
+	/**
+	 * Receive a notification that an entry is updated.
+	 *
+	 * @param event the notification event for the entry.
+	 */
+	public void entryUpdated(EntryEvent<Long, byte[]> event) {
+	    Long keyLong = event.getKey();
+	    FlowId flowId = new FlowId(keyLong);
+
+	    byte[] valueBytes = event.getValue();
+
+	    //
+	    // Decode the value and deliver the notification
+	    //
+	    Kryo kryo = kryoFactory.newKryo();
+	    Input input = new Input(valueBytes);
+	    Dpid dpid = kryo.readObject(input, Dpid.class);
+	    kryoFactory.deleteKryo(kryo);
+	    flowEventHandlerService.notificationRecvFlowIdUpdated(flowId, dpid);
+	}
+
+	/**
+	 * Receive a notification that an entry is evicted.
+	 *
+	 * @param event the notification event for the entry.
+	 */
+	public void entryEvicted(EntryEvent<Long, byte[]> event) {
+	    // NOTE: We don't use eviction for this map
+	}
+    }
+
+    /**
+     * Class for receiving notifications for FlowEntryId state.
+     *
+     * The datagrid map is:
+     *  - Key : FlowEntryId (Long)
+     *  - Value : Serialized Switch Dpid (byte[])
+     */
+    class MapFlowEntryIdListener implements EntryListener<Long, byte[]> {
+	/**
+	 * Receive a notification that an entry is added.
+	 *
+	 * @param event the notification event for the entry.
+	 */
+	public void entryAdded(EntryEvent<Long, byte[]> event) {
+	    Long keyLong = event.getKey();
+	    FlowEntryId flowEntryId = new FlowEntryId(keyLong);
+
+	    byte[] valueBytes = event.getValue();
+
+	    //
+	    // Decode the value and deliver the notification
+	    //
+	    Kryo kryo = kryoFactory.newKryo();
+	    Input input = new Input(valueBytes);
+	    Dpid dpid = kryo.readObject(input, Dpid.class);
+	    kryoFactory.deleteKryo(kryo);
+	    flowEventHandlerService.notificationRecvFlowEntryIdAdded(flowEntryId, dpid);
+	}
+
+	/**
+	 * Receive a notification that an entry is removed.
+	 *
+	 * @param event the notification event for the entry.
+	 */
+	public void entryRemoved(EntryEvent<Long, byte[]> event) {
+	    Long keyLong = event.getKey();
+	    FlowEntryId flowEntryId = new FlowEntryId(keyLong);
+
+	    byte[] valueBytes = event.getValue();
+
+	    //
+	    // Decode the value and deliver the notification
+	    //
+	    Kryo kryo = kryoFactory.newKryo();
+	    Input input = new Input(valueBytes);
+	    Dpid dpid = kryo.readObject(input, Dpid.class);
+	    kryoFactory.deleteKryo(kryo);
+	    flowEventHandlerService.notificationRecvFlowEntryIdRemoved(flowEntryId, dpid);
+	}
+
+	/**
+	 * Receive a notification that an entry is updated.
+	 *
+	 * @param event the notification event for the entry.
+	 */
+	public void entryUpdated(EntryEvent<Long, byte[]> event) {
+	    Long keyLong = event.getKey();
+	    FlowEntryId flowEntryId = new FlowEntryId(keyLong);
+
+	    byte[] valueBytes = event.getValue();
+
+	    //
+	    // Decode the value and deliver the notification
+	    //
+	    Kryo kryo = kryoFactory.newKryo();
+	    Input input = new Input(valueBytes);
+	    Dpid dpid = kryo.readObject(input, Dpid.class);
+	    kryoFactory.deleteKryo(kryo);
+	    flowEventHandlerService.notificationRecvFlowEntryIdUpdated(flowEntryId, dpid);
+	}
+
+	/**
+	 * Receive a notification that an entry is evicted.
+	 *
+	 * @param event the notification event for the entry.
+	 */
 	public void entryEvicted(EntryEvent<Long, byte[]> event) {
 	    // NOTE: We don't use eviction for this map
 	}
@@ -242,8 +426,9 @@
 	 *
 	 * @param event the notification event for the entry.
 	 */
+	@Override
 	public void entryAdded(EntryEvent<String, byte[]> event) {
-	    byte[] valueBytes = (byte[])event.getValue();
+	    byte[] valueBytes = event.getValue();
 
 	    //
 	    // Decode the value and deliver the notification
@@ -261,8 +446,9 @@
 	 *
 	 * @param event the notification event for the entry.
 	 */
+	@Override
 	public void entryRemoved(EntryEvent<String, byte[]> event) {
-	    byte[] valueBytes = (byte[])event.getValue();
+	    byte[] valueBytes = event.getValue();
 
 	    //
 	    // Decode the value and deliver the notification
@@ -280,8 +466,9 @@
 	 *
 	 * @param event the notification event for the entry.
 	 */
+	@Override
 	public void entryUpdated(EntryEvent<String, byte[]> event) {
-	    byte[] valueBytes = (byte[])event.getValue();
+	    byte[] valueBytes = event.getValue();
 
 	    //
 	    // Decode the value and deliver the notification
@@ -299,11 +486,12 @@
 	 *
 	 * @param event the notification event for the entry.
 	 */
+	@Override
 	public void entryEvicted(EntryEvent<String, byte[]> event) {
 	    // NOTE: We don't use eviction for this map
 	}
     }
-    
+
     /**
      * Class for receiving notifications for ARP requests.
      *
@@ -317,11 +505,12 @@
 		 *
 		 * @param event the notification event for the entry.
 		 */
+		@Override
 		public void entryAdded(EntryEvent<ArpMessage, byte[]> event) {
 		    for (IArpEventHandler arpEventHandler : arpEventHandlers) {
 		    	arpEventHandler.arpRequestNotification(event.getKey());
 		    }
-		    
+
 		    //
 		    // Decode the value and deliver the notification
 		    //
@@ -334,30 +523,33 @@
 		    flowEventHandlerService.notificationRecvTopologyElementAdded(topologyElement);
 		    */
 		}
-	
+
 		/**
 		 * Receive a notification that an entry is removed.
 		 *
 		 * @param event the notification event for the entry.
 		 */
+		@Override
 		public void entryRemoved(EntryEvent<ArpMessage, byte[]> event) {
 			// Not used
 		}
-	
+
 		/**
 		 * Receive a notification that an entry is updated.
 		 *
 		 * @param event the notification event for the entry.
 		 */
+		@Override
 		public void entryUpdated(EntryEvent<ArpMessage, byte[]> event) {
 			// Not used
 		}
-	
+
 		/**
 		 * Receive a notification that an entry is evicted.
 		 *
 		 * @param event the notification event for the entry.
 		 */
+		@Override
 		public void entryEvicted(EntryEvent<ArpMessage, byte[]> event) {
 		    // Not used
 		}
@@ -374,7 +566,7 @@
 	System.setProperty("hazelcast.socket.send.buffer.size", "32");
 	*/
 	// System.setProperty("hazelcast.heartbeat.interval.seconds", "100");
-	
+
 	// Init from configuration file
 	try {
 	    hazelcastConfig = new FileSystemXmlConfig(configFilename);
@@ -395,7 +587,8 @@
     /**
      * Shutdown the Hazelcast Datagrid operation.
      */
-    public void finalize() {
+    @Override
+    protected void finalize() {
 	close();
     }
 
@@ -413,7 +606,7 @@
      */
     @Override
     public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-        Collection<Class<? extends IFloodlightService>> l = 
+        Collection<Class<? extends IFloodlightService>> l =
             new ArrayList<Class<? extends IFloodlightService>>();
         l.add(IDatagridService.class);
         return l;
@@ -425,10 +618,10 @@
      * @return the collection of implemented services.
      */
     @Override
-    public Map<Class<? extends IFloodlightService>, IFloodlightService> 
+    public Map<Class<? extends IFloodlightService>, IFloodlightService>
 			       getServiceImpls() {
         Map<Class<? extends IFloodlightService>,
-	    IFloodlightService> m = 
+	    IFloodlightService> m =
             new HashMap<Class<? extends IFloodlightService>,
                 IFloodlightService>();
         m.put(IDatagridService.class, this);
@@ -441,7 +634,7 @@
      * @return the collection of modules this module depends on.
      */
     @Override
-    public Collection<Class<? extends IFloodlightService>> 
+    public Collection<Class<? extends IFloodlightService>>
                                                     getModuleDependencies() {
 	Collection<Class<? extends IFloodlightService>> l =
 	    new ArrayList<Class<? extends IFloodlightService>>();
@@ -477,7 +670,7 @@
 	hazelcastInstance = Hazelcast.newHazelcastInstance(hazelcastConfig);
 
 	restApi.addRestletRoutable(new DatagridWebRoutable());
-	
+
 	arpMap = hazelcastInstance.getMap(arpMapName);
 	arpMap.addEntryListener(new ArpMapListener(), true);
     }
@@ -504,6 +697,16 @@
 	mapFlowEntry = hazelcastInstance.getMap(mapFlowEntryName);
 	mapFlowEntryListenerId = mapFlowEntry.addEntryListener(mapFlowEntryListener, true);
 
+	// Initialize the FlowId-related map state
+	mapFlowIdListener = new MapFlowIdListener();
+	mapFlowId = hazelcastInstance.getMap(mapFlowIdName);
+	mapFlowIdListenerId = mapFlowId.addEntryListener(mapFlowIdListener, true);
+
+	// Initialize the FlowEntryId-related map state
+	mapFlowEntryIdListener = new MapFlowEntryIdListener();
+	mapFlowEntryId = hazelcastInstance.getMap(mapFlowEntryIdName);
+	mapFlowEntryIdListenerId = mapFlowEntryId.addEntryListener(mapFlowEntryIdListener, true);
+
 	// Initialize the Topology-related map state
 	mapTopologyListener = new MapTopologyListener();
 	mapTopology = hazelcastInstance.getMap(mapTopologyName);
@@ -531,6 +734,16 @@
 	mapFlowEntry = null;
 	mapFlowEntryListener = null;
 
+	// Clear the FlowId-related map state
+	mapFlowId.removeEntryListener(mapFlowIdListenerId);
+	mapFlowId = null;
+	mapFlowIdListener = null;
+
+	// Clear the FlowEntryId-related map state
+	mapFlowEntryId.removeEntryListener(mapFlowEntryIdListenerId);
+	mapFlowEntryId = null;
+	mapFlowEntryIdListener = null;
+
 	// Clear the Topology-related map state
 	mapTopology.removeEntryListener(mapTopologyListenerId);
 	mapTopology = null;
@@ -538,19 +751,19 @@
 
 	this.flowEventHandlerService = null;
     }
-    
+
     @Override
     public void registerArpEventHandler(IArpEventHandler arpEventHandler) {
     	if (arpEventHandler != null) {
     		arpEventHandlers.add(arpEventHandler);
     	}
     }
-    
+
     @Override
     public void deregisterArpEventHandler(IArpEventHandler arpEventHandler) {
     	arpEventHandlers.remove(arpEventHandler);
     }
-    
+
     /**
      * Get all Flows that are currently in the datagrid.
      *
@@ -788,6 +1001,216 @@
     }
 
     /**
+     * Get all Flow IDs that are currently in the datagrid.
+     *
+     * @return all Flow IDs that are currently in the datagrid.
+     */
+    @Override
+	public Collection<Pair<FlowId, Dpid>> getAllFlowIds() {
+	Collection<Pair<FlowId, Dpid>> allFlowIds =
+	    new LinkedList<Pair<FlowId, Dpid>>();
+
+	//
+	// Get all current entries
+	//
+	Kryo kryo = kryoFactory.newKryo();
+	for (Map.Entry<Long, byte[]> entry : mapFlowId.entrySet()) {
+	    Long key = entry.getKey();
+	    byte[] valueBytes = entry.getValue();
+
+	    FlowId flowId = new FlowId(key);
+
+	    //
+	    // Decode the value
+	    //
+	    Input input = new Input(valueBytes);
+	    Dpid dpid = kryo.readObject(input, Dpid.class);
+
+	    Pair<FlowId, Dpid> pair = new Pair(flowId, dpid);
+	    allFlowIds.add(pair);
+	}
+	kryoFactory.deleteKryo(kryo);
+
+	return allFlowIds;
+    }
+
+    /**
+     * Get all Flow Entry IDs that are currently in the datagrid.
+     *
+     * @return all Flow Entry IDs that ae currently in the datagrid.
+     */
+    @Override
+    public Collection<Pair<FlowEntryId, Dpid>> getAllFlowEntryIds() {
+	Collection<Pair<FlowEntryId, Dpid>> allFlowEntryIds =
+	    new LinkedList<Pair<FlowEntryId, Dpid>>();
+
+	//
+	// Get all current entries
+	//
+	Kryo kryo = kryoFactory.newKryo();
+	for (Map.Entry<Long, byte[]> entry : mapFlowEntryId.entrySet()) {
+	    Long key = entry.getKey();
+	    byte[] valueBytes = entry.getValue();
+
+	    FlowEntryId flowEntryId = new FlowEntryId(key);
+
+	    //
+	    // Decode the value
+	    //
+	    Input input = new Input(valueBytes);
+	    Dpid dpid = kryo.readObject(input, Dpid.class);
+
+	    Pair<FlowEntryId, Dpid> pair = new Pair(flowEntryId, dpid);
+	    allFlowEntryIds.add(pair);
+	}
+	kryoFactory.deleteKryo(kryo);
+
+	return allFlowEntryIds;
+    }
+
+    /**
+     * Send a notification that a FlowId is added.
+     *
+     * @param flowId the FlowId that is added.
+     * @param dpid the Source Switch Dpid.
+     */
+    @Override
+    public void notificationSendFlowIdAdded(FlowId flowId, Dpid dpid) {
+	//
+	// Encode the value
+	//
+	byte[] buffer = new byte[MAX_BUFFER_SIZE];
+	Kryo kryo = kryoFactory.newKryo();
+	Output output = new Output(buffer, -1);
+	kryo.writeObject(output, dpid);
+	byte[] valueBytes = output.toBytes();
+	kryoFactory.deleteKryo(kryo);
+
+	//
+	// Put the entry:
+	//  - Key : FlowId (Long)
+	//  - Value : Serialized Switch Dpid (byte[])
+	//
+	mapFlowId.putAsync(flowId.value(), valueBytes);
+    }
+
+    /**
+     * Send a notification that a FlowId is removed.
+     *
+     * @param flowId the FlowId that is removed.
+     */
+    @Override
+    public void notificationSendFlowIdRemoved(FlowId flowId) {
+	//
+	// Remove the entry:
+	//  - Key : FlowId (Long)
+	//  - Value : Serialized Switch Dpid (byte[])
+	//
+	mapFlowId.removeAsync(flowId.value());
+    }
+
+    /**
+     * Send a notification that a FlowId is updated.
+     *
+     * @param flowId the FlowId that is updated.
+     * @param dpid the Source Switch Dpid.
+     */
+    @Override
+    public void notificationSendFlowIdUpdated(FlowId flowId, Dpid dpid) {
+	// NOTE: Adding an entry with an existing key automatically updates it
+	notificationSendFlowIdAdded(flowId, dpid);
+    }
+
+    /**
+     * Send a notification that all Flow IDs are removed.
+     */
+    @Override
+    public void notificationSendAllFlowIdsRemoved() {
+	//
+	// Remove all entries
+	// NOTE: We remove the entries one-by-one so the per-entry
+	// notifications will be delivered.
+	//
+	// mapFlowId.clear();
+	Set<Long> keySet = mapFlowId.keySet();
+	for (Long key : keySet) {
+	    mapFlowId.removeAsync(key);
+	}
+    }
+
+    /**
+     * Send a notification that a FlowEntryId is added.
+     *
+     * @param flowEntryId the FlowEntryId that is added.
+     * @param dpid the Switch Dpid.
+     */
+    @Override
+    public void notificationSendFlowEntryIdAdded(FlowEntryId flowEntryId,
+						 Dpid dpid) {
+	//
+	// Encode the value
+	//
+	byte[] buffer = new byte[MAX_BUFFER_SIZE];
+	Kryo kryo = kryoFactory.newKryo();
+	Output output = new Output(buffer, -1);
+	kryo.writeObject(output, dpid);
+	byte[] valueBytes = output.toBytes();
+	kryoFactory.deleteKryo(kryo);
+
+	//
+	// Put the entry:
+	//  - Key : FlowEntryId (Long)
+	//  - Value : Serialized Switch Dpid (byte[])
+	//
+	mapFlowEntryId.putAsync(flowEntryId.value(), valueBytes);
+    }
+
+    /**
+     * Send a notification that a FlowEntryId is removed.
+     *
+     * @param flowEntryId the FlowEntryId that is removed.
+     */
+    @Override
+    public void notificationSendFlowEntryIdRemoved(FlowEntryId flowEntryId) {
+	//
+	// Remove the entry:
+	//  - Key : FlowEntryId (Long)
+	//  - Value : Serialized Switch Dpid (byte[])
+	//
+	mapFlowEntryId.removeAsync(flowEntryId.value());
+    }
+
+    /**
+     * Send a notification that a FlowEntryId is updated.
+     *
+     * @param flowEntryId the FlowEntryId that is updated.
+     * @param dpid the Switch Dpid.
+     */
+    @Override
+    public void notificationSendFlowEntryIdUpdated(FlowEntryId flowEntryId,
+						   Dpid dpid) {
+	// NOTE: Adding an entry with an existing key automatically updates it
+	notificationSendFlowEntryIdAdded(flowEntryId, dpid);
+    }
+
+    /**
+     * Send a notification that all Flow Entry IDs are removed.
+     */
+    @Override
+    public void notificationSendAllFlowEntryIdsRemoved() {
+	//
+	// Remove all entries
+	// NOTE: We remove the entries one-by-one so the per-entry
+	// notifications will be delivered.
+	//
+	// mapFlowEntryId.clear();
+	Set<Long> keySet = mapFlowEntryId.keySet();
+	for (Long key : keySet) {
+	    mapFlowEntryId.removeAsync(key);
+	}
+    }
+
+    /**
      * Get all Topology Elements that are currently in the datagrid.
      *
      * @return all Topology Elements that are currently in the datagrid.
@@ -883,7 +1306,7 @@
 	    mapTopology.removeAsync(key);
 	}
     }
-    
+
     @Override
     public void sendArpRequest(ArpMessage arpMessage) {
     	//log.debug("ARP bytes: {}", HexString.toHexString(arpRequest));
diff --git a/src/main/java/net/onrc/onos/datagrid/IDatagridService.java b/src/main/java/net/onrc/onos/datagrid/IDatagridService.java
index 0f03d77..a855798 100644
--- a/src/main/java/net/onrc/onos/datagrid/IDatagridService.java
+++ b/src/main/java/net/onrc/onos/datagrid/IDatagridService.java
@@ -7,10 +7,12 @@
 import net.onrc.onos.ofcontroller.proxyarp.ArpMessage;
 import net.onrc.onos.ofcontroller.proxyarp.IArpEventHandler;
 import net.onrc.onos.ofcontroller.topology.TopologyElement;
+import net.onrc.onos.ofcontroller.util.Dpid;
 import net.onrc.onos.ofcontroller.util.FlowEntry;
 import net.onrc.onos.ofcontroller.util.FlowEntryId;
 import net.onrc.onos.ofcontroller.util.FlowId;
 import net.onrc.onos.ofcontroller.util.FlowPath;
+import net.onrc.onos.ofcontroller.util.Pair;
 
 /**
  * Interface for providing Datagrid Service to other modules.
@@ -134,6 +136,77 @@
     void notificationSendAllFlowEntriesRemoved();
 
     /**
+     * Get all Flow IDs that are currently in the datagrid.
+     *
+     * @return all Flow IDs that ae currently in the datagrid.
+     */
+    Collection<Pair<FlowId, Dpid>> getAllFlowIds();
+
+    /**
+     * Send a notification that a FlowId is added.
+     *
+     * @param flowId the FlowId that is added.
+     * @param dpid the Source Switch Dpid.
+     */
+    void notificationSendFlowIdAdded(FlowId flowId, Dpid dpid);
+
+    /**
+     * Send a notification that a FlowId is removed.
+     *
+     * @param flowId the FlowId that is removed.
+     */
+    void notificationSendFlowIdRemoved(FlowId flowId);
+
+    /**
+     * Send a notification that a FlowId is updated.
+     *
+     * @param flowId the FlowId that is updated.
+     * @param dpid the Source Switch Dpid.
+     */
+    void notificationSendFlowIdUpdated(FlowId flowId, Dpid dpid);
+
+    /**
+     * Send a notification that all Flow IDs are removed.
+     */
+    void notificationSendAllFlowIdsRemoved();
+
+    /**
+     * Get all Flow Entry IDs that are currently in the datagrid.
+     *
+     * @return all Flow Entry IDs that ae currently in the datagrid.
+     */
+    Collection<Pair<FlowEntryId, Dpid>> getAllFlowEntryIds();
+
+    /**
+     * Send a notification that a FlowEntryId is added.
+     *
+     * @param flowEntryId the FlowEntryId that is added.
+     * @param dpid the Switch Dpid.
+     */
+    void notificationSendFlowEntryIdAdded(FlowEntryId flowEntryId, Dpid dpid);
+
+    /**
+     * Send a notification that a FlowEntryId is removed.
+     *
+     * @param flowEntryId the FlowEntryId that is removed.
+     */
+    void notificationSendFlowEntryIdRemoved(FlowEntryId flowEntryId);
+
+    /**
+     * Send a notification that a FlowEntryId is updated.
+     *
+     * @param flowEntryId the FlowEntryId that is updated.
+     * @param dpid the Switch Dpid.
+     */
+    void notificationSendFlowEntryIdUpdated(FlowEntryId flowEntryId,
+					    Dpid dpid);
+
+    /**
+     * Send a notification that all Flow Entry IDs are removed.
+     */
+    void notificationSendAllFlowEntryIdsRemoved();
+
+    /**
      * Get all Topology Elements that are currently in the datagrid.
      *
      * @return all Topology Elements that are currently in the datagrid.
diff --git a/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java b/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
index 80a6338..27de2c0 100644
--- a/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
+++ b/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
@@ -1,5 +1,7 @@
 package net.onrc.onos.graph;
 
+import java.util.Map;
+
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
 
 import org.slf4j.Logger;
@@ -35,6 +37,8 @@
 
 	}
 
+	@Override
+	//public void edgeRemoved(Edge e, Map<String, Object> arg1) {
 	public void edgeRemoved(Edge e) {
 		// TODO Auto-generated method stub
 		// Fire NetMapEvents (LinkRemoved, FlowEntryRemoved, HostRemoved, PortRemoved)
@@ -72,6 +76,8 @@
 
 	}
 
+	@Override
+	//public void vertexRemoved(Vertex vertex, Map<String, Object> arg1) {
 	public void vertexRemoved(Vertex vertex) {
 		// TODO Auto-generated method stub
 		// Generate NetMapEvents 
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
index f469911..ddc7527 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
@@ -60,7 +60,7 @@
 	 * It will close the DB connection. This is for Java garbage collection.
 	 */
 	@Override
-	public void finalize() {
+	protected void finalize() {
 		close();
 	}
 
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 b34a2fc..8882a55 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
@@ -27,6 +27,7 @@
 	protected DBOperation dbop;
 	private static PerfMon pm = PerfMon.getInstance();
 
+
 	/**
 	 * Initialize the object. Open LinkStorage using given configuration file.
 	 * @param conf Path (absolute path for now) to configuration file.
@@ -432,7 +433,7 @@
 	 * Finalize the object.
 	 */
 	@Override
-	public void finalize() {
+	protected void finalize() {
 		close();
 	}
 
@@ -493,6 +494,8 @@
 				log.error("LinkStorageImpl:addLinkImpl failed link exists {} {} src {} dst {}",
 						new Object[]{dbop, lt, vportSrc, vportDst});
 			}
+		} else {
+			log.error("Ports not found : {}", lt);
 		}
 
 		return success;
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 7c474bd..0dcf4297 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
@@ -48,7 +48,7 @@
 	 * It will close the DB connection.
 	 */
 	@Override
-	public void finalize() {
+	protected void finalize() {
 		close();
 	}
 
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java
index cf73c9c..24392df 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java
@@ -23,18 +23,18 @@
 	protected DBOperation dbop;
 	protected final static Logger log = LoggerFactory.getLogger(TopoLinkServiceImpl.class);
 
-	public void finalize() {
+	@Override
+	protected void finalize() {
 		close();
 	}
-	
+
 	@Override
 	public void close() {
 		dbop.close();
 	}
- 
+
 	@Override
 	public List<Link> getActiveLinks() {
-		// TODO Auto-generated method stub
 		dbop = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
 		//dbop = GraphDBManager.getDBOperation("", "");
 		//dbop.commit(); //Commit to ensure we see latest data
@@ -47,12 +47,12 @@
 			pipe.start(sw.asVertex());
 			pipe.enablePath(true);
 			pipe.out("on").out("link").in("on").path().step(extractor);
-					
+
 			while (pipe.hasNext() ) {
 				Link l = pipe.next();
 				links.add(l);
 			}
-						
+
 		}
 		dbop.commit();
 		return links;
@@ -68,7 +68,7 @@
 		pipe.start(sw.asVertex());
 		pipe.enablePath(true);
 		pipe.out("on").out("link").in("on").path().step(extractor);
-			
+
 		while (pipe.hasNext() ) {
 			Link l = pipe.next();
 			links.add(l);
@@ -84,7 +84,7 @@
 			long d_dpid = 0;
 			short s_port = 0;
 			short d_port = 0;
-			
+
 			List<?> V = pipe.next();
 			Vertex src_sw = (Vertex)V.get(0);
 			Vertex dest_sw = (Vertex)V.get(3);
@@ -94,9 +94,9 @@
 			d_dpid = HexString.toLong((String) dest_sw.getProperty("dpid"));
 			s_port = (Short) src_port.getProperty("number");
 			d_port = (Short) dest_port.getProperty("number");
-			
+
 			Link l = new Link(s_dpid,s_port,d_dpid,d_port);
-			
+
 			return l;
 		}
 	}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java
index 3f7090b..f417d96 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java
@@ -10,7 +10,7 @@
 import org.slf4j.LoggerFactory;
 
 public class TopoSwitchServiceImpl implements ITopoSwitchService {
-	
+
 	private DBOperation op;
 	protected final static Logger log = LoggerFactory.getLogger(TopoSwitchServiceImpl.class);
 
@@ -22,16 +22,17 @@
 	public TopoSwitchServiceImpl() {
 		this("","");
 	}
-	
-	public void finalize() {
+
+	@Override
+	protected void finalize() {
 		close();
 	}
-	
+
 	@Override
 	public void close() {
 		op.close();
 	}
-	
+
 	@Override
 	public Iterable<ISwitchObject> getActiveSwitches() {
 		// TODO Auto-generated method stub
@@ -67,5 +68,5 @@
 	public IPortObject getPortOnSwitch(String dpid, short port_num) {
 		// TODO Auto-generated method stub
 		return null;
-	}	
+	}
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
index af7bca8..1f0c163 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
@@ -3,9 +3,11 @@
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.LinkedList;
 import java.util.Map;
 
+import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.util.MACAddress;
 import net.onrc.onos.graph.DBOperation;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IBaseObject;
@@ -139,7 +141,7 @@
 	//
 	flowProp.setFlowId(flowPath.flowId().toString());
 	if ( measureONOSFlowTimeProp ) {
-	    numPropsSet += 2;
+	    numPropsSet += 1;
 	}
 
 	//
@@ -613,11 +615,7 @@
 	    }
 	}
 
-	// TODO: Hacks with hard-coded state names!
-	if (found)
-		flowProp.setUserState("FE_USER_MODIFY");
-	else
-		flowProp.setUserState("FE_USER_ADD");
+	flowProp.setUserState(flowEntry.flowEntryUserState().toString());
 	flowProp.setSwitchState(flowEntry.flowEntrySwitchState().toString());
 	if (measureONOSFlowEntryTimeProp) {
 	    numProperties += 2;
@@ -804,6 +802,77 @@
     }
 
     /**
+     * Get a previously added flow entry.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @param flowEntryId the Flow Entry ID of the flow entry to get.
+     * @return the Flow Entry if found, otherwise null.
+     */
+    static FlowEntry getFlowEntry(DBOperation dbHandler,
+				  FlowEntryId flowEntryId) {
+	IFlowEntry flowEntryObj = null;
+	try {
+	    flowEntryObj = dbHandler.searchFlowEntry(flowEntryId);
+	} catch (Exception e) {
+	    // TODO: handle exceptions
+	    dbHandler.rollback();
+	    log.error(":getFlowEntry FlowEntryId:{} failed", flowEntryId);
+	    return null;
+	}
+	if (flowEntryObj == null) {
+	    dbHandler.commit();
+	    return null;		// Flow not found
+	}
+
+	//
+	// Extract the Flow Entry state
+	//
+	FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
+	dbHandler.commit();
+
+	return flowEntry;
+    }
+
+    /**
+     * Get the source switch DPID of a previously added flow.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @param flowId the Flow ID of the flow to get.
+     * @return the source switch DPID if found, otherwise null.
+     */
+    static Dpid getFlowSourceDpid(DBOperation dbHandler, FlowId flowId) {
+	IFlowPath flowObj = null;
+	try {
+	    flowObj = dbHandler.searchFlowPath(flowId);
+	} catch (Exception e) {
+	    // TODO: handle exceptions
+	    dbHandler.rollback();
+	    log.error(":getFlowSourceDpid FlowId:{} failed", flowId);
+	    return null;
+	}
+	if (flowObj == null) {
+	    dbHandler.commit();
+	    return null;		// Flow not found
+	}
+
+	//
+	// Extract the Flow Source DPID
+	//
+	String srcSwitchStr = flowObj.getSrcSwitch();
+	if (srcSwitchStr == null) {
+	    // TODO: A work-around, becauuse of some bogus database objects
+	    dbHandler.commit();
+	    return null;
+	}
+
+	Dpid dpid = new Dpid(srcSwitchStr);
+
+	dbHandler.commit();
+
+	return dpid;
+    }
+
+    /**
      * Get all installed flows by all installers.
      *
      * @param dbHandler the Graph Database handler to use.
@@ -841,12 +910,88 @@
     }
 
     /**
+     * Get all installed flows whose Source Switch is controlled by this
+     * instance.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @param mySwitches the collection of the switches controlled by this
+     * instance.
+     * @return the Flow Paths if found, otherwise null.
+     */
+    static ArrayList<FlowPath> getAllMyFlows(DBOperation dbHandler,
+					     Map<Long, IOFSwitch> mySwitches) {
+	Iterable<IFlowPath> flowPathsObj = null;
+	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
+
+	try {
+	    flowPathsObj = dbHandler.getAllFlowPaths();
+	} catch (Exception e) {
+	    // TODO: handle exceptions
+	    dbHandler.rollback();
+	    log.error(":getAllMyFlowPaths failed");
+	    return flowPaths;
+	}
+	if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
+	    dbHandler.commit();
+	    return flowPaths;	// No Flows found
+	}
+
+	for (IFlowPath flowObj : flowPathsObj) {
+	    //
+	    // Extract the Source Switch DPID and ignore if the switch
+	    // is not controlled by this instance.
+	    //
+	    String srcSwitchStr = flowObj.getSrcSwitch();
+	    if (srcSwitchStr == null) {
+		// TODO: A work-around, becauuse of some bogus database objects
+		continue;
+	    }
+	    Dpid dpid = new Dpid(srcSwitchStr);
+	    if (mySwitches.get(dpid.value()) == null)
+		continue;
+
+	    //
+	    // Extract the Flow state
+	    //
+	    FlowPath flowPath = extractFlowPath(flowObj);
+	    if (flowPath != null)
+		flowPaths.add(flowPath);
+	}
+
+	dbHandler.commit();
+
+	return flowPaths;
+    }
+
+    /**
+     * Get a subset of installed flows.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @param flowIds the collection of Flow IDs to get.
+     * @return the Flow Paths if found, otherwise null.
+     */
+    static ArrayList<FlowPath> getFlows(DBOperation dbHandler,
+					Collection<FlowId> flowIds) {
+	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
+
+	// TODO: This implementation should use threads
+	for (FlowId flowId : flowIds) {
+	    FlowPath flowPath = getFlow(dbHandler, flowId);
+	    if (flowPath != null)
+		flowPaths.add(flowPath);
+	}
+	// dbHandler.commit();
+
+	return flowPaths;
+    }
+
+    /**
      * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
      *
      * @param flowObj the object to extract the Flow Path State from.
      * @return the extracted Flow Path State.
      */
-    private static FlowPath extractFlowPath(IFlowPath flowObj) {
+    static FlowPath extractFlowPath(IFlowPath flowObj) {
 	//
 	// Extract the Flow state
 	//
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
index 001fb3c..cf9b67d 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
@@ -15,11 +15,15 @@
 import java.util.concurrent.LinkedBlockingQueue;
 
 import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.IOFSwitchListener;
 import net.onrc.onos.datagrid.IDatagridService;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.ofcontroller.topology.Topology;
 import net.onrc.onos.ofcontroller.topology.TopologyElement;
 import net.onrc.onos.ofcontroller.topology.TopologyManager;
 import net.onrc.onos.ofcontroller.util.DataPath;
+import net.onrc.onos.ofcontroller.util.Dpid;
 import net.onrc.onos.ofcontroller.util.EventEntry;
 import net.onrc.onos.ofcontroller.util.FlowEntry;
 import net.onrc.onos.ofcontroller.util.FlowEntryAction;
@@ -31,6 +35,8 @@
 import net.onrc.onos.ofcontroller.util.FlowId;
 import net.onrc.onos.ofcontroller.util.FlowPath;
 import net.onrc.onos.ofcontroller.util.FlowPathUserState;
+import net.onrc.onos.ofcontroller.util.Pair;
+import net.onrc.onos.ofcontroller.util.Port;
 import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
 
 import com.esotericsoftware.kryo2.Kryo;
@@ -46,17 +52,16 @@
  * - Detect FlowPaths impacted by Topology change.
  * - Recompute impacted FlowPath using cached Topology.
  */
-class FlowEventHandler extends Thread implements IFlowEventHandlerService {
+class FlowEventHandler extends Thread implements IFlowEventHandlerService,
+						 IOFSwitchListener {
+
+    private boolean enableOnrc2014MeasurementsFlows = true;
+    private boolean enableOnrc2014MeasurementsTopology = true;
+
     /** The logger. */
     private final static Logger log = LoggerFactory.getLogger(FlowEventHandler.class);
 
-    // Flag to refresh Topology object periodically
-    private final static boolean refreshTopology = false;
-    // Refresh delay(ms)
-    private final static long refreshTopologyDelay = 5000;
-    // Refresh interval(ms)
-    private final static long refreshTopologyInterval = 2000;
-    private Timer refreshTopologyTimer;
+    private DBOperation dbHandler;
 
     private FlowManager flowManager;		// The Flow Manager to use
     private IDatagridService datagridService;	// The Datagrid Service to use
@@ -74,6 +79,12 @@
 	new LinkedList<EventEntry<FlowPath>>();
     private List<EventEntry<FlowEntry>> flowEntryEvents =
 	new LinkedList<EventEntry<FlowEntry>>();
+    private List<EventEntry<Pair<FlowId, Dpid>>> flowIdEvents =
+	new LinkedList<EventEntry<Pair<FlowId, Dpid>>>();
+    private List<EventEntry<Pair<FlowEntryId, Dpid>>> flowEntryIdEvents =
+	new LinkedList<EventEntry<Pair<FlowEntryId, Dpid>>>();
+    private List<EventEntry<Dpid>> switchDpidEvents =
+	new LinkedList<EventEntry<Dpid>>();
 
     // All internally computed Flow Paths
     private Map<Long, FlowPath> allFlowPaths = new HashMap<Long, FlowPath>();
@@ -119,6 +130,8 @@
      * Startup processing.
      */
     private void startup() {
+	this.dbHandler = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
+
 	//
 	// Obtain the initial Topology state
 	//
@@ -148,32 +161,33 @@
 	    flowEntryEvents.add(eventEntry);
 	}
 
+	//
+	// Obtain the initial FlowId state
+	//
+	Collection<Pair<FlowId, Dpid>> flowIds =
+	    datagridService.getAllFlowIds();
+	for (Pair<FlowId, Dpid> pair : flowIds) {
+	    EventEntry<Pair<FlowId, Dpid>> eventEntry =
+		new EventEntry<Pair<FlowId, Dpid>>(EventEntry.Type.ENTRY_ADD, pair);
+	    flowIdEvents.add(eventEntry);
+	}
+
+	//
+	// Obtain the initial FlowEntryId state
+	//
+	Collection<Pair<FlowEntryId, Dpid>> flowEntryIds =
+	    datagridService.getAllFlowEntryIds();
+	for (Pair<FlowEntryId, Dpid> pair : flowEntryIds) {
+	    EventEntry<Pair<FlowEntryId, Dpid>> eventEntry =
+		new EventEntry<Pair<FlowEntryId, Dpid>>(EventEntry.Type.ENTRY_ADD, pair);
+	    flowEntryIdEvents.add(eventEntry);
+	}
+
 	// Process the initial events (if any)
 	synchronized (allFlowPaths) {
 	    processEvents();
 	}
 
-	if (refreshTopology) {
-		refreshTopologyTimer = new Timer();
-		refreshTopologyTimer.schedule(new TimerTask() {
-			@Override
-			public void run() {
-				PerfMon pm = PerfMon.getInstance();
-				log.debug("[BEFORE] {}", topology);
-				long begin, end;
-				synchronized(topology) {
-					begin = System.nanoTime();
-					pm.read_whole_topology_start();
-					topology.readFromDatabase(flowManager.dbHandlerInner);
-					pm.read_whole_topology_end();
-					end = System.nanoTime();
-				}
-				// FIXME level raised for measurement. Was debug
-				log.error("[AFTER] {}", topology);
-				log.error("refresh takes : {}[us]", (end - begin) / 1000.0);
-			}
-		}, refreshTopologyDelay, refreshTopologyInterval);
-	}
     }
 
     /**
@@ -199,12 +213,15 @@
 		//  - EventEntry<TopologyElement>
 		//  - EventEntry<FlowPath>
 		//  - EventEntry<FlowEntry>
+		//  - EventEntry<Pair<FlowId, Dpid>>
+		//  - EventEntry<Pair<FlowEntryId, Dpid>>
 		//
 		for (EventEntry<?> event : collection) {
 		    // Topology event
 		    if (event.eventData() instanceof TopologyElement) {
 			EventEntry<TopologyElement> topologyEventEntry =
 			    (EventEntry<TopologyElement>)event;
+			
 			topologyEvents.add(topologyEventEntry);
 			continue;
 		    }
@@ -224,6 +241,34 @@
 			flowEntryEvents.add(flowEntryEventEntry);
 			continue;
 		    }
+
+		    // FlowId event
+		    if (event.eventData() instanceof Pair) {
+			EventEntry<Pair<FlowId, Dpid>> flowIdEventEntry =
+			    (EventEntry<Pair<FlowId, Dpid>>)event;
+			flowIdEvents.add(flowIdEventEntry);
+			continue;
+		    }
+
+		    // Switch Dpid event
+		    if (event.eventData() instanceof Dpid) {
+			EventEntry<Dpid> switchDpidEventEntry =
+			    (EventEntry<Dpid>)event;
+			switchDpidEvents.add(switchDpidEventEntry);
+			continue;
+		    }
+
+		    // FlowEntryId event
+		    // TODO: Fix the code below if we need again to handle
+		    // the FlowEntryId events
+		    /*
+		    if (event.eventData() instanceof Pair) {
+			EventEntry<Pair<FlowEntryId, Dpid>> flowEntryIdEventEntry =
+			    (EventEntry<Pair<FlowEntryId, Dpid>>)event;
+			flowEntryIdEvents.add(flowEntryIdEventEntry);
+			continue;
+		    }
+		    */
 		}
 		collection.clear();
 
@@ -236,13 +281,89 @@
 	    log.debug("Exception processing Network Events: ", exception);
 	}
     }
-
+    
     /**
      * Process the events (if any)
      */
     private void processEvents() {
 	Collection<FlowEntry> modifiedFlowEntries;
 
+	if (enableOnrc2014MeasurementsFlows) {
+
+	    if (topologyEvents.isEmpty() && flowIdEvents.isEmpty() &&
+		switchDpidEvents.isEmpty()) {
+		return;		// Nothing to do
+	    }
+
+	    Map<Long, IOFSwitch> mySwitches = flowManager.getMySwitches();
+
+	    // Process the Switch Dpid events
+	    processSwitchDpidEvents();
+
+	    // Process the Flow ID events
+	    processFlowIdEvents(mySwitches);
+
+	    // Fetch the topology
+	    processTopologyEvents();
+
+	    // Recompute all affected Flow Paths and keep only the modified
+	    for (FlowPath flowPath : shouldRecomputeFlowPaths.values()) {
+		if (recomputeFlowPath(flowPath))
+		    modifiedFlowPaths.put(flowPath.flowId().value(), flowPath);
+	    }
+
+	    // Assign the Flow Entry ID as needed
+	    for (FlowPath flowPath : modifiedFlowPaths.values()) {
+		for (FlowEntry flowEntry : flowPath.flowEntries()) {
+		    if (! flowEntry.isValidFlowEntryId()) {
+			long id = flowManager.getNextFlowEntryId();
+			flowEntry.setFlowEntryId(new FlowEntryId(id));
+		    }
+		}
+	    }
+
+	    //
+	    // Push the modified state to the database
+	    //
+	    for (FlowPath flowPath : modifiedFlowPaths.values()) {
+		//
+		// Delete the Flow Path from the Network Map
+		//
+		if (flowPath.flowPathUserState() ==
+		    FlowPathUserState.FP_USER_DELETE) {
+		    log.debug("Deleting Flow Path From Database: {}", flowPath);
+		    // TODO: For now the deleting of a Flow Path is blocking
+		    ParallelFlowDatabaseOperation.deleteFlow(dbHandler,
+							     flowPath.flowId());
+		    // Send the notifications for the deleted Flow Entries
+		    for (FlowEntry flowEntry : flowPath.flowEntries()) {
+			datagridService.notificationSendFlowEntryRemoved(flowEntry.flowEntryId());
+		    }
+
+		    continue;
+		}
+
+		log.debug("Pushing Flow Path To Database: {}", flowPath);
+		//
+		// Write the Flow Path to the Network Map
+		//
+		ParallelFlowDatabaseOperation.addFlow(dbHandler, flowPath,
+						      datagridService);
+	    }
+
+	    // Cleanup
+	    topologyEvents.clear();
+	    flowIdEvents.clear();
+	    switchDpidEvents.clear();
+	    //
+	    // NOTE: Keep a cache with my Flow Paths
+	    // allFlowPaths.clear();
+	    shouldRecomputeFlowPaths.clear();
+	    modifiedFlowPaths.clear();
+
+	    return;
+	}
+
 	if (topologyEvents.isEmpty() && flowPathEvents.isEmpty() &&
 	    flowEntryEvents.isEmpty()) {
 	    return;		// Nothing to do
@@ -379,6 +500,246 @@
     }
 
     /**
+     * Fix a flow fetched from the database.
+     *
+     * @param flowPath the Flow to fix.
+     */
+    private void fixFlowFromDatabase(FlowPath flowPath) {
+	//
+	// TODO: Bug workaround / fix :
+	// method FlowDatabaseOperation.extractFlowEntry() doesn't
+	// fetch the inPort and outPort, hence we assign them here.
+	//
+	// Assign the inPort and outPort for the Flow Entries
+	for (FlowEntry flowEntry : flowPath.flowEntries()) {
+	    // Set the inPort
+	    do {
+		if (flowEntry.inPort() != null)
+		    break;
+		if (flowEntry.flowEntryMatch() == null)
+		    break;
+		Port inPort = new Port(flowEntry.flowEntryMatch().inPort().value());
+		flowEntry.setInPort(inPort);
+	    } while (false);
+
+	    // Set the outPort
+	    do {
+		if (flowEntry.outPort() != null)
+		    break;
+		for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
+		    if (fa.actionOutput() != null) {
+			Port outPort = new Port(fa.actionOutput().port().value());
+			flowEntry.setOutPort(outPort);
+			break;
+		    }
+		}
+	    } while (false);
+	}
+    }
+
+    /**
+     * Process the Switch Dpid events.
+     */
+    private void processSwitchDpidEvents() {
+	Map<Long, Dpid> addedSwitches = new HashMap<Long, Dpid>();
+	Map<Long, Dpid> removedSwitches = new HashMap<Long, Dpid>();
+
+	//
+	// Process all Switch Dpid events and update the appropriate state
+	//
+	for (EventEntry<Dpid> eventEntry : switchDpidEvents) {
+	    Dpid dpid = eventEntry.eventData();
+			
+	    log.debug("SwitchDpid Event: {} {}", eventEntry.eventType(), dpid);
+
+	    // Compute the final set of added and removed switches
+	    switch (eventEntry.eventType()) {
+	    case ENTRY_ADD:
+		addedSwitches.put(dpid.value(), dpid);
+		removedSwitches.remove(dpid.value());
+		break;
+	    case ENTRY_REMOVE:
+		addedSwitches.remove(dpid.value());
+		removedSwitches.put(dpid.value(), dpid);
+		break;
+	    }
+	}
+
+	//
+	// Remove the Flows from the local cache if the removed
+	// switch is the Source Switch.
+	//
+	// TODO: This search can be expensive for a large number of flows
+	// and should be optmized.
+	//
+	List<FlowId> deleteFlowIds = new LinkedList<FlowId>();
+	for (Dpid switchDpid : removedSwitches.values()) {
+	    for (FlowPath flowPath : allFlowPaths.values()) {
+		Dpid srcDpid = flowPath.dataPath().srcPort().dpid();
+		if (srcDpid.value() == switchDpid.value())
+		    deleteFlowIds.add(flowPath.flowId());
+	    }
+	}
+	//
+	// Remove the Flows from the local cache
+	//
+	for (FlowId flowId : deleteFlowIds)
+	    allFlowPaths.remove(flowId.value());
+
+	// Get the Flows for the added switches
+	Collection<FlowPath> flowPaths =
+	    ParallelFlowDatabaseOperation.getFlowsForSwitches(dbHandler,
+							      addedSwitches.values());
+	for (FlowPath flowPath : flowPaths) {
+	    allFlowPaths.put(flowPath.flowId().value(), flowPath);
+	}
+    }
+
+    /**
+     * Process the Flow ID events.
+     *
+     * @param mySwitches the collection of my switches.
+     */
+    private void processFlowIdEvents(Map<Long, IOFSwitch> mySwitches) {
+	List<FlowId> shouldFetchMyFlowIds = new LinkedList<FlowId>();
+
+	//
+	// Process all Flow Id events and update the appropriate state
+	//
+	for (EventEntry<Pair<FlowId, Dpid>> eventEntry : flowIdEvents) {
+	    Pair<FlowId, Dpid> pair = eventEntry.eventData();
+	    FlowId flowId = pair.first;
+	    Dpid dpid = pair.second;
+
+	    log.debug("Flow ID Event: {} {} {}", eventEntry.eventType(),
+		      flowId, dpid);
+
+	    //
+	    // Ignore Flows if the Source Switch is not controlled by this
+	    // instance.
+	    //
+	    if (mySwitches.get(dpid.value()) == null)
+		continue;
+
+	    switch (eventEntry.eventType()) {
+	    case ENTRY_ADD: {
+		//
+		// Add a new Flow Path
+		//
+		if (allFlowPaths.get(flowId.value()) != null) {
+		    //
+		    // TODO: What to do if the Flow Path already exists?
+		    // Fow now, we just re-add it.
+		    //
+		}
+		shouldFetchMyFlowIds.add(flowId);
+
+		break;
+	    }
+
+	    case ENTRY_REMOVE: {
+		//
+		// Remove an existing Flow Path.
+		//
+		// Find the Flow Path, and mark the Flow and its Flow Entries
+		// for deletion.
+		//
+		FlowPath existingFlowPath =
+		    allFlowPaths.get(flowId.value());
+		if (existingFlowPath == null)
+		    continue;		// Nothing to do
+
+		existingFlowPath.setFlowPathUserState(FlowPathUserState.FP_USER_DELETE);
+		for (FlowEntry flowEntry : existingFlowPath.flowEntries()) {
+		    flowEntry.setFlowEntryUserState(FlowEntryUserState.FE_USER_DELETE);
+		    flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.FE_SWITCH_NOT_UPDATED);
+		}
+
+		// Remove the Flow Path from the internal state
+		Long key = existingFlowPath.flowId().value();
+		allFlowPaths.remove(key);
+		shouldRecomputeFlowPaths.remove(key);
+		modifiedFlowPaths.put(key, existingFlowPath);
+
+		break;
+	    }
+	    }
+	}
+
+	// Get my Flows
+	Collection<FlowPath> myFlows =
+	    ParallelFlowDatabaseOperation.getFlows(dbHandler,
+						   shouldFetchMyFlowIds);
+
+	for (FlowPath flowPath : myFlows) {
+	    fixFlowFromDatabase(flowPath);
+
+	    switch (flowPath.flowPathType()) {
+	    case FP_TYPE_SHORTEST_PATH:
+		//
+		// Reset the Data Path, in case it was set already, because
+		// we are going to recompute it anyway.
+		//
+		flowPath.flowEntries().clear();
+		shouldRecomputeFlowPaths.put(flowPath.flowId().value(),
+					     flowPath);
+		break;
+	    case FP_TYPE_EXPLICIT_PATH:
+		//
+		// Mark all Flow Entries for installation in the switches.
+		//
+		for (FlowEntry flowEntry : flowPath.flowEntries()) {
+		    flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.FE_SWITCH_NOT_UPDATED);
+		}
+		modifiedFlowPaths.put(flowPath.flowId().value(), flowPath);
+		break;
+	    case FP_TYPE_UNKNOWN:
+		log.error("FlowPath event with unknown type");
+		break;
+	    }
+	    allFlowPaths.put(flowPath.flowId().value(), flowPath);
+	}
+    }
+
+    /**
+     * Process the Flow Entry ID events.
+     *
+     * @param mySwitches the collection of my switches.
+     * @return a collection of modified Flow Entries this instance needs
+     * to push to its own switches.
+     */
+    private Collection<FlowEntry> processFlowEntryIdEvents(Map<Long, IOFSwitch> mySwitches) {
+	List<FlowEntry> modifiedFlowEntries = new LinkedList<FlowEntry>();
+
+	//
+	// Process all Flow ID events and update the appropriate state
+	//
+	for (EventEntry<Pair<FlowEntryId, Dpid>> eventEntry : flowEntryIdEvents) {
+	    Pair<FlowEntryId, Dpid> pair = eventEntry.eventData();
+	    FlowEntryId flowEntryId = pair.first;
+	    Dpid dpid = pair.second;
+
+	    log.debug("Flow Entry ID Event: {} {} {}", eventEntry.eventType(),
+		      flowEntryId, dpid);
+
+	    if (mySwitches.get(dpid.value()) == null)
+		continue;
+
+	    // Fetch the Flow Entry
+	    FlowEntry flowEntry = FlowDatabaseOperation.getFlowEntry(dbHandler,
+								     flowEntryId);
+	    if (flowEntry == null) {
+		log.debug("Flow Entry ID {} : Flow Entry not found!",
+			  flowEntryId);
+		continue;
+	    }
+	    modifiedFlowEntries.add(flowEntry);
+	}
+
+	return modifiedFlowEntries;
+    }
+
+    /**
      * Process the Flow Path events.
      */
     private void processFlowPathEvents() {
@@ -464,15 +825,34 @@
      * Process the Topology events.
      */
     private void processTopologyEvents() {
+	boolean isTopologyModified = false;
+
+	if (enableOnrc2014MeasurementsTopology) {
+	    if (topologyEvents.isEmpty())
+		return;
+
+	    // TODO: Code for debugging purpose only
+	    for (EventEntry<TopologyElement> eventEntry : topologyEvents) {
+		TopologyElement topologyElement = eventEntry.eventData();
+		log.debug("Topology Event: {} {}", eventEntry.eventType(),
+			  topologyElement.toString());
+	    }
+
+	    log.debug("[BEFORE] {}", topology.toString());
+	    topology.readFromDatabase(dbHandler);
+	    log.debug("[AFTER] {}", topology.toString());
+	    shouldRecomputeFlowPaths.putAll(allFlowPaths);
+	    return;
+	}
+
 	//
 	// Process all Topology events and update the appropriate state
 	//
-	boolean isTopologyModified = false;
 	for (EventEntry<TopologyElement> eventEntry : topologyEvents) {
 	    TopologyElement topologyElement = eventEntry.eventData();
-
+			
 	    log.debug("Topology Event: {} {}", eventEntry.eventType(),
-		      topologyElement);
+		      topologyElement.toString());
 
 	    switch (eventEntry.eventType()) {
 	    case ENTRY_ADD:
@@ -752,6 +1132,19 @@
     private boolean recomputeFlowPath(FlowPath flowPath) {
 	boolean hasChanged = false;
 
+	if (enableOnrc2014MeasurementsFlows) {
+	    // Cleanup the deleted Flow Entries from the earlier iteration
+	    flowPath.dataPath().removeDeletedFlowEntries();
+
+	    //
+	    // TODO: Fake it that the Flow Entries have been already pushed
+	    // into the switches, so we don't push them again.
+	    //
+	    for (FlowEntry flowEntry : flowPath.flowEntries()) {
+		flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.FE_SWITCH_UPDATED);
+	    }
+	}
+
 	//
 	// Test whether the Flow Path needs to be recomputed
 	//
@@ -772,7 +1165,6 @@
 	newDataPath = TopologyManager.computeNetworkPath(topology,
 								  flowPath);
 	}
-
 	if (newDataPath == null) {
 	    // We need the DataPath to compare the paths
 	    newDataPath = new DataPath();
@@ -982,6 +1374,13 @@
      */
     @Override
     public void notificationRecvFlowEntryAdded(FlowEntry flowEntry) {
+	if (enableOnrc2014MeasurementsFlows) {
+	    Collection entries = new ArrayList();
+	    entries.add(flowEntry);
+	    flowManager.pushModifiedFlowEntriesToSwitches(entries);
+	    return;
+	}
+
 	EventEntry<FlowEntry> eventEntry =
 	    new EventEntry<FlowEntry>(EventEntry.Type.ENTRY_ADD, flowEntry);
 	networkEvents.add(eventEntry);
@@ -994,6 +1393,19 @@
      */
     @Override
     public void notificationRecvFlowEntryRemoved(FlowEntry flowEntry) {
+	if (enableOnrc2014MeasurementsFlows) {
+	    //
+	    // NOTE: Must update the state to DELETE, because
+	    // the notification contains the original state.
+	    //
+	    flowEntry.setFlowEntryUserState(FlowEntryUserState.FE_USER_DELETE);
+
+	    Collection entries = new ArrayList();
+	    entries.add(flowEntry);
+	    flowManager.pushModifiedFlowEntriesToSwitches(entries);
+	    return;
+	}
+
 	EventEntry<FlowEntry> eventEntry =
 	    new EventEntry<FlowEntry>(EventEntry.Type.ENTRY_REMOVE, flowEntry);
 	networkEvents.add(eventEntry);
@@ -1006,6 +1418,13 @@
      */
     @Override
     public void notificationRecvFlowEntryUpdated(FlowEntry flowEntry) {
+	if (enableOnrc2014MeasurementsFlows) {
+	    Collection entries = new ArrayList();
+	    entries.add(flowEntry);
+	    flowManager.pushModifiedFlowEntriesToSwitches(entries);
+	    return;
+	}
+
 	// NOTE: The ADD and UPDATE events are processed in same way
 	EventEntry<FlowEntry> eventEntry =
 	    new EventEntry<FlowEntry>(EventEntry.Type.ENTRY_ADD, flowEntry);
@@ -1013,6 +1432,101 @@
     }
 
     /**
+     * Receive a notification that a FlowId is added.
+     *
+     * @param flowId the FlowId that is added.
+     * @param dpid the Source Switch Dpid for the corresponding Flow.
+     */
+    @Override
+    public void notificationRecvFlowIdAdded(FlowId flowId, Dpid dpid) {
+	Pair flowIdPair = new Pair(flowId, dpid);
+
+	EventEntry<Pair<FlowId, Dpid>> eventEntry =
+	    new EventEntry<Pair<FlowId, Dpid>>(EventEntry.Type.ENTRY_ADD, flowIdPair);
+	networkEvents.add(eventEntry);
+    }
+
+    /**
+     * Receive a notification that a FlowId is removed.
+     *
+     * @param flowId the FlowId that is removed.
+     * @param dpid the Source Switch Dpid for the corresponding Flow.
+     */
+    @Override
+    public void notificationRecvFlowIdRemoved(FlowId flowId, Dpid dpid) {
+	Pair flowIdPair = new Pair(flowId, dpid);
+
+	EventEntry<Pair<FlowId, Dpid>> eventEntry =
+	    new EventEntry<Pair<FlowId, Dpid>>(EventEntry.Type.ENTRY_REMOVE, flowIdPair);
+	networkEvents.add(eventEntry);
+    }
+
+    /**
+     * Receive a notification that a FlowId is updated.
+     *
+     * @param flowId the FlowId that is updated.
+     * @param dpid the Source Switch Dpid for the corresponding Flow.
+     */
+    @Override
+    public void notificationRecvFlowIdUpdated(FlowId flowId, Dpid dpid) {
+	Pair flowIdPair = new Pair(flowId, dpid);
+
+	// NOTE: The ADD and UPDATE events are processed in same way
+	EventEntry<Pair<FlowId, Dpid>> eventEntry =
+	    new EventEntry<Pair<FlowId, Dpid>>(EventEntry.Type.ENTRY_ADD, flowIdPair);
+	networkEvents.add(eventEntry);
+    }
+
+    /**
+     * Receive a notification that a FlowEntryId is added.
+     *
+     * @param flowEntryId the FlowEntryId that is added.
+     * @param dpid the Switch Dpid for the corresponding Flow Entry.
+     */
+    @Override
+    public void notificationRecvFlowEntryIdAdded(FlowEntryId flowEntryId,
+						 Dpid dpid) {
+	Pair flowEntryIdPair = new Pair(flowEntryId, dpid);
+
+	EventEntry<Pair<FlowEntryId, Dpid>> eventEntry =
+	    new EventEntry<Pair<FlowEntryId, Dpid>>(EventEntry.Type.ENTRY_ADD, flowEntryIdPair);
+	networkEvents.add(eventEntry);
+    }
+
+    /**
+     * Receive a notification that a FlowEntryId is removed.
+     *
+     * @param flowEntryId the FlowEntryId that is removed.
+     * @param dpid the Switch Dpid for the corresponding Flow Entry.
+     */
+    @Override
+    public void notificationRecvFlowEntryIdRemoved(FlowEntryId flowEntryId,
+						   Dpid dpid) {
+	Pair flowEntryIdPair = new Pair(flowEntryId, dpid);
+
+	EventEntry<Pair<FlowEntryId, Dpid>> eventEntry =
+	    new EventEntry<Pair<FlowEntryId, Dpid>>(EventEntry.Type.ENTRY_REMOVE, flowEntryIdPair);
+	networkEvents.add(eventEntry);
+    }
+
+    /**
+     * Receive a notification that a FlowEntryId is updated.
+     *
+     * @param flowEntryId the FlowEntryId that is updated.
+     * @param dpid the Switch Dpid for the corresponding Flow Entry.
+     */
+    @Override
+    public void notificationRecvFlowEntryIdUpdated(FlowEntryId flowEntryId,
+						   Dpid dpid) {
+	Pair flowEntryIdPair = new Pair(flowEntryId, dpid);
+
+	// NOTE: The ADD and UPDATE events are processed in same way
+	EventEntry<Pair<FlowEntryId, Dpid>> eventEntry =
+	    new EventEntry<Pair<FlowEntryId, Dpid>>(EventEntry.Type.ENTRY_ADD, flowEntryIdPair);
+	networkEvents.add(eventEntry);
+    }
+
+    /**
      * Receive a notification that a Topology Element is added.
      *
      * @param topologyElement the Topology Element that is added.
@@ -1050,6 +1564,40 @@
     }
 
     /**
+     * Receive a notification that a switch is added to this instance.
+     *
+     * @param sw the switch that is added.
+     */
+    @Override
+    public void addedSwitch(IOFSwitch sw) {
+	Dpid dpid = new Dpid(sw.getId());
+	EventEntry<Dpid> eventEntry =
+	    new EventEntry<Dpid>(EventEntry.Type.ENTRY_ADD, dpid);
+	networkEvents.add(eventEntry);
+    }
+
+    /**
+     * Receive a notification that a switch is removed from this instance.
+     *
+     * @param sw the switch that is removed.
+     */
+    @Override
+    public void removedSwitch(IOFSwitch sw) {
+	Dpid dpid = new Dpid(sw.getId());
+	EventEntry<Dpid> eventEntry =
+	    new EventEntry<Dpid>(EventEntry.Type.ENTRY_REMOVE, dpid);
+	networkEvents.add(eventEntry);
+    }
+
+    /**
+     * Receive a notification that the ports on a switch have changed.
+     */
+    @Override
+    public void switchPortChanged(Long switchId) {
+	// Nothing to do
+    }
+    
+    /**
      * Get a sorted copy of all Flow Paths.
      *
      * @return a sorted copy of all Flow Paths.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
index 611b5c9..fc5ae34 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -8,6 +8,7 @@
 import java.util.Map;
 import java.util.Random;
 import java.util.SortedMap;
+import java.util.TreeMap;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 
@@ -50,8 +51,9 @@
  * Flow Manager class for handling the network flows.
  */
 public class FlowManager implements IFloodlightModule, IFlowService, INetMapStorage {
-    // flag to use FlowPusher instead of FlowSwitchOperation/MessageDamper
-    private final static boolean enableFlowPusher = false;
+
+    private boolean enableOnrc2014MeasurementsFlows = true;
+
     protected DBOperation dbHandlerApi;
     protected DBOperation dbHandlerInner;
 
@@ -98,7 +100,7 @@
      * Shutdown the Flow Manager operation.
      */
     @Override
-    public void finalize() {
+    protected void finalize() {
     	close();
     }
 
@@ -107,6 +109,7 @@
      */
     @Override
     public void close() {
+	floodlightProvider.removeOFSwitchListener(flowEventHandler);
 	datagridService.deregisterFlowEventHandlerService(flowEventHandler);
     	dbHandlerApi.close();
     	dbHandlerInner.close();
@@ -233,6 +236,7 @@
 	//  - startup
 	//
 	flowEventHandler = new FlowEventHandler(this, datagridService);
+	floodlightProvider.addOFSwitchListener(flowEventHandler);
 	datagridService.registerFlowEventHandlerService(flowEventHandler);
 	flowEventHandler.start();
     }
@@ -273,7 +277,13 @@
 	}
 
 	if (FlowDatabaseOperation.addFlow(dbHandlerApi, flowPath)) {
-	    datagridService.notificationSendFlowAdded(flowPath);
+	    if (enableOnrc2014MeasurementsFlows) {
+		datagridService.notificationSendFlowIdAdded(flowPath.flowId(),
+							    flowPath.dataPath().srcPort().dpid());
+	    } else {
+		datagridService.notificationSendFlowAdded(flowPath);
+	    }
+
 	    return flowPath.flowId();
 	}
 	return null;
@@ -287,7 +297,11 @@
     @Override
     public boolean deleteAllFlows() {
 	if (FlowDatabaseOperation.deleteAllFlows(dbHandlerApi)) {
-	    datagridService.notificationSendAllFlowsRemoved();
+	    if (enableOnrc2014MeasurementsFlows) {
+		datagridService.notificationSendAllFlowIdsRemoved();
+	    } else {
+		datagridService.notificationSendAllFlowsRemoved();
+	    }
 	    return true;
 	}
 	return false;
@@ -302,7 +316,11 @@
     @Override
     public boolean deleteFlow(FlowId flowId) {
 	if (FlowDatabaseOperation.deleteFlow(dbHandlerApi, flowId)) {
-	    datagridService.notificationSendFlowRemoved(flowId);
+	    if (enableOnrc2014MeasurementsFlows) {
+		datagridService.notificationSendFlowIdRemoved(flowId);
+	    } else {
+		datagridService.notificationSendFlowRemoved(flowId);
+	    }
 	    return true;
 	}
 	return false;
@@ -320,6 +338,26 @@
     }
 
     /**
+     * Get a previously added flow entry.
+     *
+     * @param flowEntryId the Flow Entry ID of the flow entry to get.
+     * @return the Flow Entry if found, otherwise null.
+     */
+    public FlowEntry getFlowEntry(FlowEntryId flowEntryId) {
+	return FlowDatabaseOperation.getFlowEntry(dbHandlerApi, flowEntryId);
+    }
+
+    /**
+     * Get the source switch DPID of a previously added flow.
+     *
+     * @param flowId the Flow ID of the flow to get.
+     * @return the source switch DPID if found, otherwise null.
+     */
+    public Dpid getFlowSourceDpid(FlowId flowId) {
+	return FlowDatabaseOperation.getFlowSourceDpid(dbHandlerApi, flowId);
+    }
+
+    /**
      * Get all installed flows by all installers.
      *
      * @return the Flow Paths if found, otherwise null.
@@ -330,6 +368,18 @@
     }
 
     /**
+     * Get all installed flows whose Source Switch is controlled by this
+     * instance.
+     *
+     * @param mySwitches the collection of the switches controlled by this
+     * instance.
+     * @return the Flow Paths if found, otherwise null.
+     */
+    public ArrayList<FlowPath> getAllMyFlows(Map<Long, IOFSwitch> mySwitches) {
+	return FlowDatabaseOperation.getAllMyFlows(dbHandlerApi, mySwitches);
+    }
+
+    /**
      * Get summary of all installed flows by all installers in a given range.
      *
      * @param flowId the Flow ID of the first flow in the flow range to get.
@@ -341,7 +391,17 @@
 						  int maxFlows) {
     	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
 	SortedMap<Long, FlowPath> sortedFlowPaths =
-	    flowEventHandler.getAllFlowPathsCopy();
+	    new TreeMap<Long, FlowPath>();
+
+	if (enableOnrc2014MeasurementsFlows) {
+	    Collection<FlowPath> databaseFlowPaths =
+		ParallelFlowDatabaseOperation.getAllFlows(dbHandlerApi);
+	    for (FlowPath flowPath : databaseFlowPaths) {
+		sortedFlowPaths.put(flowPath.flowId().value(), flowPath);
+	    }
+	} else {
+	    sortedFlowPaths = flowEventHandler.getAllFlowPathsCopy();
+	}
 
 	//
 	// Truncate each Flow Path and Flow Entry
@@ -421,6 +481,9 @@
     public void flowEntriesPushedToSwitch(
 		Collection<Pair<IOFSwitch, FlowEntry>> entries) {
 
+	if (enableOnrc2014MeasurementsFlows)
+	    return;
+
 	//
 	// Process all entries
 	//
@@ -490,8 +553,12 @@
 	//  - Flow Paths to the database
 	//
 	pushModifiedFlowEntriesToSwitches(modifiedFlowEntries);
-	pushModifiedFlowPathsToDatabase(modifiedFlowPaths);
-	cleanupDeletedFlowEntriesFromDatagrid(modifiedFlowEntries);
+	if (enableOnrc2014MeasurementsFlows) {
+	    writeModifiedFlowPathsToDatabase(modifiedFlowPaths);
+	} else {
+	    pushModifiedFlowPathsToDatabase(modifiedFlowPaths);
+	    cleanupDeletedFlowEntriesFromDatagrid(modifiedFlowEntries);
+	}
     }
 
     /**
@@ -502,7 +569,7 @@
      *
      * @param modifiedFlowEntries the collection of modified Flow Entries.
      */
-    private void pushModifiedFlowEntriesToSwitches(
+    void pushModifiedFlowEntriesToSwitches(
 			Collection<FlowEntry> modifiedFlowEntries) {
 	if (modifiedFlowEntries.isEmpty())
 	    return;
@@ -679,7 +746,7 @@
      *
      * @param modifiedFlowPaths the collection of Flow Paths to write.
      */
-    private void writeModifiedFlowPathsToDatabase(
+    void writeModifiedFlowPathsToDatabase(
 		Collection<FlowPath> modifiedFlowPaths) {
 	if (modifiedFlowPaths.isEmpty())
 	    return;
@@ -719,7 +786,7 @@
 			retry = true;
 		    } catch (Exception e) {
 			log.error("Exception deleting Flow Path from Network MAP: {}", e);
-		    } 
+		    }
 		} while (retry);
 
 		continue;
@@ -738,10 +805,12 @@
 		    allValid = false;
 		    break;
 		}
-		if (flowEntry.flowEntrySwitchState() !=
-		    FlowEntrySwitchState.FE_SWITCH_UPDATED) {
-		    allValid = false;
-		    break;
+		if (! enableOnrc2014MeasurementsFlows) {
+		    if (flowEntry.flowEntrySwitchState() !=
+			FlowEntrySwitchState.FE_SWITCH_UPDATED) {
+			allValid = false;
+			break;
+		    }
 		}
 	    }
 	    if (! allValid)
@@ -777,6 +846,36 @@
                     //log.error("Performance %% Flow path total time {} : {}", endTime - startTime, flowPath.toString());
 		}
 	    } while (retry);
+
+	    if (enableOnrc2014MeasurementsFlows) {
+		// Send the notifications
+
+		for (FlowEntry flowEntry : flowPath.flowEntries()) {
+		    if (flowEntry.flowEntrySwitchState() !=
+			FlowEntrySwitchState.FE_SWITCH_NOT_UPDATED) {
+			continue;
+		    }
+		    // datagridService.notificationSendFlowEntryIdAdded(flowEntry.flowEntryId(), flowEntry.dpid());
+
+		    //
+		    // Write the Flow Entry to the Datagrid
+		    //
+		    switch (flowEntry.flowEntryUserState()) {
+		    case FE_USER_ADD:
+			datagridService.notificationSendFlowEntryAdded(flowEntry);
+			break;
+		    case FE_USER_MODIFY:
+			datagridService.notificationSendFlowEntryUpdated(flowEntry);
+			break;
+		    case FE_USER_DELETE:
+			datagridService.notificationSendFlowEntryRemoved(flowEntry.flowEntryId());
+			break;
+		    case FE_USER_UNKNOWN:
+			assert(false);
+			break;
+		    }
+		}
+	    }
 	}
     }
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowEventHandlerService.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowEventHandlerService.java
index 78562e1..a44a898 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowEventHandlerService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/IFlowEventHandlerService.java
@@ -1,7 +1,10 @@
 package net.onrc.onos.ofcontroller.flowmanager;
 
 import net.onrc.onos.ofcontroller.topology.TopologyElement;
+import net.onrc.onos.ofcontroller.util.Dpid;
 import net.onrc.onos.ofcontroller.util.FlowEntry;
+import net.onrc.onos.ofcontroller.util.FlowEntryId;
+import net.onrc.onos.ofcontroller.util.FlowId;
 import net.onrc.onos.ofcontroller.util.FlowPath;
 
 /**
@@ -51,6 +54,56 @@
     void notificationRecvFlowEntryUpdated(FlowEntry flowEntry);
 
     /**
+     * Receive a notification that a FlowId is added.
+     *
+     * @param flowId the FlowId that is added.
+     * @param dpid the Source Switch Dpid for the corresponding Flow.
+     */
+    void notificationRecvFlowIdAdded(FlowId flowId, Dpid dpid);
+
+    /**
+     * Receive a notification that a FlowId is removed.
+     *
+     * @param flowId the FlowId that is removed.
+     * @param dpid the Source Switch Dpid for the corresponding Flow.
+     */
+    void notificationRecvFlowIdRemoved(FlowId flowId, Dpid dpid);
+
+    /**
+     * Receive a notification that a FlowId is updated.
+     *
+     * @param flowId the FlowId that is updated.
+     * @param dpid the Source Switch Dpid for the corresponding Flow.
+     */
+    void notificationRecvFlowIdUpdated(FlowId flowId, Dpid dpid);
+
+    /**
+     * Receive a notification that a FlowEntryId is added.
+     *
+     * @param flowEntryId the FlowEntryId that is added.
+     * @param dpid the Switch Dpid for the corresponding Flow Entry.
+     */
+    void notificationRecvFlowEntryIdAdded(FlowEntryId flowEntryId, Dpid dpid);
+
+    /**
+     * Receive a notification that a FlowEntryId is removed.
+     *
+     * @param flowEntryId the FlowEntryId that is removed.
+     * @param dpid the Switch Dpid for the corresponding Flow Entry.
+     */
+    void notificationRecvFlowEntryIdRemoved(FlowEntryId flowEntryId,
+					    Dpid dpid);
+
+    /**
+     * Receive a notification that a FlowEntryId is updated.
+     *
+     * @param flowEntryId the FlowEntryId that is updated.
+     * @param dpid the Switch Dpid for the corresponding Flow Entry.
+     */
+    void notificationRecvFlowEntryIdUpdated(FlowEntryId flowEntryId,
+					    Dpid dpid);
+
+    /**
      * Receive a notification that a Topology Element is added.
      *
      * @param topologyElement the Topology Element that is added.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/ParallelFlowDatabaseOperation.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/ParallelFlowDatabaseOperation.java
new file mode 100644
index 0000000..212c59f
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/ParallelFlowDatabaseOperation.java
@@ -0,0 +1,367 @@
+package net.onrc.onos.ofcontroller.flowmanager;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorCompletionService;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.onrc.onos.datagrid.IDatagridService;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.FlowEntry;
+import net.onrc.onos.ofcontroller.util.FlowEntrySwitchState;
+import net.onrc.onos.ofcontroller.util.FlowId;
+import net.onrc.onos.ofcontroller.util.FlowPath;
+
+/**
+ * Class for performing parallel Flow-related operations on the Database.
+ * 
+ * This class is mostly a wrapper of FlowDatabaseOperation with a thread pool
+ * for parallelization.
+ * 
+ * @author Brian O'Connor <brian@onlab.us>
+ */
+public class ParallelFlowDatabaseOperation extends FlowDatabaseOperation {
+    private final static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
+
+    private final static int numThreads = Integer.valueOf(System.getProperty("parallelFlowDatabase.numThreads", "32"));
+    private final static ExecutorService executor = Executors.newFixedThreadPool(numThreads);
+
+    /**
+     * Get all installed flows by first querying the database for all FlowPaths
+     * and then populating them from the database in parallel.
+     * 
+     * @param dbHandler the Graph Database handler to use.
+     * @return the Flow Paths if found, otherwise an empty list.
+     */
+    static ArrayList<FlowPath> getAllFlows(DBOperation dbHandler) {
+	Iterable<IFlowPath> flowPathsObj = null;
+	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
+
+	try {
+	    flowPathsObj = dbHandler.getAllFlowPaths();
+	} catch (Exception e) {
+	    // TODO: handle exceptions
+	    dbHandler.rollback();
+	    log.error(":getAllFlowPaths failed");
+	    return flowPaths;
+	}
+	if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
+	    dbHandler.commit();
+	    return flowPaths;	// No Flows found
+	}
+	
+	CompletionService<FlowPath> tasks = new ExecutorCompletionService<>(executor);
+	int numTasks = 0;
+	for(IFlowPath flowObj : flowPathsObj) {
+	    tasks.submit(new ExtractFlowTask(flowObj));
+	    numTasks++;
+	}
+	for(int i = 0; i < numTasks; i++) {
+	    try {
+		FlowPath flowPath = tasks.take().get();
+		if(flowPath != null) {
+		    flowPaths.add(flowPath);
+		}
+	    } catch (InterruptedException | ExecutionException e) {
+		log.error("Error reading FlowPath from IFlowPath object");
+	    }
+	}
+	dbHandler.commit();
+	return flowPaths;	
+    }
+    
+    /**
+     * Query the database for all flow paths that have their source switch
+     * in the provided collection
+     * 
+     * Note: this function is implemented naively and inefficiently
+     * 
+     * @param dbHandler the Graph Database handler to use.
+     * @param switches a collection of switches whose flow paths you want
+     * @return the Flow Paths if found, otherwise an empty list.
+     */
+    static ArrayList<FlowPath> getFlowsForSwitches(DBOperation dbHandler, Collection<Dpid> switches) {
+	Iterable<IFlowPath> flowPathsObj = null;
+	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
+
+	try {
+	    flowPathsObj = dbHandler.getAllFlowPaths();
+	} catch (Exception e) {
+	    // TODO: handle exceptions
+	    dbHandler.rollback();
+	    log.error(":getAllFlowPaths failed");
+	    return flowPaths;
+	}
+	if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
+	    dbHandler.commit();
+	    return flowPaths;	// No Flows found
+	}
+	
+	// convert the collection of switch dpids into a set of strings
+	Set<String> switchSet = new HashSet<>();
+	for(Dpid dpid : switches) {
+	    switchSet.add(dpid.toString());
+	}
+	
+	CompletionService<FlowPath> tasks = new ExecutorCompletionService<>(executor);
+	int numTasks = 0;
+	for(IFlowPath flowObj : flowPathsObj) {
+	    if(switchSet.contains(flowObj.getSrcSwitch())) {
+		tasks.submit(new ExtractFlowTask(flowObj));
+		numTasks++;
+	    }
+	}
+	for(int i = 0; i < numTasks; i++) {
+	    try {
+		FlowPath flowPath = tasks.take().get();
+		if(flowPath != null) {
+		    flowPaths.add(flowPath);
+		}
+	    } catch (InterruptedException | ExecutionException e) {
+		log.error("Error reading FlowPath from IFlowPath object");
+	    }
+	}
+	dbHandler.commit();
+	return flowPaths;	
+    }
+    
+    /**
+     * The basic parallelization unit for extracting FlowEntries from the database.
+     * 
+     * This is simply a wrapper for FlowDatabaseOperation.extractFlowPath()
+     */
+    private final static class ExtractFlowTask implements Callable<FlowPath> {
+	private final IFlowPath flowObj;
+	
+	ExtractFlowTask(IFlowPath flowObj){
+	    this.flowObj = flowObj;
+	}
+	@Override 
+	public FlowPath call() throws Exception {
+	    return extractFlowPath(flowObj);
+	}
+    }
+
+    /**
+     * Get a subset of installed flows in parallel.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @param flowIds the collection of Flow IDs to get.
+     * @return the Flow Paths if found, otherwise an empty list.
+     */
+    static ArrayList<FlowPath> getFlows(DBOperation dbHandler,
+		  			Collection<FlowId> flowIds) {
+	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
+
+	CompletionService<FlowPath> tasks = new ExecutorCompletionService<>(executor);
+	int numTasks = 0;
+	for (FlowId flowId : flowIds) {
+	    tasks.submit(new GetFlowTask(dbHandler, flowId));
+	    numTasks++;
+	}
+	for(int i = 0; i < numTasks; i++) {
+	    try {
+		FlowPath flowPath = tasks.take().get();
+		if(flowPath != null) {
+		    flowPaths.add(flowPath);
+		}
+	    } catch (InterruptedException | ExecutionException e) {
+		log.error("Error reading FlowPath from database");
+	    }
+	}
+	// TODO: should we commit?
+	//dbHandler.commit();
+	return flowPaths;
+    }
+    
+    /**
+     * The basic parallelization unit for getting FlowEntries.
+     * 
+     * This is simply a wrapper for FlowDatabaseOperation.getFlow()
+     */
+    private final static class GetFlowTask implements Callable<FlowPath> {
+	private final DBOperation dbHandler;
+	private final FlowId flowId;
+
+	GetFlowTask(DBOperation dbHandler, FlowId flowId) {
+	    this.dbHandler = dbHandler;
+	    this.flowId = flowId;
+	}
+	@Override
+	public FlowPath call() throws Exception{
+	    return getFlow(dbHandler, flowId);
+	}
+    }
+    
+    /**
+     * Add a flow by creating a database task, then waiting for the result.
+     * Mostly, a wrapper for FlowDatabaseOperation.addFlow() which overs little
+     * performance benefit.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @param flowPath the Flow Path to install.
+     * @return true on success, otherwise false.
+     */
+    static boolean addFlow(DBOperation dbHandler, FlowPath flowPath) {
+	Future<Boolean> result = executor.submit(new AddFlowTask(dbHandler, flowPath, null));
+	// NOTE: This function is blocking
+	try {
+	    return result.get();
+	} catch (InterruptedException | ExecutionException e) {
+	    return false;
+	}
+    }
+    
+    /**
+     * Add a flow asynchronously by creating a database task.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @param flowPath the Flow Path to install.
+     * @param datagridService the notification service for when the task is completed
+     * @return true always
+     */
+    static boolean addFlow(DBOperation dbHandler, FlowPath flowPath, IDatagridService datagridService) {
+	executor.submit(new AddFlowTask(dbHandler, flowPath, datagridService));
+	// TODO: If we need the results, submit returns a Future that contains
+	// the result. 
+	return true;
+
+    }
+    
+    /**
+     * The basic parallelization unit for adding FlowPaths.
+     * 
+     * This is simply a wrapper for FlowDatabaseOperation.addFlow(), 
+     * which also sends a notification if a datagrid services is provided
+     */
+    private final static class AddFlowTask implements Callable<Boolean> {
+	private final DBOperation dbHandler;
+	private final FlowPath flowPath;
+	private final IDatagridService datagridService;
+
+	AddFlowTask(DBOperation dbHandler,
+		    FlowPath flowPath,
+		    IDatagridService datagridService) {
+	    this.dbHandler = dbHandler;
+	    this.flowPath = flowPath;
+	    this.datagridService = datagridService;
+	}
+	
+	@Override
+	public Boolean call() throws Exception {
+	    boolean success = FlowDatabaseOperation.addFlow(dbHandler, flowPath);
+	    if(success) {
+		if(datagridService != null) {
+		    // Send notifications for each Flow Entry
+		    for (FlowEntry flowEntry : flowPath.flowEntries()) {
+			if (flowEntry.flowEntrySwitchState() !=
+			    FlowEntrySwitchState.FE_SWITCH_NOT_UPDATED) {
+			    continue;
+			}
+			//
+			// Write the Flow Entry to the Datagrid
+			//
+			switch (flowEntry.flowEntryUserState()) {
+			case FE_USER_ADD:
+			    datagridService.notificationSendFlowEntryAdded(flowEntry);
+			    break;
+			case FE_USER_MODIFY:
+			    datagridService.notificationSendFlowEntryUpdated(flowEntry);
+			    break;
+			case FE_USER_DELETE:
+			    datagridService.notificationSendFlowEntryRemoved(flowEntry.flowEntryId());
+			    break;
+			case FE_USER_UNKNOWN:
+			    assert(false);
+			    break;
+			}
+		    }
+		}
+	    }
+	    else {
+		log.error("Error adding flow path {} to database", flowPath);
+	    }
+	    return success;
+
+	}
+    }
+
+    /**
+     * Delete a previously added flow by creating a database task, then waiting 
+     * for the result.
+     * 
+     * Mostly, a wrapper for FlowDatabaseOperation.addFlow() which overs little
+     * performance benefit.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @param flowId the Flow ID of the flow to delete.
+     * @return true on success, otherwise false.
+     */
+    static boolean deleteFlow(DBOperation dbHandler, FlowId flowId) {
+	Future<Boolean> result = executor.submit(new DeleteFlowTask(dbHandler, flowId, null));
+	// NOTE: This function is blocking
+	try {
+	    return result.get();
+	} catch (InterruptedException | ExecutionException e) {
+	    return false;
+	}
+    }    
+    
+    /**
+     * Delete a previously added flow asynchronously by creating a database task.
+     *
+     * @param dbHandler the Graph Database handler to use.
+     * @param flowId the Flow ID of the flow to delete.
+     * @param datagridService the notification service for when the task is completed
+     * @return true always
+     */
+    static boolean deleteFlow(DBOperation dbHandler, FlowId flowId, IDatagridService datagridService) {
+	executor.submit(new DeleteFlowTask(dbHandler, flowId, datagridService));
+	// TODO: If we need the results, submit returns a Future that contains
+	// the result. 
+	return true;
+    }
+    
+    /**
+     * The basic parallelization unit for deleting FlowPaths.
+     * 
+     * This is simply a wrapper for FlowDatabaseOperation.deleteFlow(),
+     * which also sends a notification if a datagrid services is provided
+     */
+    private final static class DeleteFlowTask implements Callable<Boolean> {
+	private final DBOperation dbHandler;
+	private final FlowId flowId;
+	private final IDatagridService datagridService;
+
+	DeleteFlowTask(DBOperation dbHandler, FlowId flowId, IDatagridService datagridService) {
+	    this.dbHandler = dbHandler;
+	    this.flowId = flowId;
+	    this.datagridService = datagridService;
+	}
+	@Override
+	public Boolean call() throws Exception{
+	    boolean success = FlowDatabaseOperation.deleteFlow(dbHandler, flowId);
+	    if(success) {
+		if(datagridService != null) {
+		    datagridService.notificationSendFlowIdRemoved(flowId);
+		}
+	    }
+	    else {
+		log.error("Error removing flow path {} from database", flowId);
+	    }
+	    return success;
+	}
+    }
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/PerformanceMonitor.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/PerformanceMonitor.java
new file mode 100644
index 0000000..13319e7
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/PerformanceMonitor.java
@@ -0,0 +1,162 @@
+package net.onrc.onos.ofcontroller.flowmanager;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class for collecting performance measurements
+ */
+public class PerformanceMonitor {
+    private final static Map<String, Measurement> map = new ConcurrentHashMap<String, Measurement>();;
+    private final static Logger log = LoggerFactory.getLogger(PerformanceMonitor.class);
+    private static long overhead;    
+    
+    /**
+     * Start a performance measurement, identified by a tag
+     * 
+     * Note: Only a single measurement can use the same tag at a time.
+     * 
+     * @param tag for performance measurement
+     */
+    public static void start(String tag) {
+	long start = System.nanoTime();
+	Measurement m = new Measurement();
+	if(map.put(tag, m) != null) {
+	    // if there was a previous entry, we have just overwritten it
+	    log.error("Tag {} already exists", tag);
+	}
+	m.start();
+	overhead += System.nanoTime() - start;
+    }
+    
+    /**
+     * Stop a performance measurement. 
+     * 
+     * You must have already started a measurement with tag.
+     * 
+     * @param tag for performance measurement
+     */
+    public static void stop(String tag) {
+	long time = System.nanoTime();
+	Measurement m = map.get(tag);
+	if(m == null) {
+	    log.error("Tag {} does not exist", tag);
+	}
+	else {
+	    map.get(tag).stop(time);
+	}
+	overhead += System.nanoTime() - time;
+    }
+    
+    /**
+     * Find a measurement, identified by tag, and return the result
+     * 
+     * @param tag for performance measurement
+     * @return the time in nanoseconds
+     */
+    public static long result(String tag) {
+	Measurement m = map.get(tag);
+	if(m != null) {
+	    return m.elapsed();
+	}
+	else {
+	    return -1;
+	}
+    }
+    
+    /**
+     * Clear all performance measurements.
+     */
+    public static void clear() {
+	map.clear();
+	overhead = 0;
+    }
+    
+    /**
+     * Write all performance measurements to the log
+     */
+    public static void report() {
+	double overheadMilli = overhead / Math.pow(10, 6);
+	log.error("Performance Results: {} with measurement overhead: {} ms", map, overheadMilli);
+    }
+    
+    /**
+     * A single performance measurement
+     */
+    static class Measurement {
+	long start;
+	long stop;
+	
+	/** 
+	 * Start the measurement
+	 */
+	public void start() {
+	    start = System.nanoTime();
+	}
+	
+	/**
+	 * Stop the measurement
+	 */
+	public void stop() {
+	    stop = System.nanoTime();
+	}
+	
+	/**
+	 * Stop the measurement at a specific time
+	 * @param time to stop
+	 */
+	public void stop(long time){
+	    stop = time;
+	}
+	
+	/**
+	 * Compute the elapsed time of the measurement in nanoseconds
+	 * 
+	 * @return the measurement time in nanoseconds, or -1 if the measurement is stil running.
+	 */
+	public long elapsed() {
+	    if(stop == 0) {
+		return -1;
+	    }
+	    else {
+		return stop - start;
+	    }
+	}
+	
+	/**
+	 * Returns the number of milliseconds for the measurement as a String.
+	 */
+	public String toString() {
+	    double milli = elapsed() / Math.pow(10, 6);
+	    return Double.toString(milli) + "ms";
+	}
+    }
+    
+    public static void main(String args[]){
+	// test the measurement overhead
+	String tag;
+	for(int i = 0; i < 100; i++){
+	    tag = "foo foo foo";
+	    start(tag); stop(tag);
+	    tag = "bar";
+	    start(tag); stop(tag);
+	    tag = "baz";
+	    start(tag); stop(tag);
+	    report();
+	    clear();
+	}
+	for(int i = 0; i < 100; i++){
+	    tag = "a";
+	    start(tag); stop(tag);
+	    tag = "b";
+	    start(tag); stop(tag);
+	    tag = "c";
+	    start(tag); stop(tag);
+	    report();
+	    clear();
+	}
+    }
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
index 98fe262..949cc7b 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
@@ -242,12 +242,15 @@
      *
      */
     class FlowEntryWrapper {
-	FlowEntryId flowEntryId;
-	OFFlowStatisticsReply statisticsReply;
+    FlowEntryId flowEntryId;
+    IFlowEntry iFlowEntry;
+    OFFlowStatisticsReply statisticsReply;
+
 
 	public FlowEntryWrapper(IFlowEntry entry) {
 	    flowEntryId = new FlowEntryId(entry.getFlowEntryId());
-	}
+	    iFlowEntry = entry;
+    }
 
 	public FlowEntryWrapper(OFFlowStatisticsReply entry) {
 	    flowEntryId = new FlowEntryId(entry.getCookie());
@@ -268,18 +271,14 @@
 
 	    double startDB = System.nanoTime();
 	    // Get the Flow Entry state from the Network Graph
-	    IFlowEntry iFlowEntry = null;
-	    try {
-		iFlowEntry = dbHandler.searchFlowEntry(flowEntryId);
-	    } catch (Exception e) {
-		log.error("Error finding flow entry {} in Network Graph",
-			  flowEntryId);
-		return;
-	    }
 	    if (iFlowEntry == null) {
-		log.error("Cannot add flow entry {} to sw {} : flow entry not found",
-			  flowEntryId, sw.getId());
-		return;
+            try {
+            	iFlowEntry = dbHandler.searchFlowEntry(flowEntryId);
+            } catch (Exception e) {
+            	log.error("Error finding flow entry {} in Network Graph",
+            			flowEntryId);
+            	return;
+            }
 	    }
 	    dbTime = System.nanoTime() - startDB;
 
diff --git a/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManager.java b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
index 1dbfdcb..3860e05 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
@@ -112,7 +112,7 @@
  */
 @LogMessageCategory("Network Topology")
 public class LinkDiscoveryManager
-implements IOFMessageListener, IOFSwitchListener, 
+implements IOFMessageListener, IOFSwitchListener,
 ILinkDiscoveryService, IFloodlightModule {
 	protected IFloodlightProviderService controller;
     protected final static Logger log = LoggerFactory.getLogger(LinkDiscoveryManager.class);
@@ -125,7 +125,7 @@
 
 
     // LLDP and BDDP fields
-    private static final byte[] LLDP_STANDARD_DST_MAC_STRING = 
+    private static final byte[] LLDP_STANDARD_DST_MAC_STRING =
             HexString.fromHexString("01:80:c2:00:00:0e");
     private static final long LINK_LOCAL_MASK  = 0xfffffffffff0L;
     private static final long LINK_LOCAL_VALUE = 0x0180c2000000L;
@@ -135,27 +135,27 @@
     private static final String LLDP_BSN_DST_MAC_STRING = "ff:ff:ff:ff:ff:ff";
 
 
-    // Direction TLVs are used to indicate if the LLDPs were sent 
+    // Direction TLVs are used to indicate if the LLDPs were sent
     // periodically or in response to a recieved LLDP
     private static final byte TLV_DIRECTION_TYPE = 0x73;
     private static final short TLV_DIRECTION_LENGTH = 1;  // 1 byte
     private static final byte TLV_DIRECTION_VALUE_FORWARD[] = {0x01};
     private static final byte TLV_DIRECTION_VALUE_REVERSE[] = {0x02};
-    private static final LLDPTLV forwardTLV 
+    private static final LLDPTLV forwardTLV
     = new LLDPTLV().
-    setType((byte)TLV_DIRECTION_TYPE).
-    setLength((short)TLV_DIRECTION_LENGTH).
+    setType(TLV_DIRECTION_TYPE).
+    setLength(TLV_DIRECTION_LENGTH).
     setValue(TLV_DIRECTION_VALUE_FORWARD);
 
-    private static final LLDPTLV reverseTLV 
+    private static final LLDPTLV reverseTLV
     = new LLDPTLV().
-    setType((byte)TLV_DIRECTION_TYPE).
-    setLength((short)TLV_DIRECTION_LENGTH).
+    setType(TLV_DIRECTION_TYPE).
+    setLength(TLV_DIRECTION_LENGTH).
     setValue(TLV_DIRECTION_VALUE_REVERSE);
 
     // Link discovery task details.
     protected SingletonTask discoveryTask;
-    protected final int DISCOVERY_TASK_INTERVAL = 1; 
+    protected final int DISCOVERY_TASK_INTERVAL = 1;
     protected final int LINK_TIMEOUT = 35; // original 35 secs, aggressive 5 secs
     protected final int LLDP_TO_ALL_INTERVAL = 15 ; //original 15 seconds, aggressive 2 secs.
     protected long lldpClock = 0;
@@ -206,7 +206,7 @@
     /* topology aware components are called in the order they were added to the
      * the array */
     protected ArrayList<ILinkDiscoveryListener> linkDiscoveryAware;
-    
+
     protected class LinkUpdate extends LDUpdate {
 
 		public LinkUpdate(LDUpdate old) {
@@ -263,7 +263,7 @@
      */
     protected Map<NodePortTuple, Long> broadcastDomainPortTimeMap;
 
-    /** 
+    /**
      * Get the LLDP sending period in seconds.
      * @return LLDP sending period in seconds.
      */
@@ -283,6 +283,7 @@
         return portLinks;
     }
 
+    @Override
     public Set<NodePortTuple> getSuppressLLDPsInfo() {
         return suppressLinkDiscovery;
     }
@@ -291,6 +292,7 @@
      * Add a switch port to the suppressed LLDP list.
      * Remove any known links on the switch port.
      */
+    @Override
     public void AddToSuppressLLDPs(long sw, short port)
     {
         NodePortTuple npt = new NodePortTuple(sw, port);
@@ -302,7 +304,8 @@
      * Remove a switch port from the suppressed LLDP list.
      * Discover links on that switchport.
      */
-    public void RemoveFromSuppressLLDPs(long sw, short port) 
+    @Override
+    public void RemoveFromSuppressLLDPs(long sw, short port)
     {
         NodePortTuple npt = new NodePortTuple(sw, port);
         this.suppressLinkDiscovery.remove(npt);
@@ -317,6 +320,7 @@
         return false;
     }
 
+    @Override
     public ILinkDiscovery.LinkType getLinkType(Link lt, LinkInfo info) {
         if (info.getUnicastValidTime() != null) {
             return ILinkDiscovery.LinkType.DIRECT_LINK;
@@ -326,7 +330,7 @@
         return ILinkDiscovery.LinkType.INVALID_LINK;
     }
 
-    
+
     private boolean isLinkDiscoverySuppressed(long sw, short portNumber) {
         return this.suppressLinkDiscovery.contains(new NodePortTuple(sw, portNumber));
     }
@@ -437,6 +441,7 @@
         }
     }
 
+    @Override
     public Set<Short> getQuarantinedPorts(long sw) {
         Set<Short> qPorts = new HashSet<Short>();
 
@@ -468,12 +473,12 @@
         else operation = UpdateOperation.PORT_DOWN;
 
         LinkUpdate update = new LinkUpdate(new LDUpdate(sw, port, operation));
-        
-        
+
+
         controller.publishUpdate(update);
     }
 
-    /** 
+    /**
      * Send LLDP on known ports
      */
     protected void discoverOnKnownLinkPorts() {
@@ -500,7 +505,7 @@
      */
     protected IOFSwitch addRemoteSwitch(long sw, short port) {
     	IOnosRemoteSwitch remotesw = null;
-    	
+
     	// add a switch if we have not seen it before
     	remotesw = remoteSwitches.get(sw);
 
@@ -510,26 +515,26 @@
         	remoteSwitches.put(remotesw.getId(), remotesw);
         	log.debug("addRemoteSwitch(): added fake remote sw {}", remotesw);
         }
-        
+
         // add the port if we have not seen it before
         if (remotesw.getPort(port) == null) {
         	OFPhysicalPort remoteport = new OFPhysicalPort();
         	remoteport.setPortNumber(port);
         	remoteport.setName("fake_" + port);
-        	remoteport.setConfig(0); 
+        	remoteport.setConfig(0);
         	remoteport.setState(0);
         	remotesw.setPort(remoteport);
         	log.debug("addRemoteSwitch(): added fake remote port {} to sw {}", remoteport, remotesw.getId());
         }
-        
+
         return remotesw;
     }
-    
+
     /**
      * Send link discovery message out of a given switch port.
      * The discovery message may be a standard LLDP or a modified
-     * LLDP, where the dst mac address is set to :ff.  
-     * 
+     * LLDP, where the dst mac address is set to :ff.
+     *
      * TODO: The modified LLDP will updated in the future and may
      * use a different eth-type.
      * @param sw
@@ -565,7 +570,7 @@
 
         if (isLinkDiscoverySuppressed(sw, port)) {
             /* Dont send LLDPs out of this port as suppressLLDPs set
-             * 
+             *
              */
             return;
         }
@@ -881,9 +886,9 @@
 
         addOrUpdateLink(lt, newLinkInfo);
 
-        // Check if reverse link exists. 
-        // If it doesn't exist and if the forward link was seen 
-        // first seen within a small interval, send probe on the 
+        // Check if reverse link exists.
+        // If it doesn't exist and if the forward link was seen
+        // first seen within a small interval, send probe on the
         // reverse link.
 
         newLinkInfo = links.get(lt);
@@ -927,8 +932,8 @@
 
     protected Command handlePacketIn(long sw, OFPacketIn pi,
                                      FloodlightContext cntx) {
-        Ethernet eth = 
-                IFloodlightProviderService.bcStore.get(cntx, 
+        Ethernet eth =
+                IFloodlightProviderService.bcStore.get(cntx,
                                                        IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
 
         if(eth.getEtherType() == Ethernet.TYPE_BSN) {
@@ -999,8 +1004,8 @@
                 newInfo.setFirstSeenTime(oldInfo.getFirstSeenTime());
 
             if (log.isTraceEnabled()) {
-                log.trace("addOrUpdateLink: {} {}", 
-                          lt, 
+                log.trace("addOrUpdateLink: {} {}",
+                          lt,
                           (newInfo.getMulticastValidTime()!=null) ? "multicast" : "unicast");
             }
 
@@ -1033,7 +1038,7 @@
                 // Add to portNOFLinks if the unicast valid time is null
                 if (newInfo.getUnicastValidTime() == null)
                     addLinkToBroadcastDomain(lt);
-                
+
                 // ONOS: Distinguish added event separately from updated event
                 updateOperation = UpdateOperation.LINK_ADDED;
                 linkChanged = true;
@@ -1119,6 +1124,7 @@
         return linkChanged;
     }
 
+    @Override
     public Map<Long, Set<Link>> getSwitchLinks() {
         return this.switchLinks;
     }
@@ -1198,7 +1204,7 @@
 
         // ONOS: If we do not control this switch, then we should not process its port status messages
         if (!registryService.hasControl(iofSwitch.getId())) return Command.CONTINUE;
-        
+
         if (log.isTraceEnabled()) {
             log.trace("handlePortStatus: Switch {} port #{} reason {}; " +
                     "config is {} state is {}",
@@ -1225,7 +1231,7 @@
                 LinkUpdate update = new LinkUpdate(new LDUpdate(sw, port, UpdateOperation.PORT_DOWN));
                 controller.publishUpdate(update);
                 linkDeleted = true;
-                } 
+                }
             else if (ps.getReason() ==
                     (byte)OFPortReason.OFPPR_MODIFY.ordinal()) {
                 // If ps is a port modification and the port state has changed
@@ -1237,7 +1243,7 @@
                         assert(linkInfo != null);
                         Integer updatedSrcPortState = null;
                         Integer updatedDstPortState = null;
-                        if (lt.getSrc() == npt.getNodeId() && 
+                        if (lt.getSrc() == npt.getNodeId() &&
                                 lt.getSrcPort() == npt.getPortId() &&
                                 (linkInfo.getSrcPortState() !=
                                 ps.getDesc().getState())) {
@@ -1264,7 +1270,7 @@
                                                      getLinkType(lt, linkInfo),
                                                      operation));
                             controller.publishUpdate(update);
-                            
+
                             linkInfoChanged = true;
                         }
                     }
@@ -1378,9 +1384,9 @@
             lock.writeLock().unlock();
         }
     }
-    
+
     /**
-     * We don't react the port changed notifications here. we listen for 
+     * We don't react the port changed notifications here. we listen for
      * OFPortStatus messages directly. Might consider using this notifier
      * instead
      */
@@ -1389,7 +1395,7 @@
         // no-op
     }
 
-    /** 
+    /**
      * Delete links incident on a given switch port.
      * @param npt
      * @param reason
@@ -1409,7 +1415,7 @@
         }
     }
 
-    /** 
+    /**
      * Iterates through the list of links and deletes if the
      * last discovery message reception time exceeds timeout values.
      */
@@ -1430,7 +1436,7 @@
 
                 // Timeout the unicast and multicast LLDP valid times
                 // independently.
-                if ((info.getUnicastValidTime() != null) && 
+                if ((info.getUnicastValidTime() != null) &&
                         (info.getUnicastValidTime() + (this.LINK_TIMEOUT * 1000) < curTime)){
                     info.setUnicastValidTime(null);
 
@@ -1440,7 +1446,7 @@
                     // the link would be deleted, which would trigger updateClusters().
                     linkChanged = true;
                 }
-                if ((info.getMulticastValidTime()!= null) && 
+                if ((info.getMulticastValidTime()!= null) &&
                         (info.getMulticastValidTime()+ (this.LINK_TIMEOUT * 1000) < curTime)) {
                     info.setMulticastValidTime(null);
                     // if uTime is not null, then link will remain as openflow
@@ -1451,7 +1457,7 @@
                 }
                 // Add to the erase list only if the unicast
                 // time is null.
-                if (info.getUnicastValidTime() == null && 
+                if (info.getUnicastValidTime() == null &&
                         info.getMulticastValidTime() == null){
                     eraseList.add(entry.getKey());
                 } else if (linkChanged) {
@@ -1510,11 +1516,11 @@
         srcNpt = new NodePortTuple(lt.getSrc(), lt.getSrcPort());
         dstNpt = new NodePortTuple(lt.getDst(), lt.getDstPort());
 
-        if (!portBroadcastDomainLinks.containsKey(lt.getSrc()))
+        if (!portBroadcastDomainLinks.containsKey(srcNpt))
             portBroadcastDomainLinks.put(srcNpt, new HashSet<Link>());
         portBroadcastDomainLinks.get(srcNpt).add(lt);
 
-        if (!portBroadcastDomainLinks.containsKey(lt.getDst()))
+        if (!portBroadcastDomainLinks.containsKey(dstNpt))
             portBroadcastDomainLinks.put(dstNpt, new HashSet<Link>());
         portBroadcastDomainLinks.get(dstNpt).add(lt);
     }
@@ -1575,7 +1581,7 @@
 
     @Override
     public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-        Collection<Class<? extends IFloodlightService>> l = 
+        Collection<Class<? extends IFloodlightService>> l =
                 new ArrayList<Class<? extends IFloodlightService>>();
         l.add(ILinkDiscoveryService.class);
         //l.add(ITopologyService.class);
@@ -1586,7 +1592,7 @@
     public Map<Class<? extends IFloodlightService>, IFloodlightService>
     getServiceImpls() {
         Map<Class<? extends IFloodlightService>,
-        IFloodlightService> m = 
+        IFloodlightService> m =
         new HashMap<Class<? extends IFloodlightService>,
         IFloodlightService>();
         // We are the class that implements the service
@@ -1596,7 +1602,7 @@
 
     @Override
     public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
-        Collection<Class<? extends IFloodlightService>> l = 
+        Collection<Class<? extends IFloodlightService>> l =
                 new ArrayList<Class<? extends IFloodlightService>>();
         l.add(IFloodlightProviderService.class);
         l.add(IThreadPoolService.class);
@@ -1679,7 +1685,7 @@
                     log.error("Exception in LLDP send timer.", e);
                 } finally {
                     if (!shuttingDown) {
-                    	// Always reschedule link discovery if we're not 
+                    	// Always reschedule link discovery if we're not
                     	// shutting down (no chance of SLAVE role now)
                         log.trace("Rescheduling discovery task");
                         discoveryTask.reschedule(DISCOVERY_TASK_INTERVAL,
@@ -1729,7 +1735,7 @@
         if ((sw.getChannel() != null) &&
                 (SocketAddress.class.isInstance(
                                                 sw.getChannel().getRemoteAddress()))) {
-            evTopoSwitch.ipv4Addr = 
+            evTopoSwitch.ipv4Addr =
                     IPv4.toIPv4Address(((InetSocketAddress)(sw.getChannel().
                             getRemoteAddress())).getAddress().getAddress());
             evTopoSwitch.l4Port   =
@@ -1787,10 +1793,12 @@
         evTopoCluster = evHistTopologyCluster.put(evTopoCluster, action);
     }
 
+    @Override
     public boolean isAutoPortFastFeature() {
         return autoPortFastFeature;
     }
 
+    @Override
     public void setAutoPortFastFeature(boolean autoPortFastFeature) {
         this.autoPortFastFeature = autoPortFastFeature;
     }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java b/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
index 1674cf0..9fca86a 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
@@ -1,6 +1,5 @@
 package net.onrc.onos.ofcontroller.topology;
 
-import java.util.ArrayList;
 import java.util.List;
 import java.util.LinkedList;
 import java.util.Map;
@@ -12,7 +11,6 @@
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
 import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
 
-import org.apache.commons.lang.StringUtils;
 import org.openflow.util.HexString;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -195,7 +193,10 @@
  */
 public class Topology {
     private final static Logger log = LoggerFactory.getLogger(Topology.class);
-
+    
+    // flag to use optimized readFromDatabase() method.
+    private static final boolean enableOptimizedRead = false;
+    
     private Map<Long, Node> nodesMap;	// The dpid->Node mapping
 
     /**
@@ -392,289 +393,173 @@
      * @param dbHandler the Graph Database handler to use.
      */
     public void readFromDatabase(DBOperation dbHandler) {
-		//
-		// Fetch the relevant info from the Switch and Port vertices
-		// from the Titan Graph.
-		//
-    	nodesMap.clear();
+    	if (enableOptimizedRead) {
+    		readFromDatabaseBodyOptimized(dbHandler);
+    	} else {
+    		readFromDatabaseBody(dbHandler);
+    	}
 
-        // Load all switches into Map
-        Iterable<ISwitchObject> switches = dbHandler.getAllSwitches();
-        for (ISwitchObject switchObj : switches) {
-        	// Ignore inactive ports
-            if (!switchObj.getState().equals(SwitchState.ACTIVE.toString())) {
-            	continue;
-            }
-            Vertex nodeVertex = switchObj.asVertex();
-            //
-            // The Switch info
-            //
-            String nodeDpid = nodeVertex.getProperty("dpid").toString();
-            long nodeId = HexString.toLong(nodeDpid);
-            addNode(nodeId);
-        }
-
-        //
-        // Get All Ports
-        //
-        Iterable<IPortObject> ports = dbHandler.getAllPorts(); //TODO: Add to DB operations
-        for (IPortObject myPortObj : ports) {
-            Vertex myPortVertex = myPortObj.asVertex();
-
-            // Ignore inactive ports
-            if (! myPortVertex.getProperty("state").toString().equals("ACTIVE")) {
-            	continue;
-            }
-
-            short myPort = 0;
-            String idStr = myPortObj.getPortId();
-            String[] splitter = idStr.split(IDBOperation.PORT_ID_DELIM);
-            if (splitter.length != 2) {
-            	log.error("Invalid port_id : {}", idStr);
-            	continue;
-            }
-            String myDpid = splitter[0];
-            myPort = Short.parseShort(splitter[1]);
-            long myId = HexString.toLong(myDpid);
-            Node me = nodesMap.get(myId);
-
-            if (me == null) {
-                // cannot proceed ports and switches are out of sync
-                //TODO: Restart the whole read
-                continue;
-            }
-
-            if (me.getPort(myPort) == null) {
-            	me.addPort(myPort);
-            } else if (me.getLink(myPort) != null) {
-                // Link already added..probably by neighbor
-                continue;
-            }
-
-            //
-            // The neighbor Port info
-            //
-            for (Vertex neighborPortVertex : myPortVertex.getVertices(Direction.OUT, "link")) {
-//            	log.debug("state : {}", neighborPortVertex.getProperty("state"));
-//            	log.debug("port id : {}", neighborPortVertex.getProperty("port_id"));
-                // Ignore inactive ports
-                if (! neighborPortVertex.getProperty("state").toString().equals("ACTIVE")) {
-                	continue;
-                }
-                int neighborPort = 0;
-                idStr = neighborPortVertex.getProperty("port_id").toString();
-                splitter = idStr.split(IDBOperation.PORT_ID_DELIM);
-                if (splitter.length != 2) {
-                	log.error("Invalid port_id : {}", idStr);
-                	continue;
-                }
-                String neighborDpid = splitter[0];
-                neighborPort = Short.parseShort(splitter[1]);
-                long neighborId = HexString.toLong(neighborDpid);
-                Node neighbor = nodesMap.get(neighborId);
-//                log.debug("dpid {},{}  port {}", neighborDpid, neighborId, neighborPort);
-                if (neighbor == null) {
-                	continue;
-                }
-                me.addLink(myPort, neighbor, neighborPort);
-            }
-        }
-        dbHandler.commit();
     }
 
-
-    // Only for debug use
-    List<Long> logGetSw = new ArrayList<Long>(100);
-    List<Long> logGetPt = new ArrayList<Long>(100);
-    List<Long> logAddSw = new ArrayList<Long>(100);
-    List<Long> logAddPt = new ArrayList<Long>(100);
-    List<Long> logAddLk = new ArrayList<Long>(100);
-    List<Long> logCommit = new ArrayList<Long>(100);
-    List<Integer> logGetVertices = new ArrayList<Integer>(100);
-    List<Integer> logGetProperty = new ArrayList<Integer>(100);
-       public void readFromDatabaseBreakdown(DBOperation dbHandler) {
-    	int getVerticesCount = 0;
-    	int getPropertyCount = 0;
-    	int getVCount_sw = 0;
-    	int getVCount_pt = 0;
-    	int getVCount_lk = 0;
-    	int getPCount_sw = 0;
-    	int getPCount_pt = 0;
-    	int getPCount_lk = 0;
-
-		//
-		// Fetch the relevant info from the Switch and Port vertices
-		// from the Titan Graph.
-		//
+    private void readFromDatabaseBody(DBOperation dbHandler) {
+    	//
+    	// Fetch the relevant info from the Switch and Port vertices
+    	// from the Titan Graph.
+    	//
 
     	nodesMap.clear();
-    	long t1 = System.nanoTime();
+    	Iterable<ISwitchObject> activeSwitches = dbHandler.getActiveSwitches();
+    	for (ISwitchObject switchObj : activeSwitches) {
+    	    Vertex nodeVertex = switchObj.asVertex();
+    	    //
+    	    // The Switch info
+    	    //
+    	    String nodeDpid = nodeVertex.getProperty("dpid").toString();
+    	    long nodeId = HexString.toLong(nodeDpid);
+    	    Node me = nodesMap.get(nodeId);
+    	    if (me == null)
+    		me = addNode(nodeId);
 
-        // Load all switches into Map
-        Iterable<ISwitchObject> switches = dbHandler.getAllSwitches();
+    	    //
+    	    // The local Port info
+    	    //
+    	    for (Vertex myPortVertex : nodeVertex.getVertices(Direction.OUT, "on")) {
+    		// Ignore inactive ports
+    		if (! myPortVertex.getProperty("state").toString().equals("ACTIVE"))
+    		    continue;
 
-        long t2 = System.nanoTime();
+    		int myPort = 0;
+    		Object obj = myPortVertex.getProperty("number");
+    		if (obj instanceof Short) {
+    		    myPort = (Short)obj;
+    		} else if (obj instanceof Integer) {
+    		    myPort = (Integer)obj;
+    		}
+    		me.addPort(myPort);
 
-        long t_addSw = 0;
-        for (ISwitchObject switchObj : switches) {
-            long t3 = System.nanoTime();
-            long t4;
+    		for (Vertex neighborPortVertex : myPortVertex.getVertices(Direction.OUT, "link")) {
+    		    // Ignore inactive ports
+    		    if (! neighborPortVertex.getProperty("state").toString().equals("ACTIVE")) {
+    		    	continue;
+    		    }
 
-        	// Ignore inactive ports
-            ++getPropertyCount;
-            ++getPCount_sw;
-            if (!switchObj.getState().equals(SwitchState.ACTIVE.toString())) {
-                t4 = System.nanoTime();
-                t_addSw += t4 - t3;
-            	continue;
-            }
-            Vertex nodeVertex = switchObj.asVertex();
-            //
-            // The Switch info
-            //
-            ++getPropertyCount;
-            ++getPCount_sw;
-            String nodeDpid = nodeVertex.getProperty("dpid").toString();
-            long nodeId = HexString.toLong(nodeDpid);
-            addNode(nodeId);
-            t4 = System.nanoTime();
-            t_addSw += t4 - t3;
-        }
+    		    int neighborPort = 0;
+    		    obj = neighborPortVertex.getProperty("number");
+    		    if (obj instanceof Short) {
+    			neighborPort = (Short)obj;
+    		    } else if (obj instanceof Integer) {
+    			neighborPort = (Integer)obj;
+    		    }
+    		    //
+    		    // The neighbor Switch info
+    		    //
+    		    for (Vertex neighborVertex : neighborPortVertex.getVertices(Direction.IN, "on")) {
+    			// Ignore inactive switches
+    			String state = neighborVertex.getProperty("state").toString();
+    			if (! state.equals(SwitchState.ACTIVE.toString()))
+    			    continue;
 
-        long t5 = System.nanoTime();
-        //
-        // Get All Ports
-        //
-        Iterable<IPortObject> ports = dbHandler.getAllPorts(); //TODO: Add to DB operations
-
-        long t6 = System.nanoTime();
-        long t_addPort = 0;
-        long t_addLink = 0;
-
-        for (IPortObject myPortObj : ports) {
-            long t7 = System.nanoTime();
-            long t8;
-            Vertex myPortVertex = myPortObj.asVertex();
-
-            // Ignore inactive ports
-            ++getPropertyCount;
-            ++getPCount_pt;
-            if (! myPortVertex.getProperty("state").toString().equals("ACTIVE")) {
-                t8 = System.nanoTime();
-                t_addPort += t8 - t7;
-            	continue;
-            }
-
-            short myPort = 0;
-            ++getPropertyCount;
-            ++getPCount_pt;
-            String idStr = myPortObj.getPortId();
-            String[] splitter = idStr.split(IDBOperation.PORT_ID_DELIM);
-            if (splitter.length != 2) {
-            	log.error("Invalid port_id : {}", idStr);
-                t8 = System.nanoTime();
-                t_addPort += t8 - t7;
-            	continue;
-            }
-            String myDpid = splitter[0];
-            myPort = Short.parseShort(splitter[1]);
-            long myId = HexString.toLong(myDpid);
-            Node me = nodesMap.get(myId);
-
-            if (me == null) {
-                // cannot proceed ports and switches are out of sync
-                //TODO: Restart the whole read
-                t8 = System.nanoTime();
-                t_addPort += t8 - t7;
-                continue;
-            }
-
-            if (me.getPort(myPort) == null) {
-            	me.addPort(myPort);
-            } else if (me.getLink(myPort) != null) {
-                // Link already added..probably by neighbor
-                t8 = System.nanoTime();
-                t_addPort += t8 - t7;
-                continue;
-            }
-            t8 = System.nanoTime();
-            t_addPort += t8 - t7;
-
-            //
-            // The neighbor Port info
-            //
-            ++getVerticesCount;
-            ++getVCount_pt;
-            for (Vertex neighborPortVertex : myPortVertex.getVertices(Direction.OUT, "link")) {
-//            	log.debug("state : {}", neighborPortVertex.getProperty("state"));
-//            	log.debug("port id : {}", neighborPortVertex.getProperty("port_id"));
-
-                long t9 = System.nanoTime();
-                long t10;
-
-                // Ignore inactive ports
-                ++getPropertyCount;
-                ++getPCount_lk;
-                if (! neighborPortVertex.getProperty("state").toString().equals("ACTIVE")) {
-                    t10 = System.nanoTime();
-                    t_addLink += t10 - t9;
-                	continue;
-                }
-                int neighborPort = 0;
-                ++getPropertyCount;
-                ++getPCount_lk;
-                idStr = neighborPortVertex.getProperty("port_id").toString();
-                splitter = idStr.split(IDBOperation.PORT_ID_DELIM);
-                if (splitter.length != 2) {
-                	log.error("Invalid port_id : {}", idStr);
-                    t10 = System.nanoTime();
-                    t_addLink += t10 - t9;
-                	continue;
-                }
-                String neighborDpid = splitter[0];
-                neighborPort = Short.parseShort(splitter[1]);
-                long neighborId = HexString.toLong(neighborDpid);
-                Node neighbor = nodesMap.get(neighborId);
-//                log.debug("dpid {},{}  port {}", neighborDpid, neighborId, neighborPort);
-                if (neighbor == null) {
-                    t10 = System.nanoTime();
-                    t_addLink += t10 - t9;
-                	continue;
-                }
-                me.addLink(myPort, neighbor, neighborPort);
-
-                t10 = System.nanoTime();
-                t_addLink += t10 - t9;
-            }
-        }
-        long t11 = System.nanoTime();
-        dbHandler.commit();
-        long t12 = System.nanoTime();
-
-        logGetSw.add((t2-t1)/1000);
-        logGetPt.add((t6-t5)/1000);
-        logAddSw.add(t_addSw/1000);
-        logAddPt.add(t_addPort/1000);
-        logAddLk.add(t_addLink/1000);
-        logCommit.add((t12-t11)/1000);
-        logGetVertices.add(getVerticesCount);
-        logGetProperty.add(getPropertyCount);
-        log.debug("getVertices[N({}),P({}),L({})] getProperty[N({}),P({}),L({})]",
-        		new Object[]{getVCount_sw,getVCount_pt,getVCount_lk,
-        		getPCount_sw,getPCount_pt,getPCount_lk});
+    			String neighborDpid = neighborVertex.getProperty("dpid").toString();
+    			long neighborId = HexString.toLong(neighborDpid);
+    			Node neighbor = nodesMap.get(neighborId);
+    			if (neighbor == null)
+    			    neighbor = addNode(neighborId);
+    			neighbor.addPort(neighborPort);
+    			me.addLink(myPort, neighbor, neighborPort);
+    		    }
+    		}
+    	    }
+    	}
+    	dbHandler.commit();
     }
 
-    public void printMeasuredLog() {
-    	log.debug("getsw: {}", StringUtils.join(logGetSw, ","));
-    	log.debug("getpt: {}", StringUtils.join(logGetPt, ","));
-    	log.debug("addsw: {}", StringUtils.join(logAddSw, ","));
-    	log.debug("addpt: {}", StringUtils.join(logAddPt, ","));
-    	log.debug("addlk: {}", StringUtils.join(logAddLk, ","));
-    	log.debug("commit: {}", StringUtils.join(logCommit, ","));
-    	log.debug("getvertices: {}", StringUtils.join(logGetVertices, ","));
-    	log.debug("getproperty: {}", StringUtils.join(logGetProperty, ","));
+    private void readFromDatabaseBodyOptimized(DBOperation dbHandler) {
+	    nodesMap.clear();
+		    
+		// Load all switches into Map
+		Iterable<ISwitchObject> switches = dbHandler.getAllSwitches();
+		for (ISwitchObject switchObj : switches) {
+		        // Ignore inactive ports
+		    if (!switchObj.getState().equals(SwitchState.ACTIVE.toString())) {
+	            continue;
+		    }
+		    Vertex nodeVertex = switchObj.asVertex();
+		    //
+		    // The Switch info
+		    //
+		    String nodeDpid = nodeVertex.getProperty("dpid").toString();
+		    long nodeId = HexString.toLong(nodeDpid);
+		    addNode(nodeId);
+		}
+		
+		//
+		// Get All Ports
+		//
+		Iterable<IPortObject> ports = dbHandler.getAllPorts(); //TODO: Add to DB operations
+		for (IPortObject myPortObj : ports) {
+		    Vertex myPortVertex = myPortObj.asVertex();
+		    
+		    // Ignore inactive ports
+		    if (! myPortVertex.getProperty("state").toString().equals("ACTIVE")) {
+	            continue;
+		    }
+		    
+		    short myPort = 0;
+		    String idStr = myPortObj.getPortId();
+		    String[] splitter = idStr.split(IDBOperation.PORT_ID_DELIM);
+		    if (splitter.length != 2) {
+	            log.error("Invalid port_id : {}", idStr);
+	            continue;
+		    }
+		    String myDpid = splitter[0];
+		    myPort = Short.parseShort(splitter[1]);
+		    long myId = HexString.toLong(myDpid);
+		    Node me = nodesMap.get(myId);
+		    
+		    if (me == null) {
+		        // cannot proceed ports and switches are out of sync
+		        //TODO: Restart the whole read
+		        continue;
+		    }
+		    
+		    if (me.getPort((int)myPort) == null) {
+	            me.addPort((int)myPort);
+		    } else if (me.getLink((int)myPort) != null) {
+		        // Link already added..probably by neighbor
+		        continue;
+		    }
+		
+		    //
+		    // The neighbor Port info
+		    //
+		    for (Vertex neighborPortVertex : myPortVertex.getVertices(Direction.OUT, "link")) {
+		        // Ignore inactive ports
+		        if (! neighborPortVertex.getProperty("state").toString().equals("ACTIVE")) {
+	                continue;
+		        }
+		        int neighborPort = 0;
+		        idStr = neighborPortVertex.getProperty("port_id").toString();
+		        splitter = idStr.split(IDBOperation.PORT_ID_DELIM);
+		        if (splitter.length != 2) {
+	                log.error("Invalid port_id : {}", idStr);
+	                continue;
+		        }
+		        String neighborDpid = splitter[0];
+		        neighborPort = Short.parseShort(splitter[1]);
+		        long neighborId = HexString.toLong(neighborDpid);                                
+		        Node neighbor = nodesMap.get(neighborId);
+		        if (neighbor == null) {
+	                continue;
+		        }
+		        if (neighbor.getPort(neighborPort) == null) {
+		        	neighbor.addPort(neighborPort);
+		        }
+		        me.addLink(myPort, neighbor, neighborPort);
+		    }
+		}
+		dbHandler.commit();
     }
-
+    
     // Only for debug use
     @Override
     public String toString() {
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java b/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
index cbc3224..a074d19 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
@@ -90,7 +90,8 @@
     /**
      * Shutdown the Topology Manager operation.
      */
-    public void finalize() {
+    @Override
+    protected void finalize() {
 	close();
     }
 
@@ -108,7 +109,7 @@
      */
     @Override
     public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-        Collection<Class<? extends IFloodlightService>> l = 
+        Collection<Class<? extends IFloodlightService>> l =
             new ArrayList<Class<? extends IFloodlightService>>();
         l.add(ITopologyNetService.class);
         return l;
@@ -120,10 +121,10 @@
      * @return the collection of implemented services.
      */
     @Override
-    public Map<Class<? extends IFloodlightService>, IFloodlightService> 
+    public Map<Class<? extends IFloodlightService>, IFloodlightService>
 			       getServiceImpls() {
         Map<Class<? extends IFloodlightService>,
-	    IFloodlightService> m = 
+	    IFloodlightService> m =
             new HashMap<Class<? extends IFloodlightService>,
 	    IFloodlightService>();
         m.put(ITopologyNetService.class, this);
@@ -136,7 +137,7 @@
      * @return the collection of modules this module depends on.
      */
     @Override
-    public Collection<Class<? extends IFloodlightService>> 
+    public Collection<Class<? extends IFloodlightService>>
                                                     getModuleDependencies() {
 	Collection<Class<? extends IFloodlightService>> l =
 	    new ArrayList<Class<? extends IFloodlightService>>();
@@ -200,6 +201,7 @@
      *
      * @return the allocated topology handler.
      */
+    @Override
     public Topology newDatabaseTopology() {
 	Topology topology = new Topology();
 	topology.readFromDatabase(dbHandler);
@@ -216,6 +218,7 @@
      *
      * @param topology the topology to release.
      */
+    @Override
     public void dropTopology(Topology topology) {
 	topology = null;
     }
@@ -312,6 +315,7 @@
      * @return the data path with the computed shortest path if
      * found, otherwise null.
      */
+    @Override
     public DataPath getTopologyShortestPath(Topology topology,
 					    SwitchPort src, SwitchPort dest) {
 	return ShortestPath.getTopologyShortestPath(topology, src, dest);
diff --git a/src/test/java/net/onrc/onos/graph/GraphDBConnectionTest.java b/src/test/java/net/onrc/onos/graph/GraphDBConnectionTest.java
deleted file mode 100644
index b50f889..0000000
--- a/src/test/java/net/onrc/onos/graph/GraphDBConnectionTest.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/**
- * 
- */
-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 {
-	}
-
-	
-	@SuppressWarnings("unchecked")
-	private void expectDBConnectionAvailable() throws Exception {
-		isGraphOpen = false;
-		
-		// create mock objects
-		mockStatic(TitanFactory.class);
-		mockStatic(EventTransactionalGraph.class);
-		graph = createMock(TitanGraph.class);
-		eg = (EventTransactionalGraph<TitanGraph>)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.createKeyIndex("ipv4_address", 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/graph/GraphDBOperationTest.java b/src/test/java/net/onrc/onos/graph/GraphDBOperationTest.java
deleted file mode 100644
index b40d2af..0000000
--- a/src/test/java/net/onrc/onos/graph/GraphDBOperationTest.java
+++ /dev/null
@@ -1,648 +0,0 @@
-/**
- * 
- */
-package net.onrc.onos.graph;
-
-import static org.junit.Assert.assertArrayEquals;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import junit.framework.TestCase;
-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.IIpv4Address;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
-import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
-import net.onrc.onos.ofcontroller.util.FlowEntryId;
-import net.onrc.onos.ofcontroller.util.FlowId;
-
-import org.easymock.EasyMock;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-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.google.common.net.InetAddresses;
-import com.thinkaurelius.titan.core.TitanFactory;
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.tinkerpop.blueprints.Vertex;
-
-/**
- * @author Toshio Koide
- *
- */
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class})
-public class GraphDBOperationTest extends TestCase {
-	private static TitanGraph testdb;
-	private static GraphDBOperation op;
-
-	/**
-	 * @throws java.lang.Exception
-	 */
-	@BeforeClass
-	public static void setUpBeforeClass() throws Exception {
-	}
-
-	/**
-	 * @throws java.lang.Exception
-	 */
-	@AfterClass
-	public static void tearDownAfterClass() throws Exception {
-	}
-
-	/**
-	 * @throws java.lang.Exception
-	 */
-	@Before
-	public void setUp() throws Exception {
-		TestDatabaseManager.deleteTestDatabase();
-		testdb = TestDatabaseManager.getTestDatabase();
-//		TestDatabaseManager.populateTestData(titanGraph);
-
-		String dummyPath = "/dummy/to/conf";
-		// replace return value of TitanFactory.open() to dummy DB created above
-		PowerMock.mockStatic(TitanFactory.class);
-		EasyMock.expect(TitanFactory.open(dummyPath)).andReturn(testdb);
-		PowerMock.replay(TitanFactory.class);
-		
-		op = new GraphDBOperation(dummyPath);
-	}
-
-	/**
-	 * @throws java.lang.Exception
-	 */
-	@After
-	public void tearDown() throws Exception {
-		op.close();
-		testdb.shutdown();
-		PowerMock.verifyAll();
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#newSwitch(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testNewSwitch() {
-		assertNull(op.searchSwitch("123"));
-
-		ISwitchObject sw = op.newSwitch("123");
-		assertEquals(sw.getDPID(), "123");
-		op.commit();
-
-		sw = op.searchSwitch("123");
-		assertNotNull(sw);
-		assertEquals("123", sw.getDPID());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchSwitch(net.onrc.onos.graph.GraphDBConnection, java.lang.String)}.
-	 */
-	@Test
-	public final void testSearchSwitch() {
-		op.newSwitch("123");
-		op.newSwitch("456");
-		op.commit();
-
-		ISwitchObject sw = op.searchSwitch("123");
-		assertNotNull(sw);
-		assertEquals("123", sw.getDPID());
-
-		sw = op.searchSwitch("789");
-		assertNull(sw);
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchActiveSwitch(net.onrc.onos.graph.GraphDBConnection, java.lang.String)}.
-	 */
-	@Test
-	public final void testSearchActiveSwitch() {
-		op.newSwitch("111").setState(SwitchState.ACTIVE.toString());
-		op.newSwitch("222").setState(SwitchState.INACTIVE.toString());
-		op.commit();
-		
-		ISwitchObject sw = op.searchActiveSwitch("111");
-		assertNotNull(sw);
-		assertEquals("111", sw.getDPID());
-		
-		sw = op.searchActiveSwitch("222");
-		assertNull(sw);	
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getActiveSwitches(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testGetActiveSwitches() {
-		op.newSwitch("111").setState(SwitchState.ACTIVE.toString());
-		op.newSwitch("222").setState(SwitchState.INACTIVE.toString());
-		op.commit();
-		
-		Iterator<ISwitchObject> i = op.getActiveSwitches().iterator();
-		
-		assertTrue(i.hasNext());
-		assertEquals("111", i.next().getDPID());
-		assertFalse(i.hasNext());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getAllSwitches(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testGetAllSwitches() {
-		List<String> dpids = Arrays.asList("111", "222", "333");
-		Collections.sort(dpids);
-		
-		for (String dpid: dpids) op.newSwitch(dpid);
-		op.commit();
-
-		List<String> actual_ids = new ArrayList<String>();
-		for (ISwitchObject switchObj: op.getAllSwitches()) actual_ids.add(switchObj.getDPID());
-		Collections.sort(actual_ids);
-
-		assertArrayEquals(dpids.toArray(), actual_ids.toArray());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getInactiveSwitches(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testGetInactiveSwitches() {
-		op.newSwitch("111").setState(SwitchState.ACTIVE.toString());
-		op.newSwitch("222").setState(SwitchState.INACTIVE.toString());
-		op.commit();
-		
-		Iterator<ISwitchObject> i = op.getInactiveSwitches().iterator();
-		
-		assertTrue(i.hasNext());
-		assertEquals("222", i.next().getDPID());
-		assertFalse(i.hasNext());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getAllSwitchNotUpdatedFlowEntries(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testGetAllSwitchNotUpdatedFlowEntries() {
-		FlowEntryId flowEntryId10 = new FlowEntryId(10);
-		FlowEntryId flowEntryId20 = new FlowEntryId(20);
-		IFlowEntry flowEntry10 = op.newFlowEntry();
-		IFlowEntry flowEntry20 = op.newFlowEntry();
-		flowEntry10.setFlowEntryId(flowEntryId10.toString());
-		flowEntry20.setFlowEntryId(flowEntryId20.toString());
-		flowEntry10.setSwitchState("FE_SWITCH_NOT_UPDATED");
-		flowEntry20.setSwitchState("FE_SWITCH_UPDATED");
- 		op.commit();
-		
-		Iterator<IFlowEntry> flowEntries = op.getAllSwitchNotUpdatedFlowEntries().iterator();
-		assertNotNull(flowEntries);
-		assertTrue(flowEntries.hasNext());
-		assertEquals(flowEntryId10.toString(), flowEntries.next().getFlowEntryId());
-		assertFalse(flowEntries.hasNext());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#removeSwitch(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject)}.
-	 */
-	@Test
-	public final void testRemoveSwitch() {
-		ISwitchObject sw = op.newSwitch("123");
-		op.commit();	
-		sw = op.searchSwitch("123");
-		assertNotNull(sw);
-
-		op.removeSwitch(sw);
-		op.commit();
-		
-		assertNull(op.searchSwitch("123"));
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#newPort(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testNewPort() {
-		assertFalse(testdb.getVertices("type", "port").iterator().hasNext());
-		
-		IPortObject port = op.newPort("1", (short) 10);
-		assertTrue(port.getNumber() == 10);
-		op.commit();
-		
-		Iterator<Vertex> vertices = testdb.getVertices("type", "port").iterator();
-		assertTrue(vertices.hasNext());
-		assertEquals(vertices.next().getProperty("number").toString(), "10");		
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchPort(net.onrc.onos.graph.GraphDBConnection, java.lang.String, short)}.
-	 */
-	@Test
-	public final void testSearchPort() {
-		ISwitchObject sw;
-		IPortObject port;
-		
-		sw = op.newSwitch("1");
-		sw.addPort(op.newPort("1", (short) 1));
-		sw.addPort(op.newPort("1", (short) 2));
-		
-		sw = op.newSwitch("2");
-		sw.addPort(op.newPort("2", (short) 1));
-		sw.addPort(op.newPort("2", (short) 2));
-
-		op.commit();
-
-		assertNull(op.searchPort("3", (short) 1));
-		assertNull(op.searchPort("1", (short) 3));
-
-		port = op.searchPort("1", (short) 1);
-		assertNotNull(port);
-		assertTrue(port.getNumber() == 1);
-		sw = port.getSwitch();
-		assertNotNull(sw);
-		assertEquals("1", sw.getDPID());
-
-		port = op.searchPort("1", (short) 2);
-		assertNotNull(port);
-		assertTrue(port.getNumber() == 2);
-		sw = port.getSwitch();
-		assertNotNull(sw);
-		assertEquals("1", sw.getDPID());
-
-		port = op.searchPort("2", (short) 1);
-		assertNotNull(port);
-		assertTrue(port.getNumber() == 1);
-		sw = port.getSwitch();
-		assertNotNull(sw);
-		assertEquals("2", sw.getDPID());
-
-		port = op.searchPort("2", (short) 2);
-		assertNotNull(port);
-		assertTrue(port.getNumber() == 2);
-		sw = port.getSwitch();
-		assertNotNull(sw);
-		assertEquals("2", sw.getDPID());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#removePort(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject)}.
-	 */
-	@Test
-	public final void testRemovePort() {
-		ISwitchObject sw;
-		IPortObject port;
-		
-		sw = op.newSwitch("1");
-		sw.addPort(op.newPort("1", (short) 1));
-		sw.addPort(op.newPort("1", (short) 2));
-		
-		op.commit();
-
-		port = op.searchPort("1", (short) 1);
-		assertNotNull(port);
-		assertNotNull(op.searchPort("1", (short) 2));
-		assertNull(op.searchPort("1", (short) 3));
-
-		op.removePort(port);
-		op.commit();
-		
-		assertNull(op.searchPort("1", (short) 1));
-		port = op.searchPort("1", (short) 2);
-		assertNotNull(port);
-		
-		op.removePort(port);
-		op.commit();
-
-		assertNull(op.searchPort("1", (short) 1));
-		assertNull(op.searchPort("1", (short) 2));
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#newDevice(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testNewDevice() {
-		assertFalse(testdb.getVertices("type", "device").iterator().hasNext());
-		
-		IDeviceObject device = op.newDevice();
-		device.setMACAddress("11:22:33:44:55:66");
-		//device.setIPAddress("192.168.1.1");
-		op.commit();
-		
-		Iterator<Vertex> vertices = testdb.getVertices("type", "device").iterator();
-		assertTrue(vertices.hasNext());
-		Vertex v = vertices.next();
-		assertEquals("11:22:33:44:55:66", v.getProperty("dl_addr").toString());
-		//assertEquals("192.168.1.1", v.getProperty("nw_addr").toString());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchDevice(net.onrc.onos.graph.GraphDBConnection, java.lang.String)}.
-	 */
-	@Test
-	public final void testSearchDevice() {
-		assertNull(op.searchDevice("11:22:33:44:55:66"));
-		assertNull(op.searchDevice("66:55:44:33:22:11"));
-
-		op.newDevice().setMACAddress("11:22:33:44:55:66");
-		op.commit();
-		
-		IDeviceObject device = op.searchDevice("11:22:33:44:55:66");
-		assertNotNull(device);
-		assertEquals("11:22:33:44:55:66", device.getMACAddress());
-		
-		assertNull(op.searchDevice("66:55:44:33:22:11"));
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getDevices(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testGetDevices() {
-		List<String> original_macs = Arrays.asList(
-				"11:11:11:11:11:11",
-				"22:22:22:22:22:22",
-				"33:33:33:33:33:33"
-				);
-		
-		for (String mac: original_macs) op.newDevice().setMACAddress(mac);
-		op.commit();
-		
-		Iterable<IDeviceObject> devices = op.getDevices();
-		List<String> macs = new ArrayList<String>();
-		for (IDeviceObject device: devices) macs.add(device.getMACAddress());
-		Collections.sort(macs);
-		assertArrayEquals(original_macs.toArray(), macs.toArray());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#removeDevice(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject)}.
-	 */
-	@Test
-	public final void testRemoveDevice() {
-		op.newDevice().setMACAddress("11:22:33:44:55:66");
-		op.commit();
-		
-		op.removeDevice(op.searchDevice("11:22:33:44:55:66"));
-		op.commit();
-		assertNull(op.searchDevice("11:22:33:44:55:66"));
-	}
-	
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#newIpv4Address(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IIpv4Address)}.
-	 */
-	@Test
-	public final void testNewIpv4Address() {
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.10.1"));
-		
-		assertFalse(testdb.getVertices("type", "ipv4Address").iterator().hasNext());
-		
-		IIpv4Address ipv4Address = op.newIpv4Address();
-		ipv4Address.setIpv4Address(intIpv4Address);
-		//device.setIPAddress("192.168.1.1");
-		op.commit();
-		
-		Iterator<Vertex> vertices = testdb.getVertices("type", "ipv4Address").iterator();
-		assertTrue(vertices.hasNext());
-		Vertex v = vertices.next();
-		assertEquals(intIpv4Address, ((Integer) v.getProperty("ipv4_address")).intValue());
-	}
-	
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchIpv4Address(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IIpv4Address)}.
-	 */
-	@Test
-	public final void testSearchIpv4Address() {
-		int addr1 = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.20.1"));
-		int addr2 = InetAddresses.coerceToInteger(InetAddresses.forString("59.203.2.15"));
-		
-		assertNull(op.searchIpv4Address(addr1));
-		assertNull(op.searchIpv4Address(addr2));
-
-		op.newIpv4Address().setIpv4Address(addr1);
-		op.commit();
-		
-		IIpv4Address ipv4Address = op.searchIpv4Address(addr1);
-		assertNotNull(ipv4Address);
-		assertEquals(addr1, ipv4Address.getIpv4Address());
-		
-		assertNull(op.searchIpv4Address(addr2));
-	}
-	
-	@Ignore
-	@Test
-	public final void testEnsureIpv4Address() {
-		// TODO not yet implemented
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#newFlowPath(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testNewFlowPath() {
-		FlowId flowId = new FlowId(10);
-		IFlowPath flowPath = op.newFlowPath();
-		flowPath.setFlowId(flowId.toString());
-		op.commit();
-
-		Iterator<IFlowPath> flows = op.getAllFlowPaths().iterator();
-		assertTrue(flows.hasNext());
-		assertEquals(flowId.toString(), flows.next().getFlowId());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchFlowPath(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.util.FlowId)}.
-	 */
-	@Test
-	public final void testSearchFlowPath() {
-		FlowId flowId = new FlowId(20);
-		assertNull(op.searchFlowPath(flowId));
-
-		op.newFlowPath().setFlowId(flowId.toString());
-		op.commit();
-		
-		IFlowPath flowPath = op.searchFlowPath(flowId);
-		assertNotNull(flowPath);
-		assertEquals(flowId.toString(), flowPath.getFlowId());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getFlowPathByFlowEntry(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry)}.
-	 */
-	@Test
-	public final void testGetFlowPathByFlowEntry() {
-		FlowId flowId10 = new FlowId(10);
-		FlowId flowId20 = new FlowId(20);
-		IFlowPath flowPath10 = op.newFlowPath();
-		IFlowPath flowPath20 = op.newFlowPath();
-		IFlowEntry flowEntry10 = op.newFlowEntry();
-		IFlowEntry flowEntry20 = op.newFlowEntry();
-		IFlowEntry flowEntry30 = op.newFlowEntry();
-		FlowEntryId flowEntryId10 = new FlowEntryId(10); 
-		FlowEntryId flowEntryId20 = new FlowEntryId(20); 
-		FlowEntryId flowEntryId30 = new FlowEntryId(30); 
-		flowEntry10.setFlowEntryId(flowEntryId10.toString());
-		flowEntry20.setFlowEntryId(flowEntryId20.toString());
-		flowEntry30.setFlowEntryId(flowEntryId30.toString());
-		flowPath10.setFlowId(flowId10.toString());
-		flowPath10.addFlowEntry(flowEntry10);
-		flowPath20.setFlowId(flowId20.toString());
-		flowPath20.addFlowEntry(flowEntry20);
-		op.commit();
-
-		flowEntry10 = op.searchFlowEntry(flowEntryId10);
-		IFlowPath obtainedFlowPath = op.getFlowPathByFlowEntry(flowEntry10);
-		assertNotNull(obtainedFlowPath);
-		assertEquals(flowId10.toString(), obtainedFlowPath.getFlowId());
-		
-		flowEntry20 = op.searchFlowEntry(flowEntryId20);
-		obtainedFlowPath = op.getFlowPathByFlowEntry(flowEntry20);
-		assertNotNull(obtainedFlowPath);
-		assertEquals(flowId20.toString(), obtainedFlowPath.getFlowId());
-		
-		flowEntry30 = op.searchFlowEntry(flowEntryId30);
-		obtainedFlowPath = op.getFlowPathByFlowEntry(flowEntry30);
-		assertNull(obtainedFlowPath);
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getAllFlowPaths(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testGetAllFlowPaths() {
-		List<FlowId> flowids = Arrays.asList(
-				new FlowId(10), new FlowId(20), new FlowId(30)
-				);
-		
-		for (FlowId flowId: flowids)
-			op.newFlowPath().setFlowId(flowId.toString());
-		op.commit();
-
-		List<String> actual_ids = new ArrayList<String>();
-		for (IFlowPath flowPath: op.getAllFlowPaths()) actual_ids.add(flowPath.getFlowId());
-		Collections.sort(actual_ids);
-
-		List<String> expected_ids = new ArrayList<String>();
-		for (FlowId flowid: flowids) expected_ids.add(flowid.toString());
-		Collections.sort(expected_ids);
-		
-		assertArrayEquals(expected_ids.toArray(), actual_ids.toArray());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#removeFlowPath(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath)}.
-	 */
-	@Test
-	public final void testRemoveFlowPath() {
-		FlowId flowId10 = new FlowId(10);
-		FlowId flowId20 = new FlowId(20);
-		op.newFlowPath().setFlowId(flowId10.toString());
-		op.newFlowPath().setFlowId(flowId20.toString());
-		op.commit();
-		
-		IFlowPath flowPath = op.searchFlowPath(flowId10);
-		assertNotNull(flowPath);
-		op.removeFlowPath(flowPath);
-		op.commit();
-		
-		assertNull(op.searchFlowPath(flowId10));
-		assertNotNull(op.searchFlowPath(flowId20));
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#newFlowEntry(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testNewFlowEntry() {
-		IFlowEntry flowEntry = op.newFlowEntry();
-		FlowEntryId flowEntryId = new FlowEntryId();
-		flowEntryId.setValue(12345);
-		flowEntry.setFlowEntryId(flowEntryId.toString());
-		op.commit();
-		
-		flowEntry = op.searchFlowEntry(flowEntryId);
-		assertNotNull(flowEntry);
-		assertEquals(flowEntry.getFlowEntryId(), flowEntryId.toString());		
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#searchFlowEntry(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.util.FlowEntryId)}.
-	 */
-	@Test
-	public final void testSearchFlowEntry() {
-		FlowEntryId flowEntryId10 = new FlowEntryId();
-		flowEntryId10.setValue(10);
-		FlowEntryId flowEntryId20 = new FlowEntryId();
-		flowEntryId20.setValue(20);
-		FlowEntryId flowEntryId30 = new FlowEntryId();
-		flowEntryId30.setValue(30);
-		
-		op.newFlowEntry().setFlowEntryId(flowEntryId10.toString());
-		op.newFlowEntry().setFlowEntryId(flowEntryId20.toString());
-		op.commit();
-		
-		assertNull(op.searchFlowEntry(flowEntryId30));
-		IFlowEntry flowEntry = op.searchFlowEntry(flowEntryId10);
-		assertEquals(flowEntry.getFlowEntryId(), flowEntryId10.toString());
-		flowEntry = op.searchFlowEntry(flowEntryId20);
-		assertEquals(flowEntry.getFlowEntryId(), flowEntryId20.toString());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#getAllFlowEntries(net.onrc.onos.graph.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testGetAllFlowEntries() {
-		List<FlowEntryId> flowEntryIds = Arrays.asList(
-				new FlowEntryId(10), new FlowEntryId(20), new FlowEntryId(30)
-				);
-		
-		for (FlowEntryId flowEntryId: flowEntryIds)
-			op.newFlowEntry().setFlowEntryId(flowEntryId.toString());
-		op.commit();
-
-		List<String> actual_ids = new ArrayList<String>();
-		for (IFlowEntry flowEntry: op.getAllFlowEntries()) actual_ids.add(flowEntry.getFlowEntryId());
-		Collections.sort(actual_ids);
-
-		List<String> expected_ids = new ArrayList<String>();
-		for (FlowEntryId flowEntryId: flowEntryIds) expected_ids.add(flowEntryId.toString());
-		Collections.sort(expected_ids);
-		
-		assertArrayEquals(expected_ids.toArray(), actual_ids.toArray());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.graph.GraphDBOperation#removeFlowEntry(net.onrc.onos.graph.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry)}.
-	 */
-	@Test
-	public final void testRemoveFlowEntry() {
-		FlowEntryId flowEntryId10 = new FlowEntryId(10);
-		FlowEntryId flowEntryId20 = new FlowEntryId(20);
-		op.newFlowEntry().setFlowEntryId(flowEntryId10.toString());
-		op.newFlowEntry().setFlowEntryId(flowEntryId20.toString());
-		op.commit();
-		
-		IFlowEntry flowEntry = op.searchFlowEntry(flowEntryId10);
-		assertNotNull(flowEntry);
-		op.removeFlowEntry(flowEntry);
-		op.commit();
-		
-		assertNull(op.searchFlowEntry(flowEntryId10));
-		assertNotNull(op.searchFlowEntry(flowEntryId20));
-	}
-
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIDeviceObjectTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIDeviceObjectTest.java
deleted file mode 100644
index 7bd75d2..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIDeviceObjectTest.java
+++ /dev/null
@@ -1,206 +0,0 @@
-package net.onrc.onos.ofcontroller.core;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-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.IIpv4Address;
-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.powermock.modules.junit4.PowerMockRunner;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.net.InetAddresses;
-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() {
-		int ipaddr = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.0.1"));
-		IDeviceObject devObj = ope.newDevice();
-		IIpv4Address ipv4Address = ope.newIpv4Address();
-		ipv4Address.setIpv4Address(ipaddr);
-		devObj.addIpv4Address(ipv4Address);
-		assertEquals(devObj.getIpv4Address(ipaddr), ipv4Address);
-	}
-	
-	/**
-	 * 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);
-		
-		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;	
-		IPortObject portObj = ope.newPort(dpid, number);
-		
-		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
deleted file mode 100644
index f1c2c71..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowEntryTest.java
+++ /dev/null
@@ -1,476 +0,0 @@
-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 Idle Timeout.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set Idle Timeout.
-	 * 2. Should get Idle Timeout.
-	 */
-	@Test
-	public void testSetGetIdleTimeout() {
-		Integer idleTimeout = 5;
-		flowEntry.setIdleTimeout(idleTimeout);
-		assertEquals(flowEntry.getIdleTimeout(), idleTimeout);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get Hard Timeout.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set Hard Timeout.
-	 * 2. Should get Hard Timeout.
-	 */
-	@Test
-	public void testSetGetHardTimeout() {
-		Integer hardTimeout = 5;
-		flowEntry.setHardTimeout(hardTimeout);
-		assertEquals(flowEntry.getHardTimeout(), hardTimeout);
-	}
-	
-	/**
-	 * 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 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 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 MatchVlanId.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchVlanId.
-	 * 2. Should get MatchVlanId.
-	 */
-	@Test
-	public void testSetGetMatchVlanId() {
-		Short matchVlanId = 10;
-		flowEntry.setMatchVlanId(matchVlanId);
-		assertEquals(flowEntry.getMatchVlanId(), matchVlanId);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchVlanPriority.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchVlanPriority.
-	 * 2. Should get MatchVlanPriority.
-	 */
-	@Test
-	public void testSetGetMatchVlanPriority() {
-		Byte matchVlanPriority = 10;
-		flowEntry.setMatchVlanPriority(matchVlanPriority);
-		assertEquals(flowEntry.getMatchVlanPriority(), matchVlanPriority);
-	}
-	
-	/**
-	 * 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 MatchIpProto.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchIpProto.
-	 * 2. Should get MatchIpProto.
-	 */
-	@Test
-	public void testSetGetMatchIpProto() {
-		Byte matchIpProto = 20;
-		flowEntry.setMatchIpProto(matchIpProto);
-		assertEquals(flowEntry.getMatchIpProto(), matchIpProto);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchIpToS.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchIpToS.
-	 * 2. Should get MatchIpToS.
-	 */
-	@Test
-	public void testSetGetMatchIpToS() {
-		Byte matchIpToS = 20;
-		flowEntry.setMatchIpToS(matchIpToS);
-		assertEquals(flowEntry.getMatchIpToS(), matchIpToS);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchSrcTcpUdpPort.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchSrcTcpUdpPort.
-	 * 2. Should get MatchSrcTcpUdpPort.
-	 */
-	@Test
-	public void testSetGetMatchSrcTcpUdpPort() {
-		Short srcTcpUdpPort = (short)65535;
-		flowEntry.setMatchSrcTcpUdpPort(srcTcpUdpPort);
-		assertEquals(flowEntry.getMatchSrcTcpUdpPort(), srcTcpUdpPort);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchDstTcpUdpPort.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchDstTcpUdpPort.
-	 * 2. Should get MatchDstTcpUdpPort.
-	 */
-	@Test
-	public void testSetGetMatchDstTcpUdpPort() {
-		Short dstTcpUdpPort = (short)65535;
-		flowEntry.setMatchDstTcpUdpPort(dstTcpUdpPort);
-		assertEquals(flowEntry.getMatchDstTcpUdpPort(), dstTcpUdpPort);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get ActionOutputPort.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set ActionOutputPort.
-	 * 2. Should get ActionOutputPort.
-	 */
-	@Test
-	public void testSetGetActionOutputPort() {
-		Short actionOutputPort = 1;
-		flowEntry.setActionOutputPort(actionOutputPort);
-		assertEquals(flowEntry.getActionOutputPort(), actionOutputPort);
-	}
-	
-	/**
-	 * 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
deleted file mode 100644
index 39e4955..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIFlowPathTest.java
+++ /dev/null
@@ -1,563 +0,0 @@
-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 FlowPathType method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the Flow Path Type.
-	 * 2. Should get the Flow Path Type.
-	 */
-	@Test
-	public void testSetGetFlowPathType() {
-		String flowId = "xx";
-		String flowPathType = "FP_TYPE_SHORTEST_PATH";
-		flowPath.setFlowId(flowId);
-		flowPath.setFlowPathType(flowPathType);
-		assertEquals(flowPath.getFlowPathType(), flowPathType);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for get and set FlowPathUserState method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the Flow Path User State.
-	 * 2. Should get the Flow Path User State.
-	 */
-	@Test
-	public void testSetGetFlowPathUserState() {
-		String flowId = "xx";
-		String flowPathUserState = "FP_USER_ADD";
-		flowPath.setFlowId(flowId);
-		flowPath.setFlowPathUserState(flowPathUserState);
-		assertEquals(flowPath.getFlowPathUserState(), flowPathUserState);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for get and set FlowPathFlags method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the Flow Path Flags.
-	 * 2. Should get the Flow Path Flags.
-	 */
-	@Test
-	public void testSetGetFlowPathFlags() {
-		String flowId = "xx";
-		Long flowPathFlags = new Long(0x3);
-		flowPath.setFlowId(flowId);
-		flowPath.setFlowPathFlags(flowPathFlags);
-		assertEquals(flowPath.getFlowPathFlags(), flowPathFlags);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for get and set Idle Timeout method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the Idle Timeout.
-	 * 2. Should get the Idle Timeout.
-	 */
-	@Test
-	public void testSetGetIdleTimeout() {
-		String flowId = "xx";
-		Integer idleTimeout = 5;
-		flowPath.setFlowId(flowId);
-		flowPath.setIdleTimeout(idleTimeout);
-		assertEquals(flowPath.getIdleTimeout(), idleTimeout);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for get and set Hard Timeout method.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set the Hard Timeout.
-	 * 2. Should get the Hard Timeout.
-	 */
-	@Test
-	public void testSetGetHardTimeout() {
-		String flowId = "xx";
-		Integer hardTimeout = 5;
-		flowPath.setFlowId(flowId);
-		flowPath.setHardTimeout(hardTimeout);
-		assertEquals(flowPath.getHardTimeout(), hardTimeout);
-	}
-
-	/**
-	 * 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 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 MatchEthernetFrameType
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchEthernetFrameType.
-	 * 2. Should get MatchEthernetFrameType.
-	 */
-	@Test
-	public void testSetGetMatchEthernetFrameType() {
-		String flowId = "xx";
-		Short matchEthernetFrameType = 1;
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchEthernetFrameType(matchEthernetFrameType);
-		assertEquals(flowPath.getMatchEthernetFrameType(), matchEthernetFrameType);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchVlanId
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchVlanId.
-	 * 2. Should get MatchVlanId.
-	 */
-	@Test
-	public void testSetGetMatchVlanId() {
-		String flowId = "xx";
-		Short matchVlanId = 10;
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchVlanId(matchVlanId);
-		assertEquals(flowPath.getMatchVlanId(), matchVlanId);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchVlanPriority
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchVlanPriority.
-	 * 2. Should get MatchVlanPriority.
-	 */
-	@Test
-	public void testSetGetMatchVlanPriority() {
-		String flowId = "xx";
-		Byte matchVlanPriority = 20;
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchVlanPriority(matchVlanPriority);
-		assertEquals(flowPath.getMatchVlanPriority(), matchVlanPriority);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchSrcIPv4Net.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchSrcIPv4Net.
-	 * 2. Should get MatchSrcIPv4Net.
-	 */
-	@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 MatchDstIPv4Net.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchDstIPv4Net.
-	 * 2. Should get MatchDstIPv4Net.
-	 */
-	@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 MatchIpProto
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchIpProto.
-	 * 2. Should get MatchIpProto.
-	 */
-	@Test
-	public void testSetGetMatchIpProto() {
-		String flowId = "xx";
-		Byte matchIpProto = 20;
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchIpProto(matchIpProto);
-		assertEquals(flowPath.getMatchIpProto(), matchIpProto);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchIpToS
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchIpToS.
-	 * 2. Should get MatchIpToS.
-	 */
-	@Test
-	public void testSetGetMatchIpToS() {
-		String flowId = "xx";
-		Byte matchIpToS = 20;
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchIpToS(matchIpToS);
-		assertEquals(flowPath.getMatchIpToS(), matchIpToS);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchSrcTcpUdpPort.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchSrcTcpUdpPort.
-	 * 2. Should get MatchSrcTcpUdpPort.
-	 */
-	@Test
-	public void testSetGetMatchSrcTcpUdpPort() {
-		String flowId = "xx";
-		Short srcTcpUdpPort = (short)65535;
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchSrcTcpUdpPort(srcTcpUdpPort);
-		assertEquals(flowPath.getMatchSrcTcpUdpPort(), srcTcpUdpPort);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for set and get MatchDstTcpUdpPort.
-	 * Condition:
-	 *  N/A
-	 * Expect:
-	 * 1. Should set MatchDstTcpUdpPort.
-	 * 2. Should get MatchDstTcpUdpPort.
-	 */
-	@Test
-	public void testSetGetMatchDstTcpUdpPort() {
-		String flowId = "xx";
-		Short dstTcpUdpPort = (short)65535;
-		flowPath.setFlowId(flowId);
-		flowPath.setMatchDstTcpUdpPort(dstTcpUdpPort);
-		assertEquals(flowPath.getMatchDstTcpUdpPort(), dstTcpUdpPort);
-	}
-
-	/**
-	 * 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
deleted file mode 100644
index 74f9758..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsIPortObjectTest.java
+++ /dev/null
@@ -1,355 +0,0 @@
-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 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
deleted file mode 100644
index dacfdb5..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjectsISwitchObjectTest.java
+++ /dev/null
@@ -1,286 +0,0 @@
-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;
-		final int testSwitchPortNumber = 1;
-		ISwitchObject swObj = ope.newSwitch(dpid);
-		IPortObject portObj = ope.newPort(dpid, portNumber);
-
-		swObj.addPort(portObj);
-		int i = 0;
-		for(@SuppressWarnings("unused") IPortObject port : swObj.getPorts()){
-			i++;
-		}
-		assertEquals(testSwitchPortNumber, i);
-	}
-	
-	/**
-	 * 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(@SuppressWarnings("unused") 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
deleted file mode 100644
index 69c3c8a..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
+++ /dev/null
@@ -1,767 +0,0 @@
-package net.onrc.onos.ofcontroller.core.internal;
-
-import static org.junit.Assert.*;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import net.floodlightcontroller.routing.Link;
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.ILinkStorage;
-import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
-
-import org.easymock.*;
-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.OFPhysicalPort;
-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 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})
-@SuppressWarnings("serial")
-public class LinkStorageImplTest {
-	protected final static Logger log = LoggerFactory.getLogger(LinkStorageImplTest.class);
-
-	private static ILinkStorage linkStorage;
-	
-	// Mock GraphDBConnection (do nothing)
-	private static GraphDBConnection conn;
-	
-	// Mock GraphDBOperation (mocks port-related methods only)
-	private static GraphDBOperation ope;
-	
-	// Uncommitted actions executed in LinkStorageImpl
-	private static ArrayList<LinkEvent> actions;
-	
-	// Dictionary of mock IPortObject to information of port
-	// -> Used to refer DPID from IPortObject
-	private static Map<IPortObject,PortInfo> mockToPortInfoMap;
-	
-	
-	// Links existing in virtual graph
-	private List<Link> links;
-	
-	//================ Utility classes for logging actions in LinkStorageImpl ===========
-	private enum LinkEventType {
-		ADD, DELETE
-	}
-	
-	private class LinkEvent {
-		private Long src_dpid = null;
-		private Long dst_dpid = null;
-		private Short src_port = null;
-		private Short dst_port = null;
-		
-		public LinkEventType type;
-		
-		public LinkEvent(Link link, LinkEventType type) {
-			this.src_dpid = link.getSrc();
-			this.src_port = link.getSrcPort();
-			this.dst_dpid = link.getDst();
-			this.dst_port = link.getDstPort();
-			
-			this.type = type;
-		}
-
-		public Long getSrcDpid() { return src_dpid; }
-		public Short getSrcPort() { return src_port; }
-		public Long getDstDpid() { return dst_dpid; }
-		public Short getDstPort() { return dst_port; }
-		public LinkEventType getType() { return type; }
-	}
-	
-	private class PortInfo {
-		public Long dpid = null;
-		public Short port = null;
-		
-		public PortInfo(Long dpid, Short port) { this.dpid = dpid; this.port = port; }
-	}
-
-	/**
-	 * Setup code called before each tests.
-	 * Read test graph data and replace DB access by test graph data.
-	 * @throws Exception
-	 */
-	@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.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);
-		
-		actions = new ArrayList<LinkEvent>();
-		mockToPortInfoMap = new HashMap<IPortObject,PortInfo>();
-		
-		linkStorage = new LinkStorageImpl();
-		linkStorage.init("dummyStore", "/dummy/path/to/conf");
-		
-		initLinks();
-	}
-	
-	/**
-	 * Closing code called after each tests.
-	 * @throws Exception
-	 */
-	@After
-	public void tearDown() throws Exception {
-		linkStorage.close();
-	}
-	
-
-	/**
-	 * Test if {@link LinkStorageImpl#addLink(Link)} can correctly creates a Link.
-	 */
-	@Test
-	public void testAddLink() {
-		Link linkToCreate = createFeasibleLink();
-		Link linkToVerify = createFeasibleLink();
-		
-		//Use the link storage API to add the link
-		linkStorage.addLink(linkToCreate);
-		doTestLinkExist(linkToVerify);
-	}
-	
-	/**
-	 * Test if {@link LinkStorageImpl#update(List, DM_OPERATION)} can correctly creates multiple Links.
-	 */
-	@Test
-	public void testAddLinks() {
-		List<Link> linksToCreate = createFeasibleLinks();
-		List<Link> linksToVerify = createFeasibleLinks();
-	
-		// Test creation of new links
-		linkStorage.addLinks(linksToCreate);
-		for(Link l : linksToVerify) {
-			doTestLinkExist(l);
-		}
-	}
-
-	// TODO: remove @Ignore after UPDATE method is implemented
-	/**
-	 * Test if {@link LinkStorageImpl#updateLinkInfo(Link, LinkInfo, DM_OPERATION)} can correctly updates LinkInfo for a Link.
-	 */
-	@Ignore @Test
-	public void testUpdate_Update() {
-		Link linkToUpdate= createExistingLink();
-		long currentTime = System.currentTimeMillis();
-		LinkInfo infoToUpdate = createFeasibleLinkInfo(currentTime);
-		LinkInfo infoToVerify = createFeasibleLinkInfo(currentTime);
-
-		linkStorage.update(linkToUpdate, infoToUpdate, ILinkStorage.DM_OPERATION.UPDATE);
-		
-		doTestLinkHasStateOf(linkToUpdate, infoToVerify);
-	}
-	
-	/**
-	 * Test if {@link LinkStorageImpl#update(Link, DM_OPERATION)} can correctly creates a Link.
-	 */
-	@Test
-	public void testUpdate_Create() {
-		Link linkToCreate = createFeasibleLink();
-		Link linkToVerify = createFeasibleLink();
-		
-		//Use the link storage API to add the link
-		linkStorage.update(linkToCreate, null, ILinkStorage.DM_OPERATION.CREATE);
-		doTestLinkExist(linkToVerify);
-	}
-
-	/**
-	 * Test if {@link LinkStorageImpl#update(Link, DM_OPERATION)}can correctly inserts a Link.
-	 */
-	@Test
-	public void testUpdate_Insert(){
-		Link linkToInsert = createFeasibleLink();
-		Link linkToVerify = createFeasibleLink();
-		
-		//Use the link storage API to add the link
-		linkStorage.update(linkToInsert, null, ILinkStorage.DM_OPERATION.INSERT);
-		doTestLinkExist(linkToVerify);
-	}
-	
-	/**
-	 * Test if {@link LinkStorageImpl#update(Link, DM_OPERATION)} can correctly deletes a Link.
-	 */
-	@Test
-	public void testUpdate_Delete(){
-		Link linkToDelete = createExistingLink();
-		Link linkToVerify = createExistingLink();
-
-		// Test deletion of existing link
-		linkStorage.update(linkToDelete, null, DM_OPERATION.DELETE);
-		doTestLinkNotExist(linkToVerify);
-	}
-
-	/**
-	 * Test if {@link LinkStorageImpl#getLinks(Long, short)} can correctly return Links connected to specific DPID and port.
-	 */
-	@Test
-	public void testGetLinks_ByDpidPort(){
-		Link linkToVerify = createExistingLink();
-		Long dpid = linkToVerify.getSrc();
-		short port = (short)linkToVerify.getSrcPort();
-		
-		List<Link> list = linkStorage.getLinks(dpid, port);
-		
-		assertEquals(1, list.size());
-		
-		Link l = list.get(0);
-		assertEquals(l.getSrc(), linkToVerify.getSrc());
-		assertEquals(l.getSrcPort(), linkToVerify.getSrcPort());
-		assertEquals(l.getDst(), linkToVerify.getDst());
-		assertEquals(l.getDstPort(), linkToVerify.getDstPort());
-		
-		Link linkToVerifyNot = createFeasibleLink();
-		
-		List<Link> list2 = linkStorage.getLinks(linkToVerifyNot.getSrc(), (short)linkToVerifyNot.getSrcPort());
-		
-		assertEquals(0, list2.size());
-	}
-	
-	/**
-	 * Test if {@link LinkStorageImpl#getLinks(String)} can correctly return Links connected to specific MAC address.
-	 */
-	@Test
-	public void testGetLinks_ByString() {
-		Link linkToVeryfy = createExistingLink();
-		String dpid = HexString.toHexString(linkToVeryfy.getSrc());
-		
-		List<Link> links = linkStorage.getLinks(dpid);
-		assertTrue(links.contains(linkToVeryfy));
-
-		Link linkToVerifyNot = createFeasibleLink();
-		assertFalse(links.contains(linkToVerifyNot));
-	}
-
-	/**
-	 * Test if {@link LinkStorageImpl#getReverseLinks(String)} can correctly return Links connected to specific MAC address.
-	 */
-	@Test
-	public void testGetReverseLinks_ByString() {
-		Link linkToVeryfy = createExistingLink();
-		String dpid = HexString.toHexString(linkToVeryfy.getDst());
-		
-		List<Link> links = linkStorage.getReverseLinks(dpid);
-		assertTrue(links.contains(linkToVeryfy));
-
-		Link linkToVerifyNot = createFeasibleLink();
-		assertFalse(links.contains(linkToVerifyNot));
-	}
-	
-	/**
-	 * Test if {@link LinkStorageImpl#deleteLink(Link)} can correctly delete a Link.
-	 */
-	@Test
-	public void testDeleteLink() {
-		// Deletion of existing link
-		Link linkToDelete = createExistingLink();
-		Link linkToVerify = createExistingLink();
-		
-		linkStorage.deleteLink(linkToDelete);
-		doTestLinkNotExist(linkToVerify);
-	}
-	
-	/**
-	 * Test if {@link LinkStorageImpl#deleteLinks(List)} can correctly delete Links.
-	 */
-	@Test
-	public void testDeleteLinks(){
-		List<Link> linksToDelete = createExistingLinks();
-		List<Link> linksToVerify = createExistingLinks();
-		
-		linkStorage.deleteLinks(linksToDelete);
-		for(Link l : linksToVerify) {
-			doTestLinkNotExist(l);
-		}
-	}
-
-	/**
-	 * Test if {@link LinkStorageImpl#getActiveLinks()} can correctly return active Links.
-	 */
-	@Test
-	public void testGetActiveLinks() {
-		Link existingLink = createExistingLink();
-		Link notExistingLink = createFeasibleLink();
-
-		List<Link> links = linkStorage.getActiveLinks();
-		
-		assertTrue(links.contains(existingLink));
-		assertFalse(links.contains(notExistingLink));
-	}
-	
-	/**
-	 * Test if {@link LinkStorageImpl#deleteLinksOnPort(Long, short)} can delete Links.
-	 */
-	@Test
-	public void testDeleteLinksOnPort() {
-		Link linkToDelete = createExistingLink();
-		Link linkToVerify = createExistingLink();
-		
-		linkStorage.deleteLinksOnPort(linkToDelete.getSrc(), linkToDelete.getSrcPort());
-		
-		doTestLinkNotExist(linkToVerify);
-	}
-	
-	/**
-	 * Test if {@link LinkStorageImpl#getLinkInfo(Link)} can delete Links.
-	 */
-	@Ignore @Test
-	public void testGetLinkInfo() {
-		fail("not yet implemented");
-	}
-
-	/**
-	 * Test if specific link exists
-	 * @param link 
-	 */
-	private void doTestLinkExist(Link link) {
-		int count = 0;
-		for(Link lt : links) {
-			if(lt.equals(link)) {
-				++count;
-			}
-		}
-		
-		assertTrue(count == 1);
-	}
-	
-	/**
-	 * Test if specific link doesn't exist
-	 * @param link
-	 */
-	private void doTestLinkNotExist(Link link) {
-		assertFalse(links.contains(link));
-	}
-	
-	/**
-	 * 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 {@link IPortObject#removeLink(IPortObject)} is called.
-	 * @author Naoki Shiota
-	 *
-	 */
-	private class RemoveLinkCallback implements IAnswer<Object> {
-		private long dpid;
-		private short port;
-		public RemoveLinkCallback(long dpid, short port) {
-			this.dpid = dpid; this.port = port;
-		}
-		
-		@Override
-		public Object answer() throws Throwable {
-			IPortObject dstPort = (IPortObject) EasyMock.getCurrentArguments()[0];
-			PortInfo dst = mockToPortInfoMap.get(dstPort);
-
-			Link linkToRemove = new Link(this.dpid,this.port,dst.dpid,dst.port);
-			actions.add(new LinkEvent(linkToRemove,LinkEventType.DELETE));
-			
-			return null;
-		}
-	}
-	
-	/**
-	 * 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;
-		private short port;
-		public SetLinkPortCallback(long dpid, short port) {
-			this.dpid = dpid; this.port = port;
-		}
-
-		@Override
-		public Object answer() throws Throwable {
-			IPortObject dstPort = (IPortObject) EasyMock.getCurrentArguments()[0];
-			PortInfo dst = mockToPortInfoMap.get(dstPort);
-
-			Link linkToAdd = new Link(this.dpid,this.port,dst.dpid,dst.port);
-			actions.add(new LinkEvent(linkToAdd,LinkEventType.ADD));
-
-			return null;
-		}
-		
-	}
-	
-	/**
-	 * Class defines a function called back when {@link IPortObject#getSwitch()} is called.
-	 * @author Naoki Shiota
-	 *
-	 */
-	private class GetSwitchCallback implements IAnswer<ISwitchObject> {
-		private long dpid;
-		
-		public GetSwitchCallback(long dpid) {
-			this.dpid = dpid;
-		}
-
-		@Override
-		public ISwitchObject answer() throws Throwable {
-			ISwitchObject sw = createMockSwitch(dpid);
-			return sw;
-		}
-	}
-	
-	/**
-	 * Class defines a function called back when {@link IPortObject#getLinkedPorts()} is called.
-	 * @author Naoki Shiota
-	 *
-	 */
-	private class GetLinkedPortsCallback implements IAnswer< Iterable<IPortObject> > {
-		private long dpid;
-		private short port;
-		
-		public GetLinkedPortsCallback(long dpid, short port) {
-			this.dpid = dpid;
-			this.port = port;
-		}
-
-		@Override
-		public Iterable<IPortObject> answer() throws Throwable {
-			List<IPortObject> ports = new ArrayList<IPortObject>();
-
-			for(Link lk : links) {
-				if(lk.getSrc() == dpid && lk.getSrcPort() == port) {
-					ports.add(createMockPort(lk.getDst(), lk.getDstPort()));
-				}
-			}
-
-			return ports;
-		}
-		
-	}
-
-	/**
-	 * Class defines a function called back when {@link IPortObject#getReverseLinkedPorts()} is called.
-	 * @author Naoki Shiota
-	 *
-	 */
-	private class GetReverseLinkedPortsCallback implements IAnswer< Iterable<IPortObject> > {
-		private long dpid;
-		private short port;
-		
-		public GetReverseLinkedPortsCallback(long dpid, short port) {
-			this.dpid = dpid;
-			this.port = port;
-		}
-
-		@Override
-		public Iterable<IPortObject> answer() throws Throwable {
-			List<IPortObject> ports = new ArrayList<IPortObject>();
-
-			for(Link lk : links) {
-				if(lk.getDst() == dpid && lk.getDstPort() == port) {
-					ports.add(createMockPort(lk.getSrc(), lk.getSrcPort()));
-				}
-			}
-
-			return ports;
-		}
-		
-	}
-
-	/**
-	 * Class defines a function called back when {@link LinkStorageImplTest} is called.
-	 * @author Naoki Shiota
-	 *
-	 */
-	private class GetPortsCallback implements IAnswer< Iterable <IPortObject> > {
-		private long dpid;
-		
-		public GetPortsCallback(long dpid) {
-			this.dpid = dpid;
-		}
-		
-		@Override
-		public Iterable<IPortObject> answer() throws Throwable {
-			List<IPortObject> ports = new ArrayList<IPortObject>();
-			
-			for(Short number : getPorts(dpid)) {
-				ports.add(createMockPort(dpid, number));
-			}
-
-			return ports;
-		}
-	}
-
-	// ------------------------Creation of Mock-----------------------------
-	/**
-	 * Create a mock {@link GraphDBOperation} which hooks port-related methods.
-	 * @return EasyMock-wrapped GraphDBOperation object.
-	 */
-	private GraphDBOperation createMockGraphDBOperation() {
-		GraphDBOperation mockDBOpe = EasyMock.createNiceMock(GraphDBOperation.class);
-		
-		// Mock searchPort() method to create new mock IPortObject.
-		EasyMock.expect(mockDBOpe.searchPort((String)EasyMock.anyObject(), EasyMock.anyShort())).
-			andAnswer(new IAnswer<IPortObject>() {
-			@Override
-			public IPortObject answer() throws Throwable {
-				long dpid = HexString.toLong((String)EasyMock.getCurrentArguments()[0]);
-				short port = (Short) EasyMock.getCurrentArguments()[1];
-				IPortObject ret = createMockPort(dpid,port);
-				
-				return ret;
-			}
-		}).anyTimes();
-		
-		// Mock searchSwitch() method to create new mock ISwitchObject.
-		EasyMock.expect(mockDBOpe.searchSwitch((String)EasyMock.anyObject())).
-			andAnswer(new IAnswer<ISwitchObject>() {
-			@Override
-			public ISwitchObject answer() throws Throwable {
-				long dpid = HexString.toLong((String)EasyMock.getCurrentArguments()[0]);
-				ISwitchObject ret = createMockSwitch(dpid);
-				
-				return ret;
-			}
-		}).anyTimes();
-		
-		// Mock getActiveSwitches() method to create list of mock ISwitchObject.
-		EasyMock.expect(mockDBOpe.getActiveSwitches()).andReturn(new ArrayList<ISwitchObject> () {{
-			for(Long dpid : getDpids()) {
-				add(createMockSwitch(dpid));
-			}
-		}}).anyTimes();
-
-		// Mock commit() method to commit change of link information
-		mockDBOpe.commit();
-		EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
-			@Override
-			public Object answer() throws Throwable {
-				for(LinkEvent action : actions) {
-					if(action.getType().equals(LinkEventType.ADD)) {
-						Link linkToAdd = new Link(
-								action.getSrcDpid(),
-								action.getSrcPort(),
-								action.getDstDpid(),
-								action.getDstPort());
-						links.add(linkToAdd);
-					} else if(action.getType().equals(LinkEventType.DELETE)) {
-						Link linkToRemove = new Link(
-								action.getSrcDpid(),
-								action.getSrcPort(),
-								action.getDstDpid(),
-								action.getDstPort());
-						links.remove(linkToRemove);
-					} else {
-						log.error("mock commit(): unexpected action {}", new Object[]{action.getType()});
-					}
-				}
-				actions.clear();
-				return null;
-			}
-		}).atLeastOnce();
-		
-		EasyMock.replay(mockDBOpe);
-		return mockDBOpe;
-	}
-	
-	/**
-	 * 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
-	 * @return EasyMock-wrapped IPortObject
-	 */
-	private IPortObject createMockPort(long dpid, short number) {
-		IPortObject mockPort = EasyMock.createNiceMock(IPortObject.class);
-		
-		EasyMock.expect(mockPort.getNumber()).andReturn(number);
-		
-		// Mock removeLink() method
-		mockPort.removeLink((IPortObject) EasyMock.anyObject());
-		EasyMock.expectLastCall().andAnswer(new RemoveLinkCallback(dpid, number)).anyTimes();
-		
-		// Mock setLinkPort() method
-		mockPort.setLinkPort((IPortObject) EasyMock.anyObject());
-		EasyMock.expectLastCall().andAnswer(new SetLinkPortCallback(dpid, number)).anyTimes();
-		
-		// Mock getLinkPorts() method
-		EasyMock.expect(mockPort.getLinkedPorts()).andAnswer(new GetLinkedPortsCallback(dpid, number)).anyTimes();
-
-		// Mock getReverseLinkPorts() method
-		EasyMock.expect(mockPort.getReverseLinkedPorts()).andAnswer(new GetReverseLinkedPortsCallback(dpid, number)).anyTimes();
-		
-		// Mock getSwitch() method
-		EasyMock.expect(mockPort.getSwitch()).andAnswer(new GetSwitchCallback(dpid)).anyTimes();
-		
-		mockToPortInfoMap.put(mockPort, new PortInfo(dpid,number));
-		EasyMock.replay(mockPort);
-		
-		return mockPort;
-	}
-	
-	/**
-	 * Create a mock {@link ISwitchObject} using given DPID number.
-	 * Duplication is not checked.
-	 * @param dpid DPID of a switch
-	 * @return EasyMock-wrapped ISwitchObject
-	 */
-	private ISwitchObject createMockSwitch(long dpid) {
-		ISwitchObject mockSw = EasyMock.createNiceMock(ISwitchObject.class);
-		
-		EasyMock.expect(mockSw.getPorts()).andAnswer(new GetPortsCallback(dpid)).anyTimes();
-		EasyMock.expect(mockSw.getDPID()).andReturn(HexString.toHexString(dpid)).anyTimes();
-		EasyMock.expect(mockSw.getState()).andReturn("ACTIVE").anyTimes();
-		
-		EasyMock.replay(mockSw);
-		return mockSw;
-	}
-
-
-	//----------------- Creation of test data -----------------------
-	// Assume a network shown below.
-	//
-	// [dpid1]--+--[port:1]----[port:1]--+--[dpid2]
-	//          |                        |
-	//          +--[port:2]    [port:2]--+
-	//          |
-	//          +--[port:3]    [port:1]--+--[dpid3]
-	//          |                        |
-	//          +--[port:4]----[port:2]--+
-	//
-	// dpid1 : 00:00:00:00:0a:01
-	// dpid2 : 00:00:00:00:0a:02
-	// dpid3 : 00:00:00:00:0a:03
-	
-	/**
-	 * Initialize links member to represent test topology above.
-	 */
-	private void initLinks() {
-		links = new ArrayList<Link>();
-		
-		links.add(new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1));
-		links.add(new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a03"), 2));
-	}
-	
-	/**
-	 * Returns list of port number attached to the switch specified by given DPID.
-	 * @param dpid DPID of the switch
-	 * @return List of port number
-	 */
-	private List<Short> getPorts(long dpid) {
-		List<Short> ports;
-		
-		if(dpid == Long.decode("0x0000000000000a01")) {
-			ports = new ArrayList<Short>() {{
-				add((short)1);
-				add((short)2);
-				add((short)3);
-				add((short)4);
-			}};
-		} else if(dpid == Long.decode("0x0000000000000a02") || dpid == Long.decode("0x0000000000000a03")) {
-			ports = new ArrayList<Short>() {{
-				add((short)1);
-				add((short)2);
-			}};
-		} else {
-			ports = new ArrayList<Short>();
-		}
-		
-		return ports;
-	}
-	
-	/**
-	 * Returns list of DPIDs in test topology.
-	 * @return List of DPIDs
-	 */
-	private List<Long> getDpids() {
-		List<Long> dpids = new ArrayList<Long>() {{
-			add(Long.decode("0x0000000000000a01"));
-			add(Long.decode("0x0000000000000a02"));
-			add(Long.decode("0x0000000000000a03"));
-		}};
-		
-		return dpids;
-	}
-	
-	/**
-	 * Returns new {@link Link} object of an existing link
-	 * @return new Link object
-	 */
-	private Link createExistingLink() {
-		return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1);
-	}
-	
-	/**
-	 * Returns new {@link Link} object of a not-existing but feasible link
-	 * @return new Link object
-	 */
-	private Link createFeasibleLink() {
-		return new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 1);
-	}
-	
-	/**
-	 * Returns list of existing {@link Link} objects
-	 * @return ArrayList of new Link objects
-	 */
-	private List<Link> createExistingLinks() {
-		List<Link> links = new ArrayList<Link>();
-		links.add(new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1));
-		links.add(new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a03"), 2));
-		return links;
-	}
-	
-	/**
-	 * Returns list of {@link Link} objects that are all not-existing but feasible
-	 * @return ArrayList of new Link objects
-	 */
-	private List<Link> createFeasibleLinks() {
-		List<Link> links = new ArrayList<Link>();
-		links.add(new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a02"), 2));
-		links.add(new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 1));
-		return links;
-	}
-	
-	/**
-	 * Returns new {@link LinkInfo} object with convenient values.
-	 * @return LinkInfo object
-	 */
-	private LinkInfo createFeasibleLinkInfo(long time) {
-		long time_first = time;
-		long time_last_lldp = time + 50;
-		long time_last_bddp = time + 100;
-		int state_src = OFPhysicalPort.OFPortState.OFPPS_STP_FORWARD.getValue();
-		int state_dst = OFPhysicalPort.OFPortState.OFPPS_STP_LISTEN.getValue();
-
-		return new LinkInfo(time_first,
-				time_last_lldp,
-				time_last_bddp,
-				state_src,
-				state_dst);
-	}
-	//---------------------------------------------------------------
-}
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
deleted file mode 100644
index fdc13db..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java
+++ /dev/null
@@ -1,788 +0,0 @@
-package net.onrc.onos.ofcontroller.core.internal;
-
-import static org.easymock.EasyMock.*;
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.ISwitchStorage;
-import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
-import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
-import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-
-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.openflow.protocol.OFPhysicalPort;
-import org.openflow.protocol.OFPhysicalPort.OFPortState;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.slf4j.LoggerFactory;
-
-import com.thinkaurelius.titan.core.TitanFactory;
-
-//Add Powermock preparation
-@Ignore //TODO broken 11/19/13, should fix
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
-public class SwitchStorageImplTest {
-
-	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
-
-	String conf;
-        String dbStore;
-    private GraphDBConnection mockConn = null;
-    private GraphDBOperation mockOpe = null;
-    ISwitchStorage swSt = null;
-    
-	@Before
-	public void setUp() throws Exception {
-		
-		swSt = new SwitchStorageImpl();
-                dbStore = "dummyStore";
-		conf = "/dummy/path/to/db";
-		
-        // Make mock cassandra DB
-		// Replace TitanFactory.open() to return mock DB
-
-		PowerMock.mockStatic(GraphDBConnection.class);
-		mockConn = createMock(GraphDBConnection.class);
-		PowerMock.suppress(PowerMock.constructor(GraphDBConnection.class));
-		EasyMock.expect(GraphDBConnection.getInstance((String)EasyMock.anyObject())).andReturn(mockConn);
-		PowerMock.replay(GraphDBConnection.class);
-		
-		PowerMock.mockStatic(GraphDBOperation.class);
-		mockOpe = PowerMock.createStrictMock(GraphDBOperation.class);
-		PowerMock.expectNew(GraphDBOperation.class, mockConn).andReturn(mockOpe);
-		PowerMock.replay(GraphDBOperation.class);
-        // Replace the conf to dummy conf
-		// String conf = "/tmp/cassandra.titan";
-		
-
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		swSt.close();
-		swSt = null;
-		
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addSwitch method.
-	 * Condition:
-	 *  Normal
-	 * Expect:
-	 * 	Call SwitchStorageImpl.addSwitch func with proper properties.
-	 */
-	@Test
-	public void testAddSwitch() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		String state = "ACTIVE";
-		
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(state);
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addSwitch method.
-	 * Condition:
-	 *  The switch is already existing.
-	 * Expect:
-	 * 	Call SwitchStorageImpl.addSwitch func with proper properties.
-	 */
-	//@Ignore 
-	@Test
-	public void testAddSwitchExisting() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		String state = "ACTIVE";
-		
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(state);
-		mockISw.setState(state);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.addSwitch(dpid);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addSwitch method.
-	 * Condition:
-	 *  The switch construction is fail and return null
-	 * Expect:
-	 * 	Write the status as info log.
-	 */
-	@Test
-	public void testAddSwitchAbnormal() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(null);
-		mockOpe.rollback();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addSwitch method.
-	 * Condition:
-	 *  Throw runtimeException. 
-	 * Expect:
-	 * 	The rollback method is called.
-	 */
-	//@Ignore 
-	@Test
-	public void testAddSwitchException() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		String state = "ACTIVE";
-		
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(state);
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expectLastCall().andThrow(new RuntimeException());
-		mockOpe.rollback();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for updateSwitch method.
-	 * Condition:
-	 *  SwitchState : INACTIVE
-	 *  DMOPERATION : UPDATE
-	 * Expect:
-	 * 	Should call addSwitch function and commit.
-	 */
-	//@Ignore 
-	@Test
-	public void testUpdateUPDATE() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		SwitchState stateINACTIVE = SwitchState.INACTIVE;
-		DM_OPERATION opUPDATE = DM_OPERATION.UPDATE;
-		
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(stateINACTIVE.toString());
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.updateSwitch(dpid, stateINACTIVE, opUPDATE);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for updateSwitch method.
-	 * Condition:
-	 *  SwitchState : INACTIVE
-	 *  DMOPERATION : CREATE
-	 * Expect:
-	 * 	Should call addSwitch function and commit.
-	 */
-	//@Ignore 
-	@Test
-	public void testUpdateCREATE() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		SwitchState stateINACTIVE = SwitchState.INACTIVE;
-		DM_OPERATION opCREATE = DM_OPERATION.CREATE;
-		
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState("ACTIVE");
-		mockISw.setState(stateINACTIVE.toString());
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);	
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.updateSwitch(dpid, stateINACTIVE, opCREATE);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for updateSwitch method.
-	 * Condition:
-	 *  SwitchState : INACTIVE
-	 *  DMOPERATION : INSERT
-	 * Expect:
-	 * 	Should call addSwitch function and commit.
-	 */
-	//@Ignore 
-	@Test
-	public void testUpdateINSERT() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		SwitchState stateINACTIVE = SwitchState.INACTIVE;
-		DM_OPERATION opINSERT = DM_OPERATION.INSERT;
-		
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState("ACTIVE");
-		mockISw.setState(stateINACTIVE.toString());
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.updateSwitch(dpid, stateINACTIVE, opINSERT);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for updateSwitch method.
-	 * Condition:
-	 *  SwitchState : ACTIVE
-	 *  DMOPERATION : DELETE
-	 * Expect:
-	 * 	Should call removeSwitch function and commit.
-	 */
-	//@Ignore 
-	@Test
-	public void testUpdateDELETE() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		SwitchState stateACTIVE = SwitchState.ACTIVE;
-		DM_OPERATION opDELETE = DM_OPERATION.DELETE;
-		
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(stateACTIVE.toString());
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-		mockOpe.removeSwitch(mockISw);
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.updateSwitch(dpid, stateACTIVE, opDELETE);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for deleteSwitch method.
-	 * Condition:
-	 *  The switch is existing.
-	 * Expect:
-	 * 	Should call removeSwitch function and commit.
-	 */
-	//@Ignore
-	@Test
-	public void testDeleteSwitch() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		String state = "ACTIVE";
-	
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(state);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-    	mockOpe.removeSwitch(mockISw);
-    	mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.deleteSwitch(dpid);
-		
-		//Iterator<Vertex> it = titanGraph.getVertices("dpid", dpid).iterator();
-		//assertFalse(it.hasNext());
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for deleteSwitch method.
-	 * Condition:
-	 *  The commit func throw exception.
-	 * Expect:
-	 * 	Should call rollback.
-	 */
-	@Test
-	public void testDeleteSwitchException() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		String state = "ACTIVE";
-		
-		//Mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(state);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-		mockOpe.removeSwitch(mockISw);
-		mockOpe.commit();
-		expectLastCall().andThrow(new RuntimeException());
-		mockOpe.rollback();
-		mockOpe.close();
-		replay(mockOpe);
-		
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.deleteSwitch(dpid);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addPort method.
-	 * Condition:
-	 *  port is existing.
-	 * Expect:
-	 * 	Should call addPort and commit.
-	 */
-	//@Ignore
-	@Test
-	public void testAddPort() {
-		String dpid = "00:00:00:00:00:00:0a:01";
-		short portNumber = 5;
-		String state = "ACTIVE";
-		String name = "port 5 at SEA switch";
-		
-		OFPhysicalPort portToAdd = new OFPhysicalPort();
-		portToAdd.setName(name);
-		portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
-		portToAdd.setPortNumber(portNumber);
-		portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		
-		//Expectation of  mock Port
-		IPortObject mockIPort = createMock(IPortObject.class);
-		mockIPort.setState(state);
-		mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		mockIPort.setDesc(name);
-		replay(mockIPort);
-		
-		//Expectation of mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(state);
-		mockISw.addPort(mockIPort);
-		expect(mockISw.getPort(anyShort())).andReturn(null);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-//		expect(mockOpe.searchPort(dpid, portNumber)).andReturn(null);
-		expect(mockOpe.newPort(dpid, portNumber)).andReturn(mockIPort);	
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.addPort(dpid, portToAdd);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addPort method.
-	 * Condition:
-	 *  Port status is down.
-	 * Expect:
-	 * 	Should call removePort and commit.
-	 */
-	//@Ignore
-	@Test
-	public void testAddPortWithPortLinkDown() {
-		String dpid = "00:00:00:00:00:00:0a:01";
-		short portNumber = 5;
-		String swState = "ACTIVE";
-//		String portState = "INACTIVE";
-		String portId = "5";
-		String name = "port 5 at SEA switch";
-		
-		OFPhysicalPort portToAdd = new OFPhysicalPort();
-		portToAdd.setName(name);
-		portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
-		portToAdd.setPortNumber(portNumber);
-		portToAdd.setState(OFPortState.OFPPS_LINK_DOWN.getValue());
-		
-		//Expectation of  mock Port
-		IPortObject mockIPort = createMock(IPortObject.class);
-		expect(mockIPort.getPortId()).andReturn(portId);
-//		mockIPort.setState(portState);
-//		mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
-//		mockIPort.setDesc(name);
-		replay(mockIPort);
-		
-		//Expectation of mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(swState);
-//		mockISw.removePort(mockIPort);
-		expect(mockISw.getPort(anyShort())).andReturn(mockIPort);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);	
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-//		expect(mockOpe.searchPort(dpid, portNumber)).andReturn(mockIPort);
-		mockOpe.removePort(mockIPort);
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.addPort(dpid, portToAdd);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addPort method.
-	 * Condition:
-	 *  The switch is not existing.
-	 * Expect:
-	 * 	Nothing happens.
-	 */
-	@Test
-	public void testAddPortAbnormalNoSwitch() {
-		String dpid = "00:00:00:00:00:00:0a:01";
-		short portNumber = 5;
-		String name = "port 5 at SEA switch";
-		
-		OFPhysicalPort portToAdd = new OFPhysicalPort();
-		portToAdd.setName(name);
-		portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
-		portToAdd.setPortNumber(portNumber);
-		portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		
-		//Expectation of  mock Port
-		IPortObject mockIPort = createStrictMock(IPortObject.class);
-		replay(mockIPort);
-		
-		//Expectation of mock Switch
-		ISwitchObject mockISw = createStrictMock(ISwitchObject.class);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		mockOpe.close();
-		replay(mockOpe);
-
-		swSt.init(dbStore, conf);
-		swSt.addPort(dpid, portToAdd);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addPort method.
-	 * Condition:
-	 *  port is not existing.
-	 * Expect:
-	 * 	Should call addPort and commit.
-	 */
-	//@Ignore
-	@Test
-	public void testAddPortAbnormalNoPort() {
-		String dpid = "00:00:00:00:00:00:0a:01";
-		short portNumber = 5;
-		String state = "ACTIVE";
-		String name = "port 5 at SEA switch";
-		
-		OFPhysicalPort portToAdd = new OFPhysicalPort();
-		portToAdd.setName(name);
-		portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
-		portToAdd.setPortNumber(portNumber);
-		portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		
-		//Expectation of  mock Port
-		IPortObject mockIPort = createMock(IPortObject.class);
-		mockIPort.setState(state);
-		mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		mockIPort.setDesc(name);
-		replay(mockIPort);
-		
-		//Expectation of mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(state);
-		mockISw.addPort(mockIPort);
-		expect(mockISw.getPort(portNumber)).andReturn(null);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-//		expect(mockOpe.searchPort(dpid, portNumber)).andReturn(null);
-		expect(mockOpe.newPort(dpid, portNumber)).andReturn(null);	
-		mockOpe.rollback();
-		mockOpe.close();
-		replay(mockOpe);
-
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.addPort(dpid, portToAdd);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addPort method.
-	 * Condition:
-	 *  commit throw the exception.
-	 * Expect:
-	 * 	Should call rollback.
-	 */
-	//@Ignore
-	@Test
-	public void testAddPortWithException() {
-		String dpid = "00:00:00:00:00:00:0a:01";
-		short portNumber = 5;
-		String state = "ACTIVE";
-		String name = "port 5 at SEA switch";
-		
-		OFPhysicalPort portToAdd = new OFPhysicalPort();
-		portToAdd.setName(name);
-		portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
-		portToAdd.setPortNumber(portNumber);
-		portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		
-		//Expectation of  mock Port
-		IPortObject mockIPort = createMock(IPortObject.class);
-		mockIPort.setState(state);
-		mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		mockIPort.setDesc(name);
-		replay(mockIPort);
-		
-		//Expectation of mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(state);
-		mockISw.addPort(mockIPort);
-		expect(mockISw.getPort(portNumber)).andReturn(null);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-//		expect(mockOpe.searchPort(dpid, portNumber)).andReturn(null);
-		expect(mockOpe.newPort(dpid, portNumber)).andReturn(mockIPort);	
-		mockOpe.commit();
-		expectLastCall().andThrow(new RuntimeException());
-		mockOpe.rollback();
-		mockOpe.close();
-		replay(mockOpe);
-
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.addPort(dpid, portToAdd);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for deletePort method.
-	 * Condition:
-	 *  port is existing.
-	 * Expect:
-	 * 	Should call removePort and commit.
-	 */
-	//@Ignore
-	@Test
-	public void testDeletePort() {
-		String dpid = "00:00:00:00:00:00:0a:01";
-		short portNumber = 5;
-		String portState = "INACTIVE";
-		String swState = "ACTIVE";
-		String portId = "5";
-		String name = "port 5 at SEA switch";
-		
-		OFPhysicalPort portToAdd = new OFPhysicalPort();
-		portToAdd.setName(name);
-		portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
-		portToAdd.setPortNumber(portNumber);
-		portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		
-		//Expectation of  mock Port
-		IPortObject mockIPort = createMock(IPortObject.class);
-		mockIPort.setState(swState);
-//		mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		mockIPort.setDesc(name);
-		mockIPort.setState(portState);
-		expect(mockIPort.getPortId()).andReturn(portId);
-		replay(mockIPort);
-		
-		//Expectation of mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(swState);
-//		mockISw.removePort(mockIPort);
-		expect(mockISw.getPort(portNumber)).andReturn(null);
-		mockISw.addPort(mockIPort);
-		expect(mockISw.getPort(portNumber)).andReturn(mockIPort);
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-//		expect(mockOpe.searchPort(dpid, portNumber)).andReturn(null);
-		expect(mockOpe.newPort(dpid, portNumber)).andReturn(mockIPort);	
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-//		expect(mockOpe.searchPort(dpid, portNumber)).andReturn(mockIPort);
-		mockOpe.removePort(mockIPort);
-		mockOpe.commit();
-		mockOpe.close();
-		replay(mockOpe);
-
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.addPort(dpid, portToAdd);
-		swSt.deletePort(dpid, portNumber);
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for addPort method.
-	 * Condition:
-	 *  commit throws the exception.
-	 * Expect:
-	 * 	Should call rollback.
-	 */
-	//@Ignore
-	@Test
-	public void testDeletePortException() {
-		String dpid = "00:00:00:00:00:00:0a:01";
-		short portNumber = 5;
-		String swState = "ACTIVE";
-		String portState = "INACTIVE";
-		String portId = "5";
-		String name = "port 5 at SEA switch";
-		
-		OFPhysicalPort portToAdd = new OFPhysicalPort();
-		portToAdd.setName(name);
-		portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
-		portToAdd.setPortNumber(portNumber);
-		portToAdd.setState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		
-		//Expectation of  mock Port
-		IPortObject mockIPort = createMock(IPortObject.class);
-		mockIPort.setState(swState);
-		mockIPort.setPortState(OFPortState.OFPPS_STP_FORWARD.getValue());
-		mockIPort.setDesc(name);
-		mockIPort.setState(portState);
-		expect(mockIPort.getPortId()).andReturn(portId);
-		replay(mockIPort);
-		
-		//Expectation of mock Switch
-		ISwitchObject mockISw = createMock(ISwitchObject.class);
-		mockISw.setState(swState);
-		mockISw.addPort(mockIPort);
-		expect(mockISw.getPort(portNumber)).andReturn(null);
-		expect(mockISw.getPort(portNumber)).andReturn(mockIPort).anyTimes();
-//		mockISw.removePort(mockIPort);
-		
-		expect(mockISw.getDPID()).andReturn(dpid).anyTimes();
-		replay(mockISw);
-		
-		//Expectation of mock operation.
-		expect(mockOpe.searchSwitch(dpid)).andReturn(null);
-		expect(mockOpe.newSwitch(dpid)).andReturn(mockISw);
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-//		expect(mockOpe.searchPort(dpid, portNumber)).andReturn(null);
-		expect(mockOpe.newPort(dpid, portNumber)).andReturn(mockIPort);	
-		mockOpe.commit();
-		expect(mockOpe.searchSwitch(dpid)).andReturn(mockISw);
-//		expect(mockOpe.searchPort(dpid, portNumber)).andReturn(mockIPort);
-//		mockOpe.commit(); // Cannot generate exception..need to revisit this test
-		mockOpe.removePort(mockIPort);
-		expectLastCall().andThrow(new RuntimeException());
-		mockOpe.rollback();
-		mockOpe.close();
-		replay(mockOpe);
-	
-		swSt.init(dbStore, conf);
-		swSt.addSwitch(dpid);
-		swSt.addPort(dpid, portToAdd);
-		swSt.deletePort(dpid, portNumber);
-	}
-}
\ No newline at end of file
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTestBB.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTestBB.java
deleted file mode 100644
index fe51f95..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTestBB.java
+++ /dev/null
@@ -1,349 +0,0 @@
-package net.onrc.onos.ofcontroller.core.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import net.floodlightcontroller.core.internal.TestDatabaseManager;
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.INetMapStorage;
-import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.core.ISwitchStorage;
-import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
-
-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.openflow.protocol.OFPhysicalPort;
-import org.openflow.protocol.OFPhysicalPort.OFPortState;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.slf4j.LoggerFactory;
-
-import com.thinkaurelius.titan.core.TitanFactory;
-import com.thinkaurelius.titan.core.TitanGraph;
-
-/*
- * Jono, 11/4/2013
- * These tests are being ignored because they don't work because they
- * rely on test functionality that was written ages ago and hasn't been
- * updated as the database schema has evolved. 
- * These tests work by getting an in-memory Titan database and testing
- * the SwitchStorageImpl on top of that. In this regard they're not really
- * unit tests as they test the entire DB stack (i.e. GraphDBOperation and
- * GraphDBConnection), not just SwitchStorageImpl.
- * I've left them here as we may wish to resurrect this kind of 
- * integration testing of the DB layers in the future.
- */
-@Ignore
-//Add Powermock preparation
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
-public class SwitchStorageImplTestBB {
-
-	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
-
-	String conf;
-        String dbStore;
-    private GraphDBConnection conn = null;
-    private GraphDBOperation ope = null;
-    private TitanGraph titanGraph = null;
-    ISwitchStorage swSt = null;
-    
-	@Before
-	public void setUp() throws Exception {
-		
-		swSt = new SwitchStorageImpl();
-		conf = "/dummy/path/to/db";
-                dbStore ="dummyStore";
-		
-		// Make mock cassandra DB
-		// Replace TitanFactory.open() to return mock DB
-		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);
-		
-		swSt.init(dbStore, conf);
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		
-		titanGraph.shutdown();
-		TestDatabaseManager.deleteTestDatabase();
-
-		swSt.close();
-		swSt = null;
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addSwitch method.
-	 * Condition:
-	 *  Normal
-	 * Expect:
-	 * 1. Switch should be generated.
-	 * 2. The status of switch should be ACTIVE
-	 */
-	//@Ignore 
-	@Test
-	public void testAddSwitch() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw == null);
-		swSt.addSwitch(dpid);
-		ISwitchObject sw2 = ope.searchSwitch(dpid);
-		assertTrue(sw2 != null);
-		assertEquals(sw2.getState(), "ACTIVE");
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for addSwitch method.
-	 * Condition:
-	 *  The existing switch status is INACTIVE.
-	 *  The switch is already existing.
-	 * Expect:
-	 * 1. After add the same switch, the status of switch should be ACTIVE
-	 */
-	//@Ignore 
-	@Test
-	public void testAddSwitchExisting() {
-		String dpid = "00:00:00:00:00:00:0a:06";
-		
-		swSt.updateSwitch(dpid, SwitchState.INACTIVE, DM_OPERATION.UPDATE);
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw != null);
-		assertEquals(sw.getState(), SwitchState.INACTIVE.toString());
-		swSt.addSwitch(dpid);
-		ISwitchObject sw2 = ope.searchSwitch(dpid);
-		assertTrue(sw2 != null);
-		assertEquals(sw2.getState(), SwitchState.ACTIVE.toString());
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for testUpdate method.
-	 * Condition:
-	 *  The switch is not existing.
-	 *  The status of added switch is INACTIVE.
-	 *  DM_OPERATION is CREATE.
-	 * Expect:
-	 * 1. Switch should be created.
-	 * 2. The status of switch should be INACTIVE.
-	 */
-	//@Ignore 
-	@Test
-	public void testUpdate() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		SwitchState state = ISwitchStorage.SwitchState.INACTIVE;
-		DM_OPERATION dmope = INetMapStorage.DM_OPERATION.CREATE;
-		
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw == null);
-		swSt.updateSwitch(dpid, state, dmope);
-		ISwitchObject sw2 = ope.searchSwitch(dpid);
-		assertTrue(sw2 != null);
-		assertEquals(sw2.getState(), state.toString());
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for testUpdate method.
-	 * Condition:
-	 *  The switch is existing.
-	 *  The status of added switch is ACTIVE.
-	 *  DM_OPERATION is DELETE.
-	 * Expect:
-	 * 1. Switch should be deleted.
-	 */
-	//@Ignore 
-	@Test
-	public void testUpdateWithDELETE() {
-		String dpid = "00:00:00:00:00:00:0a:06";
-		SwitchState state = ISwitchStorage.SwitchState.ACTIVE;
-		DM_OPERATION dmope = INetMapStorage.DM_OPERATION.DELETE;
-		
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw != null);
-		swSt.updateSwitch(dpid, state, dmope);
-		ISwitchObject sw2 = ope.searchSwitch(dpid);
-		assertTrue(sw2 == null);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for delete switch method.
-	 * Condition:
-	 *  The switch is existing.
-	 * Expect:
-	 * 1. Switch should be deleted.
-	 */
-	//@Ignore 
-	@Test
-	public void testDeleteSwitch() {
-		String dpid = "00:00:00:00:00:00:0a:06";
-		
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw != null);
-		swSt.deleteSwitch(dpid);
-		ISwitchObject sw2 = ope.searchSwitch(dpid);
-		assertTrue(sw2 == null);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for delete switch method.
-	 * Condition:
-	 *  The switch is not existing.
-	 * Expect:
-	 * Nothing happens.
-	 */
-	//@Ignore 
-	@Test
-	public void testDeleteNonExistingSwitch() {
-		String dpid = "00:00:00:00:00:00:0a:07";
-		
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw == null);
-		swSt.deleteSwitch(dpid);
-		ISwitchObject sw2 = ope.searchSwitch(dpid);
-		assertTrue(sw2 == null);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for delete port method.
-	 * Condition:
-	 *  The port is existing.
-	 * Expect:
-	 *  Deleted the port.
-	 */
-	//@Ignore 
-	@Test
-	public void testDeletePort() {
-		String dpid = "00:00:00:00:00:00:0a:06";
-		short portNumber = 3;
-		
-		IPortObject portObj1 = ope.searchPort(dpid, portNumber);
-		assertTrue(portObj1 != null);
-		swSt.deletePort(dpid, portNumber);
-		IPortObject portObj2 = ope.searchPort(dpid, portNumber);
-		assertTrue(portObj2 == null);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for delete port method.
-	 * Condition:
-	 *  The port is not existing.
-	 * Expect:
-	 *  Nothing happens.
-	 */
-	//@Ignore 
-	@Test
-	public void testDeleteNonExistingPort() {
-		String dpid = "00:00:00:00:00:00:0a:06";
-		short portNumber = 4;
-		
-		IPortObject portObj1 = ope.searchPort(dpid, portNumber);
-		assertTrue(portObj1 == null);
-		swSt.deletePort(dpid, portNumber);
-		IPortObject portObj2 = ope.searchPort(dpid, portNumber);
-		assertTrue(portObj2 == null);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for add port method.
-	 * Condition:
-	 *  The port is not existing.
-	 * Expect:
-	 *  The port should be added.
-	 *  The desc of IPortObject is the same as the name of OFPhysicalPort.
-	 */
-	//@Ignore 
-	@Test
-	public void testAddPort() {
-		String dpid = "00:00:00:00:00:00:0a:06";
-		short portNumber = 4;
-		String name = "port 4 at ATL Switch";
-		int state = OFPortState.OFPPS_STP_FORWARD.getValue();
-		OFPhysicalPort port = new OFPhysicalPort(); 
-		port.setPortNumber(portNumber);
-		port.setName(name);
-		port.setState(state);
-		
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw != null);
-		swSt.addPort(dpid, port);
-		IPortObject portObj = ope.searchPort(dpid, portNumber);
-		assertTrue(portObj != null);
-		assertEquals(portObj.getDesc(), name);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for add method.
-	 * Condition:
-	 *  The port is existing.
-	 * Expect:
-	 *  Nothing happens.
-	 */
-	//@Ignore 
-	@Test
-	public void testAddExistingPort() {
-		String dpid = "00:00:00:00:00:00:0a:06";
-		short portNumber = 3;
-		String name = "xxx";
-		int state = OFPortState.OFPPS_STP_FORWARD.getValue();
-		OFPhysicalPort port = new OFPhysicalPort(); 
-		port.setPortNumber(portNumber);
-		port.setName(name);
-		port.setState(state);
-		
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw != null);
-		swSt.addPort(dpid, port);
-		IPortObject portObj = ope.searchPort(dpid, portNumber);
-		assertTrue(portObj != null);
-	}
-	
-	/**
-	 * Desc:
-	 *  Test method for add method.
-	 * Condition:
-	 *  The port status is down.
-	 * Expect:
-	 *  Delete the port.
-	 */
-	//@Ignore 
-	@Test
-	public void testAddDownPort() {
-		String dpid = "00:00:00:00:00:00:0a:06";
-		short portNumber = 3;
-		String name = "port 3 at ATL Switch";
-		int state = OFPortState.OFPPS_LINK_DOWN.getValue();
-		OFPhysicalPort port = new OFPhysicalPort(); 
-		port.setPortNumber(portNumber);
-		port.setName(name);
-		port.setState(state);
-		
-		ISwitchObject sw = ope.searchSwitch(dpid);
-		assertTrue(sw != null);
-		swSt.addPort(dpid, port);
-		IPortObject portObj = ope.searchPort(dpid, portNumber);
-		assertTrue(portObj == null);
-	}
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java
deleted file mode 100644
index 8da306f..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java
+++ /dev/null
@@ -1,1619 +0,0 @@
-package net.onrc.onos.ofcontroller.core.internal;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.codehaus.jackson.annotate.JsonIgnore;
-import org.easymock.EasyMock;
-import org.openflow.util.HexString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.tinkerpop.blueprints.Vertex;
-import com.tinkerpop.frames.Property;
-import com.tinkerpop.frames.annotations.gremlin.GremlinParam;
-
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.graph.IDBConnection;
-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.IIpv4Address;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.util.FlowEntryId;
-import net.onrc.onos.ofcontroller.util.FlowId;
-
-/**
- * Mock class of GraphDBOperation which provides additional setter to construct a graph for test.
- * This object simply caches parameters set up by override interfaces and reflect them when commit().
- * *ForTest() methods are exempt from cache, parameters through those methods are reflected soon.
- * @author Naoki Shiota
- *
- */
-public class TestableGraphDBOperation extends GraphDBOperation {
-	protected final static Logger log = LoggerFactory.getLogger(TestableGraphDBOperation.class);
-
-	protected List<TestSwitchObject> switches;
-	protected List<TestPortObject> ports;
-	protected List<TestDeviceObject> devices;
-	protected List<TestFlowPath> paths;
-	protected List<TestFlowEntry> entries;
-
-	protected List<TestSwitchObject> switchesToAdd;
-	protected List<TestPortObject> portsToAdd;
-	protected List<TestDeviceObject> devicesToAdd;
-	protected List<TestFlowPath> pathsToAdd;
-	protected List<TestFlowEntry> entriesToAdd;
-
-	protected List<TestSwitchObject> switchesToRemove;
-	protected List<TestPortObject> portsToRemove;
-	protected List<TestDeviceObject> devicesToRemove;
-	protected List<TestFlowPath> pathsToRemove;
-	protected List<TestFlowEntry> entriesToRemove;
-
-	// Testable implementations of INetMapTopologyObject interfaces
-
-	public static class TestSwitchObject implements ISwitchObject {
-		private String state,type,dpid;
-		private List<IPortObject> ports;
-		private List<IDeviceObject> devices;
-		private List<IFlowEntry> entries;
-
-		private String stateToUpdate, typeToUpdate, dpidToUpdate;
-		private List<IPortObject> portsToAdd;
-		private List<IPortObject> portsToRemove;
-
-		public TestSwitchObject() {
-			type = "switch";
-			
-			ports = new ArrayList<IPortObject>();
-			portsToAdd = new ArrayList<IPortObject>();
-			portsToRemove = new ArrayList<IPortObject>();
-			devices = new ArrayList<IDeviceObject>();
-			entries = new ArrayList<IFlowEntry>();
-			
-			clearUncommitedData();
-		}
-		
-		public void commit() {
-			for(IPortObject port : portsToAdd) {
-				ports.add(port);
-			}
-			for(IPortObject port : portsToRemove) {
-				ports.remove(port);
-			}
-			if(stateToUpdate != null) { state = stateToUpdate; }
-			if(typeToUpdate != null) { type = typeToUpdate; }
-			if(dpidToUpdate != null) { dpid = dpidToUpdate; }
-
-			clearUncommitedData();
-		}
-		
-		public void rollback() {
-			clearUncommitedData();
-		}
-		
-		public void clearUncommitedData() {
-			portsToAdd.clear();
-			portsToRemove.clear();
-			stateToUpdate = typeToUpdate = dpidToUpdate = null;
-		}
-		
-		public void setStateForTest(String state) { this.state = state; }
-		public void setTypeForTest(String type) { this.type = type; }
-		public void setDpidForTest(String dpid) { this.dpid = dpid; }
-		public void addPortForTest(TestPortObject port) { ports.add(port);  }
-		public void addDeviceForTest(TestDeviceObject dev) { devices.add(dev); }
-		public void addEntryForTest(TestFlowEntry entry) { entries.add(entry); }
-		
-		@Override
-		public String getState() { return state; }
-	
-		@Override
-		public void setState(String state) { this.stateToUpdate = state; }
-	
-		@Override
-		public String getType() { return type ; }
-	
-		@Override
-		public void setType(String type) { this.typeToUpdate = type; }
-	
-		// Not support for test
-		@Override
-		public Vertex asVertex() { return null; }
-	
-		@Override
-		public String getDPID() { return dpid; }
-	
-		@Override
-		public void setDPID(String dpid) { this.dpidToUpdate = dpid; }
-	
-		@Override
-		public Iterable<IPortObject> getPorts() { return ports; }
-	
-		@Override
-		public IPortObject getPort(@GremlinParam("port_num") short port_num) {
-			for(IPortObject port : ports) {
-				if(port.getNumber() == port_num) {
-					return port;
-				}
-			}
-			return null;
-		}
-	
-		@Override
-		public void addPort(IPortObject port) { portsToAdd.add(port); }
-	
-		@Override
-		public void removePort(IPortObject port) { portsToRemove.add(port); }
-	
-		@Override
-		public Iterable<IDeviceObject> getDevices() { return devices; }
-	
-		@Override
-		public Iterable<IFlowEntry> getFlowEntries() { return entries; }
-	}
-	
-	public static class TestPortObject implements IPortObject {
-		private String state,type,desc;
-		private Short number;
-		private Integer port_state;
-		private ISwitchObject sw;
-		
-		private List<IPortObject> linkedPorts;
-		private List<IPortObject> reverseLinkedPorts;
-		private List<IDeviceObject> devices;
-		private List<IFlowEntry> inflows,outflows;
-		
-		private String stateToUpdate,typeToUpdate,descToUpdate;
-		private Short numberToUpdate;
-		private Integer port_stateToUpdate;
-		
-		private List<IPortObject> linkedPortsToAdd;
-		private List<IPortObject> linkedPortsToRemove;
-		private List<IDeviceObject> devicesToAdd;
-		private List<IDeviceObject> devicesToRemove;
-		
-
-		public TestPortObject() {
-			type = "port";
-
-			linkedPorts = new ArrayList<IPortObject>();
-			reverseLinkedPorts = new ArrayList<IPortObject>();
-			linkedPortsToAdd = new ArrayList<IPortObject>();
-			linkedPortsToRemove = new ArrayList<IPortObject>();
-			devices = new ArrayList<IDeviceObject>();
-			devicesToAdd = new ArrayList<IDeviceObject>();
-			devicesToRemove = new ArrayList<IDeviceObject>();
-			inflows = new ArrayList<IFlowEntry>();
-			outflows = new ArrayList<IFlowEntry>();
-			
-			clearUncommitedData();
-		}
-		
-		public void commit() {
-			for(IPortObject port : linkedPortsToAdd) { linkedPorts.add(port); }
-			for(IPortObject port : linkedPortsToRemove) { linkedPorts.remove(port); }
-			for(IDeviceObject dev : devicesToAdd) { devices.add(dev); }
-			for(IDeviceObject dev : devicesToRemove) { devices.remove(dev); }
-			
-			if(stateToUpdate != null) { state = stateToUpdate; }
-			if(typeToUpdate != null) { type = typeToUpdate; }
-			if(descToUpdate != null) { desc = descToUpdate; }
-			if(numberToUpdate != null) { number = numberToUpdate; }
-			if(port_stateToUpdate != null) { port_state = port_stateToUpdate; }
-			
-			clearUncommitedData();
-		}
-		
-		public void rollback() {
-			clearUncommitedData();
-		}
-		
-		public void clearUncommitedData() {
-			linkedPortsToAdd.clear();
-			linkedPortsToRemove.clear();
-			devicesToAdd.clear();
-			devicesToRemove.clear();
-			stateToUpdate = typeToUpdate = descToUpdate = null;
-			port_stateToUpdate = null;
-			numberToUpdate = null;
-		}
-		
-		// Setter methods for test
-		public void setStateForTest(String state) { this.state = state; }
-		public void setTypeForTest(String type) { this.type = type; }
-		public void setDescForTest(String desc) { this.desc = desc; }
-		public void setNumberForTest(Short number) { this.number = number; }
-		public void setPortStateForTest(Integer state) { this.port_state = state; }
-		public void setSwitchForTest(ISwitchObject sw) { this.sw = sw; }
-		public void addLinkedPortForTest(TestPortObject port) { this.linkedPorts.add(port); }
-		public void addInflowForTest(TestFlowEntry entry) { inflows.add(entry); }
-		public void addOutflowForTest(TestFlowEntry entry) { outflows.add(entry); }
-		
-		// Override methods for mock IPortObject
-		@Override
-		public String getState() { return state; }
-
-		@Override
-		public void setState(String state) { this.stateToUpdate = state; }
-
-		@Override
-		public String getType() { return type; }
-
-		@Override
-		public void setType(String type) { this.typeToUpdate = type; }
-
-		// not support for test
-		@Override
-		public Vertex asVertex() {
-			return null;
-		}
-
-		@Override
-		public Short getNumber() { return number; }
-
-		@Override
-		public void setNumber(Short n) { this.numberToUpdate = n; }
-
-		@Override
-		public String getDesc() { return desc; }
-
-		@Override
-		public void setDesc(String s) { this.descToUpdate = s; }
-
-		@Override
-		public Integer getPortState() { return port_state; }
-
-		@Override
-		public void setPortState(Integer s) { this.port_stateToUpdate = s; }
-
-		@Override
-		public ISwitchObject getSwitch() { return sw; }
-
-		@Override
-		public Iterable<IDeviceObject> getDevices() { return devices; }
-
-		@Override
-		public void setDevice(IDeviceObject device) { devicesToAdd.add(device); }
-
-		@Override
-		public void removeDevice(IDeviceObject device) { devicesToRemove.add(device); }
-
-		@Override
-		public Iterable<IFlowEntry> getInFlowEntries() { return inflows; }
-
-		@Override
-		public Iterable<IFlowEntry> getOutFlowEntries() { return outflows; }
-
-		@Override
-		public Iterable<IPortObject> getLinkedPorts() { return linkedPorts; }
-
-		@Override
-		public Iterable<IPortObject> getReverseLinkedPorts() { return reverseLinkedPorts; }
-
-		@Override
-		public void removeLink(IPortObject dest_port) { linkedPortsToRemove.add(dest_port); }
-
-		@Override
-		public void setLinkPort(IPortObject dest_port) { linkedPortsToAdd.add(dest_port); }
-
-		@Override
-		@JsonIgnore
-		@Property("port_id")
-		public void setPortId(String id) {
-			// TODO Auto-generated method stub
-			
-		}
-
-		@Override
-		@JsonIgnore
-		@Property("port_id")
-		public String getPortId() {
-			// TODO Auto-generated method stub
-			return null;
-		}
-	}
-		
-	/*
-	 * Note by Jono, 11/4/2013
-	 * I changed the interface of IDeviceObject but I didn't spend the
-	 * time to update this class, because I can't see where this is used.
-	 * I think this whole file is a candidate for deletion if it is not
-	 * used anywhere - the graphDB objects are tested elsewhere by the
-	 * tests in net.onrc.onos.ofcontroller.core.*
-	 */
-	public static class TestDeviceObject implements IDeviceObject {
-		@SuppressWarnings("unused")
-		private String state,type,mac,ipaddr;
-		private List<IPortObject> ports;
-		private List<ISwitchObject> switches;
-		
-		private String stateToUpdate,typeToUpdate,macToUpdate,ipaddrToUpdate;
-		private List<IPortObject> portsToAdd;
-		private List<IPortObject> portsToRemove;
-	
-		public TestDeviceObject() {
-			type = "device";
-			
-			ports = new ArrayList<IPortObject>();
-			portsToAdd = new ArrayList<IPortObject>();
-			portsToRemove = new ArrayList<IPortObject>();
-			switches = new ArrayList<ISwitchObject>();
-			
-			clearUncommitedData();
-		}
-		
-		public void commit() {
-			for(IPortObject port : portsToAdd) {
-				ports.add(port);
-			}
-			for(IPortObject port : portsToRemove) {
-				ports.remove(port);
-			}
-			
-			if(stateToUpdate != null) { state = stateToUpdate; }
-			if(typeToUpdate != null) { type = typeToUpdate; }
-			if(macToUpdate != null) { mac = macToUpdate; }
-			if(ipaddrToUpdate != null) { ipaddr = ipaddrToUpdate; }
-			
-			clearUncommitedData();
-		}
-		
-		public void rollback() {
-			clearUncommitedData();
-		}
-		
-		public void clearUncommitedData() {
-			ports.clear();
-			portsToAdd.clear();
-			portsToRemove.clear();
-			
-			stateToUpdate = typeToUpdate = macToUpdate = ipaddrToUpdate = null;
-		}
-		
-		// Setter methods for test
-		public void setStateForTest(String state) { this.state = state; }
-		public void setTypeForTest(String type) { this.type = type; }
-		public void setMacForTest(String mac) { this.mac = mac; }
-		public void setIpaddrForTest(String ipaddr) { this.ipaddr = ipaddr; }
-		public void addSwitchForTest(ISwitchObject sw) { switches.add(sw); }
-		public void addPortForTest(IPortObject port) { ports.add(port); }
-		
-		
-		// Override methods
-		@Override
-		public String getState() { return state; }
-	
-		@Override
-		public void setState(String state) { stateToUpdate = state; }
-	
-		@Override
-		public String getType() { return type; }
-	
-		@Override
-		public void setType(String type) { typeToUpdate = type; }
-	
-		@Override
-		public Vertex asVertex() {
-			// TODO Auto-generated method stub
-			return null;
-		}
-	
-		@Override
-		public String getMACAddress() { return mac; }
-	
-		@Override
-		public void setMACAddress(String macaddr) { macToUpdate = macaddr; }
-	
-		//@Override
-		//public String getIPAddress() { return ipaddr; }
-	
-		//@Override
-		//public void setIPAddress(String ipaddr) { ipaddrToUpdate = ipaddr; }
-	
-		@Override
-		public Iterable<IPortObject> getAttachedPorts() {
-			return ports; }
-	
-		@Override
-		public void setHostPort(IPortObject port) { portsToAdd.add(port); }
-	
-		@Override
-		public void removeHostPort(IPortObject port) { portsToRemove.add(port); }
-	
-		@Override
-		public Iterable<ISwitchObject> getSwitch() { return switches; }
-
-		@Override
-		public Iterable<IIpv4Address> getIpv4Addresses() {
-			// TODO Auto-generated method stub
-			return null;
-		}
-
-		@Override
-		public IIpv4Address getIpv4Address(int ipv4Address) {
-			// TODO Auto-generated method stub
-			return null;
-		}
-
-		@Override
-		public void addIpv4Address(IIpv4Address ipv4Address) {
-			// TODO Auto-generated method stub
-			
-		}
-
-		@Override
-		public void removeIpv4Address(IIpv4Address ipv4Address) {
-			// TODO Auto-generated method stub
-			
-		}
-	}
-	
-	public static class TestFlowPath implements IFlowPath {
-		private String state,type,flowId,installerId,srcSw,dstSw;
-		private String flowPathType;
-		private String flowPathUserState;
-		private Long flowPathFlags;
-		private Integer idleTimeout;
-		private Integer hardTimeout;
-		private String dataPathSummary;
-		private Short srcPort,dstPort;
-		private String matchSrcMac,matchDstMac;
-		private Short matchEthernetFrameType;
-		private Short matchVlanId;
-		private Byte matchVlanPriority;
-		private String matchSrcIpaddr,matchDstIpaddr;
-		private Byte matchIpProto, matchIpToS;
-		private Short matchSrcTcpUdpPort, matchDstTcpUdpPort;
-		private String actions;
-		
-		private List<IFlowEntry> entries;
-		private List<ISwitchObject> switches;
-
-		private String stateToUpdate,typeToUpdate,flowIdToUpdate,installerIdToUpdate,srcSwToUpdate,dstSwToUpdate;
-		private String flowPathTypeToUpdate;
-		private String flowPathUserStateToUpdate;
-		private Long flowPathFlagsToUpdate;
-		private Integer idleTimeoutToUpdate;
-		private Integer hardTimeoutToUpdate;
-		private String dataPathSummaryToUpdate;
-		private Short srcPortToUpdate,dstPortToUpdate;
-		private String matchSrcMacToUpdate,matchDstMacToUpdate;
-		private Short matchEthernetFrameTypeToUpdate;
-		private Short matchVlanIdToUpdate;
-		private Byte matchVlanPriorityToUpdate;
-		private String matchSrcIpaddrToUpdate,matchDstIpaddrToUpdate;
-		private Byte matchIpProtoToUpdate, matchIpToSToUpdate;
-		private Short matchSrcTcpUdpPortToUpdate, matchDstTcpUdpPortToUpdate;
-		private String actionsToUpdate;
-
-		private List<IFlowEntry> flowsToAdd;
-		private List<IFlowEntry> flowsToRemove;
-
-		public TestFlowPath() {
-			type = "flow";
-			
-			entries = new ArrayList<IFlowEntry>();
-			flowsToAdd = new ArrayList<IFlowEntry>();
-			flowsToRemove = new ArrayList<IFlowEntry>();
-			
-			switches = new ArrayList<ISwitchObject>();
-			
-			clear();
-		}
-		
-		public void commit() {
-			for(IFlowEntry flow : flowsToAdd) {
-				entries.add(flow);
-			}
-			for(IFlowEntry flow : flowsToRemove) {
-				entries.remove(flow);
-			}
-			if(stateToUpdate != null) { state = stateToUpdate; }
-			if(typeToUpdate != null) { type = typeToUpdate; }
-			if(flowIdToUpdate != null) { flowId = flowIdToUpdate; }
-			if(installerIdToUpdate != null) { installerId = installerIdToUpdate; }
-			if(flowPathTypeToUpdate != null) { flowPathType = flowPathTypeToUpdate; }
-			if(flowPathUserStateToUpdate != null) { flowPathUserState = flowPathUserStateToUpdate; }
-			if(flowPathFlagsToUpdate != null) { flowPathFlags = flowPathFlagsToUpdate; }
-			if(idleTimeoutToUpdate != null) { idleTimeout = idleTimeoutToUpdate; }
-			if(hardTimeoutToUpdate != null) { hardTimeout = hardTimeoutToUpdate; }
-			if(srcSwToUpdate != null) { srcSw = srcSwToUpdate; }
-			if(dstSwToUpdate != null) { dstSw = dstSwToUpdate; }
-			if(dataPathSummaryToUpdate != null) { dataPathSummary = dataPathSummaryToUpdate; }
-			if(srcPortToUpdate != null) { srcPort = srcPortToUpdate; }
-			if(dstPortToUpdate != null) { dstPort = dstPortToUpdate; }
-			if(matchSrcMacToUpdate != null) { matchSrcMac = matchSrcMacToUpdate; }
-			if(matchDstMacToUpdate != null) { matchDstMac = matchDstMacToUpdate; }
-			if(matchEthernetFrameTypeToUpdate != null) { matchEthernetFrameType = matchEthernetFrameTypeToUpdate; }
-			if(matchVlanIdToUpdate != null) { matchVlanId = matchVlanIdToUpdate; }
-			if(matchVlanPriorityToUpdate != null) { matchVlanPriority = matchVlanPriorityToUpdate; }
-			if(matchSrcIpaddrToUpdate != null) { matchSrcIpaddr = matchSrcIpaddrToUpdate; }
-			if(matchDstIpaddrToUpdate != null) { matchDstIpaddr = matchDstIpaddrToUpdate; }
-			if(matchIpProtoToUpdate != null) { matchIpProto = matchIpProtoToUpdate; }
-			if(matchIpToSToUpdate != null) { matchIpToS = matchIpToSToUpdate; }
-			if(matchSrcTcpUdpPortToUpdate != null) { matchSrcTcpUdpPort = matchSrcTcpUdpPortToUpdate; }
-			if(matchDstTcpUdpPortToUpdate != null) { matchDstTcpUdpPort = matchDstTcpUdpPortToUpdate; }
-			if(actionsToUpdate != null) { actions = actionsToUpdate; }
-		}
-		
-		public void rollback() {
-			clear();
-		}
-		
-		public void clear() {
-			flowsToAdd.clear();
-			flowsToRemove.clear();
-			
-			stateToUpdate = typeToUpdate = flowIdToUpdate = installerIdToUpdate = null;
-			flowPathTypeToUpdate = null;
-			flowPathUserStateToUpdate = null;
-			flowPathFlagsToUpdate = null;
-			idleTimeoutToUpdate = null;
-			hardTimeoutToUpdate = null;
-			srcSwToUpdate = dstSwToUpdate = dataPathSummaryToUpdate = null;
-			srcPortToUpdate = dstPortToUpdate = null;
-			matchSrcMacToUpdate = matchDstMacToUpdate = null;
-			matchEthernetFrameTypeToUpdate = null;
-			matchVlanIdToUpdate = null;
-			matchVlanPriorityToUpdate = null;
-			matchSrcIpaddrToUpdate = matchDstIpaddrToUpdate = null;
-			matchIpProtoToUpdate = matchIpToSToUpdate = null;
-			matchSrcTcpUdpPortToUpdate = matchDstTcpUdpPortToUpdate = null;
-			actionsToUpdate = null;
-		}
-		
-		// Setter methods for test
-		public void setStateForTest(String state) { this.state = state; }
-		public void setTypeForTest(String type) { this.type = type; }
-		public void setFlowIdForTest(String flowId) { this.flowId = flowId; }
-		public void setInstallerIdForTest(String installerId) { this.installerId = installerId; }
-		public void setFlowPathTypeForTest(String flowPathType) { this.flowPathType = flowPathType; }
-		public void setFlowPathUserStateForTest(String flowPathUserState) { this.flowPathUserState = flowPathUserState; }
-		public void setFlowPathFlagsForTest(Long flowPathFlags) { this.flowPathFlags = flowPathFlags; }
-		public void setIdleTimeoutForTest(Integer idleTimeout) { this.idleTimeout = idleTimeout; }
-		public void setHardTimeoutForTest(Integer hardTimeout) { this.hardTimeout = hardTimeout; }
-		public void setSrcSwForTest(String srcSw) { this.srcSw = srcSw; }
-		public void setDstSwForTest(String dstSw) { this.dstSw = dstSw; }
-		public void setDataPathSummaryForTest(String dataPathSummary) { this.dataPathSummary = dataPathSummary; }
-		public void setSrcPortForTest(Short srcPort) { this.srcPort = srcPort; }
-		public void setDstPortForTest(Short dstPort) { this.dstPort = dstPort; }
-		public void setMatchSrcMacForTest(String matchSrcMac) { this.matchSrcMac = matchSrcMac; }
-		public void setMatchDstMacForTest(String matchDstMac) { this.matchDstMac = matchDstMac; }
-		public void setMatchEthernetFrameTypeForTest(Short matchEthernetFrameType) { this.matchEthernetFrameType = matchEthernetFrameType; }
-		public void setMatchVlanIdForTest(Short matchVlanId) { this.matchVlanId = matchVlanId; }
-		public void setMatchVlanPriorityForTest(Byte matchVlanPriority) { this.matchVlanPriority = matchVlanPriority; }
-		public void setMatchSrcIpaddrForTest(String matchSrcIpaddr) { this.matchSrcIpaddr = matchSrcIpaddr; }
-		public void setMatchDstIpaddrForTest(String matchDstIpaddr) { this.matchDstIpaddr = matchDstIpaddr; }
-		public void setMatchIpProtoForTest(Byte matchIpProto) { this.matchIpProto = matchIpProto; }
-		public void setMatchIpToSForTest(Byte matchIpToS) { this.matchIpToS = matchIpToS; }
-		public void setMatchSrcTcpUdpPortForTest(Short matchSrcTcpUdpPort) { this.matchSrcTcpUdpPort = matchSrcTcpUdpPort; }
-		public void setMatchDstTcpUdpPortForTest(Short matchDstTcpUdpPort) { this.matchDstTcpUdpPort = matchDstTcpUdpPort; }
-		public void setActionsForTest(String actions) { this.actions = actions; }
-		public void addFlowEntryForTest(IFlowEntry entry) { entries.add(entry); }
-		public void addSwitchForTest(ISwitchObject sw) { switches.add(sw); }
-
-		@Override
-		public String getState() { return state; }
-
-		@Override
-		public void setState(String state) { stateToUpdate = state; }
-
-		@Override
-		public String getType() { return type; }
-
-		@Override
-		public void setType(String type) { typeToUpdate = type; }
-
-		@Override
-		public Vertex asVertex() {
-			// TODO Auto-generated method stub
-			return null;
-		}
-
-		@Override
-		public String getFlowId() { return flowId; }
-
-		@Override
-		public void setFlowId(String flowId) { flowIdToUpdate = flowId; }
-
-		@Override
-		public String getInstallerId() { return installerId; }
-
-		@Override
-		public void setInstallerId(String installerId) { installerIdToUpdate = installerId; }
-
-		@Override
-		public String getFlowPathType() { return flowPathType; }
-
-		@Override
-		public void setFlowPathType(String flowPathType) { flowPathTypeToUpdate = flowPathType; }
-
-		@Override
-		public String getFlowPathUserState() { return flowPathUserState; }
-
-		@Override
-		public void setFlowPathUserState(String flowPathUserState) { flowPathUserStateToUpdate = flowPathUserState; }
-
-		@Override
-		public Long getFlowPathFlags() { return flowPathFlags; }
-
-		@Override
-		public void setFlowPathFlags(Long flowPathFlags) { flowPathFlagsToUpdate = flowPathFlags; }
-
-		@Override
-		public Integer getIdleTimeout() { return idleTimeout; }
-
-		@Override
-		public void setIdleTimeout(Integer idleTimeout) { idleTimeoutToUpdate = idleTimeout; }
-
-		@Override
-		public Integer getHardTimeout() { return hardTimeout; }
-
-		@Override
-		public void setHardTimeout(Integer hardTimeout) { hardTimeoutToUpdate = hardTimeout; }
-
-		@Override
-		public String getSrcSwitch() { return srcSw; }
-
-		@Override
-		public void setSrcSwitch(String srcSwitch) { srcSwToUpdate = srcSwitch; }
-
-		@Override
-		public Short getSrcPort() { return srcPort; }
-
-		@Override
-		public void setSrcPort(Short srcPort) { srcPortToUpdate = srcPort; }
-
-		@Override
-		public String getDstSwitch() { return dstSw; }
-
-		@Override
-		public void setDstSwitch(String dstSwitch) { dstSwToUpdate = dstSwitch; }
-
-		@Override
-		public Short getDstPort() { return dstPort; }
-
-		@Override
-		public void setDstPort(Short dstPort) { dstPortToUpdate = dstPort; }
-
-		@Override
-		public String getDataPathSummary() { return dataPathSummary; }
-
-		@Override
-		public void setDataPathSummary(String dataPathSummary) { dataPathSummaryToUpdate = dataPathSummary; }
-
-		@Override
-		public Iterable<IFlowEntry> getFlowEntries() { return entries; }
-
-		@Override
-		public void addFlowEntry(IFlowEntry flowEntry) {
-			if(! entries.contains(flowEntry)) {
-				flowsToAdd.add(flowEntry);
-			}
-		}
-
-		@Override
-		public void removeFlowEntry(IFlowEntry flowEntry) {
-			if(entries.contains(flowEntry)) {
-				flowsToAdd.add(flowEntry);
-			}
-		}
-
-		@Override
-		public String getMatchSrcMac() { return matchSrcMac; }
-
-		@Override
-		public void setMatchSrcMac(String matchSrcMac) { matchSrcMacToUpdate = matchSrcMac; }
-
-		@Override
-		public String getMatchDstMac() { return matchDstMac; }
-
-		@Override
-		public void setMatchDstMac(String matchDstMac) { matchDstMacToUpdate = matchDstMac; }
-
-		@Override
-		public Short getMatchEthernetFrameType() { return matchEthernetFrameType; }
-
-		@Override
-		public void setMatchEthernetFrameType(Short matchEthernetFrameType) {
-			matchEthernetFrameTypeToUpdate = matchEthernetFrameType; }
-
-		@Override
-		public Short getMatchVlanId() { return matchVlanId; }
-
-		@Override
-		public void setMatchVlanId(Short matchVlanId) {
-			matchVlanIdToUpdate = matchVlanId; }
-
-		@Override
-		public Byte getMatchVlanPriority() { return matchVlanPriority; }
-
-		@Override
-		public void setMatchVlanPriority(Byte matchVlanPriority) {
-			matchVlanPriorityToUpdate = matchVlanPriority; }
-
-		@Override
-		public String getMatchSrcIPv4Net() { return matchSrcIpaddr; }
-
-		@Override
-		public void setMatchSrcIPv4Net(String matchSrcIPv4Net) {
-			matchSrcIpaddrToUpdate = matchSrcIPv4Net; }
-
-		@Override
-		public String getMatchDstIPv4Net() { return matchDstIpaddr; }
-
-		@Override
-		public void setMatchDstIPv4Net(String matchDstIPv4Net) {
-			matchDstIpaddrToUpdate = matchDstIPv4Net; }
-
-		@Override
-		public Byte getMatchIpProto() { return matchIpProto; }
-
-		@Override
-		public void setMatchIpProto(Byte matchIpProto) {
-			matchIpProtoToUpdate = matchIpProto; }
-
-		@Override
-		public Byte getMatchIpToS() { return matchIpToS; }
-
-		@Override
-		public void setMatchIpToS(Byte matchIpToS) {
-			matchIpToSToUpdate = matchIpToS; }
-
-		@Override
-		public Short getMatchSrcTcpUdpPort() { return matchSrcTcpUdpPort; }
-
-		@Override
-		public void setMatchSrcTcpUdpPort(Short matchSrcTcpUdpPort) {
-			matchSrcTcpUdpPortToUpdate = matchSrcTcpUdpPort; }
-
-		@Override
-		public Short getMatchDstTcpUdpPort() { return matchDstTcpUdpPort; }
-
-		@Override
-		public void setMatchDstTcpUdpPort(Short matchDstTcpUdpPort) {
-			matchDstTcpUdpPortToUpdate = matchDstTcpUdpPort; }
-
-		@Override
-		public String getActions() { return actions; }
-
-		@Override
-		public void setActions(String actions) {
-			actionsToUpdate = actions; }
-
-		@Override
-		public Iterable<ISwitchObject> getSwitches() { return switches; }
-	}
-
-	public static class TestFlowEntry implements IFlowEntry {
-		private String state,type,entryId,dpid,userState,switchState,errorStateType,errorStateCode;
-		private Integer idleTimeout;
-		private Integer hardTimeout;
-		private Short matchInPort;
-		private String matchSrcMac,matchDstMac;
-		private Short matchEtherFrameType;
-		private Short matchVlanId;
-		private Byte matchVlanPriority;
-		private String matchSrcIpaddr,matchDstIpaddr;
-		private Byte matchIpProto, matchIpToS;
-		private Short matchSrcTcpUdpPort, matchDstTcpUdpPort;
-		private Short actionOutputPort;
-		private String actions;
-		
-		private IFlowPath flowPath;
-		private ISwitchObject sw;
-		private IPortObject inport,outport;
-	
-		private String stateToUpdate,typeToUpdate,entryIdToUpdate,dpidToUpdate,
-			userStateToUpdate,switchStateToUpdate,errorStateTypeToUpdate,errorStateCodeToUpdate;
-		private Integer idleTimeoutToUpdate;
-		private Integer hardTimeoutToUpdate;
-		private Short matchInPortToUpdate;
-		private String matchSrcMacToUpdate,matchDstMacToUpdate;
-		private Short matchEtherFrameTypeToUpdate;
-		private Short matchVlanIdToUpdate;
-		private Byte matchVlanPriorityToUpdate;
-		private String matchSrcIpaddrToUpdate,matchDstIpaddrToUpdate;
-		private Byte matchIpProtoToUpdate, matchIpToSToUpdate;
-		private Short matchSrcTcpUdpPortToUpdate, matchDstTcpUdpPortToUpdate;
-		private Short actionOutputPortToUpdate;
-		private String actionsToUpdate;
-	
-		private IFlowPath flowPathToUpdate;
-		private ISwitchObject swToUpdate;
-		private IPortObject inportToUpdate,outportToUpdate;
-	
-		public TestFlowEntry() {
-			type = "flow_entry";
-			
-			clearUncommitedData();
-		}
-		
-		public void commit() {
-			if(stateToUpdate != null) { state = stateToUpdate; }
-			if(typeToUpdate != null) { type = typeToUpdate; }
-			if(entryIdToUpdate != null) { entryId = entryIdToUpdate; }
-			if(idleTimeoutToUpdate != null) { idleTimeout = idleTimeoutToUpdate; }
-			if(hardTimeoutToUpdate != null) { hardTimeout = hardTimeoutToUpdate; }
-			if(dpidToUpdate != null) { dpid = dpidToUpdate; }
-			if(userStateToUpdate != null) { userState = userStateToUpdate; }
-			if(switchStateToUpdate != null) { switchState = switchStateToUpdate; }
-			if(errorStateTypeToUpdate != null) { errorStateType = errorStateTypeToUpdate; }
-			if(errorStateCodeToUpdate != null) { errorStateCode = errorStateCodeToUpdate; }
-			if(matchInPortToUpdate != null) { matchInPort = matchInPortToUpdate; }
-			if(matchSrcMacToUpdate != null) { matchSrcMac = matchSrcMacToUpdate; }
-			if(matchDstMacToUpdate != null) { matchDstMac = matchDstMacToUpdate; }
-			if(matchEtherFrameTypeToUpdate != null) { matchEtherFrameType = matchEtherFrameTypeToUpdate; }
-			if(matchVlanIdToUpdate != null) { matchVlanId = matchVlanIdToUpdate; }
-			if(matchVlanPriorityToUpdate != null) { matchVlanPriority = matchVlanPriorityToUpdate; }
-			if(matchSrcIpaddrToUpdate != null) { matchSrcIpaddr = matchSrcIpaddrToUpdate; }
-			if(matchDstIpaddrToUpdate != null) { matchDstIpaddr = matchDstIpaddrToUpdate; }
-			if(matchIpProtoToUpdate != null) { matchIpProto = matchIpProtoToUpdate; }
-			if(matchIpToSToUpdate != null) { matchIpToS = matchIpToSToUpdate; }
-			if(matchSrcTcpUdpPortToUpdate != null) { matchSrcTcpUdpPort = matchSrcTcpUdpPortToUpdate; }
-			if(matchDstTcpUdpPortToUpdate != null) { matchDstTcpUdpPort = matchDstTcpUdpPortToUpdate; }
-			if(actionOutputPortToUpdate != null) { actionOutputPort = actionOutputPortToUpdate; }
-			if(actionsToUpdate != null) { actions = actionsToUpdate; }
-			
-			if(flowPathToUpdate != null) { flowPath = flowPathToUpdate; }
-			if(swToUpdate != null) { sw = swToUpdate; }
-			if(inportToUpdate != null) { inport = inportToUpdate; }
-			if(outportToUpdate != null) { outport = outportToUpdate; }
-	
-			clearUncommitedData();
-		}
-		
-		public void rollback() {
-			clearUncommitedData();
-		}
-		
-		public void clearUncommitedData() {
-			stateToUpdate = typeToUpdate = entryIdToUpdate = dpidToUpdate = null;
-			idleTimeoutToUpdate = hardTimeoutToUpdate = null;
-			userStateToUpdate = switchStateToUpdate = errorStateTypeToUpdate = errorStateCodeToUpdate = null;
-			matchInPortToUpdate = null;
-			matchSrcMacToUpdate = matchDstMacToUpdate = null;
-			matchEtherFrameTypeToUpdate = null;
-			matchVlanIdToUpdate = null;
-			matchVlanPriorityToUpdate = null;
-			matchSrcIpaddrToUpdate = matchDstIpaddrToUpdate = null;
-			matchIpProtoToUpdate = matchIpToSToUpdate = null;
-			matchSrcTcpUdpPortToUpdate = matchDstTcpUdpPortToUpdate = null;
-			actionOutputPortToUpdate = null;
-			actionsToUpdate = null;
-			flowPathToUpdate = null;
-			swToUpdate = null;
-			inportToUpdate = outportToUpdate = null;
-		}
-		
-		// Setter methods for test
-		public void setStateForTest(String state) { this.state = state; }
-		public void setTypeForTest(String type) { this.type = type; }
-		public void setEntryIdForTest(String entryId) { this.entryId = entryId; }
-		public void setIdleTimeoutForTest(Integer idleTimeout) { this.idleTimeout = idleTimeout; }
-		public void setHardTimeoutForTest(Integer hardTimeout) { this.hardTimeout = hardTimeout; }
-		public void setDpidForTest(String dpid) { this.dpid = dpid; }
-		public void setUserStateForTest(String userState) { this.userState = userState; }
-		public void setSwitchStateForTest(String switchState) { this.switchState = switchState; }
-		public void setErrorStateTypeForTest(String errorStateType) { this.errorStateType = errorStateType; }
-		public void setErrorStateCodeForTest(String errorStateCode) { this.errorStateCode = errorStateCode; }
-		public void setMatchInPortForTest(Short matchInPort) { this.matchInPort = matchInPort; }
-		public void setMatchSrcMacForTest(String matchSrcMac) { this.matchSrcMac = matchSrcMac; }
-		public void setMatchDstMacForTest(String matchDstMac) { this.matchDstMac = matchDstMac; }
-		public void setMatchEtherFrameTypeForTest(Short matchEtherFrameType) { this.matchEtherFrameType = matchEtherFrameType; }
-		public void setMatchVlanIdForTest(Short matchVlanId) { this.matchVlanId = matchVlanId; }
-		public void setMatchVlanPriorityForTest(Byte matchVlanPriority) { this.matchVlanPriority = matchVlanPriority; }
-		public void setMatchSrcIpaddrForTest(String matchSrcIpaddr) { this.matchSrcIpaddr = matchSrcIpaddr; }
-		public void setMatchDstIpaddrForTest(String matchDstIpaddr) { this.matchDstIpaddr = matchDstIpaddr; }
-		public void setMatchIpProtoForTest(Byte matchIpProto) { this.matchIpProto = matchIpProto; }
-		public void setMatchIpToSForTest(Byte matchIpToS) { this.matchIpToS = matchIpToS; }
-		public void setMatchSrcTcpUdpPortForTest(Short matchSrcTcpUdpPort) { this.matchSrcTcpUdpPort = matchSrcTcpUdpPort; }
-		public void setMatchDstTcpUdpPortForTest(Short matchDstTcpUdpPort) { this.matchDstTcpUdpPort = matchDstTcpUdpPort; }
-		public void setActionOutputPortForTest(Short actionOutputPort) { this.actionOutputPort = actionOutputPort; }
-		public void setActionsForTest(String actions) { this.actions = actions; }
-		public void setFlowPathForTest(IFlowPath flowPath) { this.flowPath = flowPath; }
-		public void setSwitchForTest(ISwitchObject sw) { this.sw = sw; }
-		public void setInportForTest(IPortObject inport) { this.inport = inport; }
-		public void setOutportForTest(IPortObject outport) { this.outport = outport; }
-		
-		@Override
-		public String getState() { return state; }
-	
-		@Override
-		public void setState(String state) { stateToUpdate = state; }
-	
-		@Override
-		public String getType() { return type; }
-	
-		@Override
-		public void setType(String type) { typeToUpdate = type; }
-	
-		@Override
-		public Vertex asVertex() {
-			// TODO Auto-generated method stub
-			return null;
-		}
-	
-		@Override
-		public String getFlowEntryId() { return entryId; }
-	
-		@Override
-		public void setFlowEntryId(String flowEntryId) { entryIdToUpdate = flowEntryId; }
-
-		@Override
-		public Integer getIdleTimeout() { return idleTimeout; }
-	
-		@Override
-		public void setIdleTimeout(Integer idleTimeout) { idleTimeoutToUpdate = idleTimeout; }
-
-		@Override
-		public Integer getHardTimeout() { return hardTimeout; }
-	
-		@Override
-		public void setHardTimeout(Integer hardTimeout) { hardTimeoutToUpdate = hardTimeout; }
-	
-		@Override
-		public String getSwitchDpid() { return dpid; }
-	
-		@Override
-		public void setSwitchDpid(String switchDpid) { dpidToUpdate = switchDpid; }
-	
-		@Override
-		public String getUserState() { return userState; }
-	
-		@Override
-		public void setUserState(String userState) { userStateToUpdate = userState; }
-	
-		@Override
-		public String getSwitchState() { return switchState; }
-	
-		@Override
-		public void setSwitchState(String switchState) { switchStateToUpdate = switchState; }
-	
-		@Override
-		public String getErrorStateType() { return errorStateType; }
-	
-		@Override
-		public void setErrorStateType(String errorStateType) { errorStateTypeToUpdate = errorStateType; }
-	
-		@Override
-		public String getErrorStateCode() { return errorStateCode; }
-	
-		@Override
-		public void setErrorStateCode(String errorStateCode) { errorStateCodeToUpdate = errorStateCode; }
-	
-		@Override
-		public Short getMatchInPort() { return matchInPort; }
-	
-		@Override
-		public void setMatchInPort(Short matchInPort) { matchInPortToUpdate = matchInPort; }
-	
-		@Override
-		public String getMatchSrcMac() { return matchSrcMac; }
-	
-		@Override
-		public void setMatchSrcMac(String matchSrcMac) { matchSrcMacToUpdate = matchSrcMac; }
-	
-		@Override
-		public String getMatchDstMac() { return matchDstMac; }
-	
-		@Override
-		public void setMatchDstMac(String matchDstMac) { matchDstMacToUpdate = matchDstMac; }
-
-		@Override
-		public Short getMatchEthernetFrameType() {return matchEtherFrameType; }
-	
-		@Override
-		public void setMatchEthernetFrameType(Short matchEthernetFrameType) { matchEtherFrameTypeToUpdate = matchEthernetFrameType; }
-
-		@Override
-		public Short getMatchVlanId() {return matchVlanId; }
-	
-		@Override
-		public void setMatchVlanId(Short matchVlanId) { matchVlanIdToUpdate = matchVlanId; }
-
-		@Override
-		public Byte getMatchVlanPriority() {return matchVlanPriority; }
-	
-		@Override
-		public void setMatchVlanPriority(Byte matchVlanPriority) { matchVlanPriorityToUpdate = matchVlanPriority; }
-		
-		@Override
-		public String getMatchSrcIPv4Net() { return matchSrcIpaddr; }
-	
-		@Override
-		public void setMatchSrcIPv4Net(String matchSrcIPv4Net) { matchSrcIpaddrToUpdate = matchSrcIPv4Net; }
-	
-		@Override
-		public String getMatchDstIPv4Net() { return matchDstIpaddr; }
-	
-		@Override
-		public void setMatchDstIPv4Net(String matchDstIPv4Net) { matchDstIpaddrToUpdate = matchDstIPv4Net; }
-
-		@Override
-		public Byte getMatchIpProto() {return matchIpProto; }
-	
-		@Override
-		public void setMatchIpProto(Byte matchIpProto) { matchIpProtoToUpdate = matchIpProto; }
-
-		@Override
-		public Byte getMatchIpToS() {return matchIpToS; }
-	
-		@Override
-		public void setMatchIpToS(Byte matchIpToS) { matchIpToSToUpdate = matchIpToS; }
-
-		@Override
-		public Short getMatchSrcTcpUdpPort() {return matchSrcTcpUdpPort; }
-	
-		@Override
-		public void setMatchSrcTcpUdpPort(Short matchSrcTcpUdpPort) { matchSrcTcpUdpPortToUpdate = matchSrcTcpUdpPort; }
-
-		@Override
-		public Short getMatchDstTcpUdpPort() {return matchDstTcpUdpPort; }
-	
-		@Override
-		public void setMatchDstTcpUdpPort(Short matchDstTcpUdpPort) { matchDstTcpUdpPortToUpdate = matchDstTcpUdpPort; }
-	
-		@Override
-		public Short getActionOutputPort() { return actionOutputPort; }
-	
-		@Override
-		public void setActionOutputPort(Short actionOutputPort) { actionOutputPortToUpdate = actionOutputPort; }
-
-		@Override
-		public String getActions() { return actions; }
-	
-		@Override
-		public void setActions(String actions) { actionsToUpdate = actions; }
-	
-		@Override
-		public IFlowPath getFlow() { return flowPath; }
-	
-		@Override
-		public void setFlow(IFlowPath flow) { flowPathToUpdate = flow; }
-	
-		@Override
-		public ISwitchObject getSwitch() { return sw; }
-	
-		@Override
-		public void setSwitch(ISwitchObject sw) { swToUpdate = sw; }
-	
-		@Override
-		public IPortObject getInPort() { return inport; }
-	
-		@Override
-		public void setInPort(IPortObject port) { inportToUpdate = port; }
-	
-		@Override
-		public IPortObject getOutPort() { return outport; }
-	
-		@Override
-		public void setOutPort(IPortObject port) { outportToUpdate = port; }
-	}
-
-
-	public TestableGraphDBOperation() {
-		super(EasyMock.createNiceMock(GraphDBConnection.class));
-		
-		switches = new ArrayList<TestSwitchObject>();
-		ports = new ArrayList<TestPortObject>();
-		devices = new ArrayList<TestDeviceObject>();
-		paths = new ArrayList<TestFlowPath>();
-		entries = new ArrayList<TestFlowEntry>();
-		
-		switchesToAdd = new ArrayList<TestSwitchObject>();
-		portsToAdd = new ArrayList<TestPortObject>();
-		devicesToAdd = new ArrayList<TestDeviceObject>();
-		pathsToAdd = new ArrayList<TestFlowPath>();
-		entriesToAdd = new ArrayList<TestFlowEntry>();
-
-		switchesToRemove = new ArrayList<TestSwitchObject>();
-		portsToRemove = new ArrayList<TestPortObject>();
-		devicesToRemove = new ArrayList<TestDeviceObject>();
-		pathsToRemove = new ArrayList<TestFlowPath>();
-		entriesToRemove = new ArrayList<TestFlowEntry>();
-		
-		clearUncommitedData();
-	}
-	
-	private void clearUncommitedData() {
-		for(TestFlowEntry flow : entries) {
-			flow.clearUncommitedData();
-		}
-		for(TestFlowEntry flow : entriesToAdd) {
-			flow.clearUncommitedData();
-		}
-		
-		for(TestDeviceObject dev : devices) {
-			dev.clearUncommitedData();
-		}
-		for(TestDeviceObject dev : devicesToAdd) {
-			dev.clearUncommitedData();
-		}
-		
-		for(TestSwitchObject sw : switches) {
-			sw.clearUncommitedData();
-		}
-		for(TestSwitchObject sw : switchesToAdd) {
-			sw.clearUncommitedData();
-		}
-		
-		for(TestPortObject port : ports) {
-			port.clearUncommitedData();
-		}
-		for(TestPortObject port : portsToAdd) {
-			port.clearUncommitedData();
-		}
-		
-		entriesToAdd.clear();
-		entriesToRemove.clear();
-		devicesToAdd.clear();
-		devicesToRemove.clear();
-		switchesToAdd.clear();
-		switchesToRemove.clear();
-		portsToAdd.clear();
-		portsToRemove.clear();
-	}
-	
-	
-	// this.*ForTest() methods below are supposed to be used for creation of test topology.
-	/**
-	 * Create new empty TestSwitchObject.
-	 * @return New TestSwitchObject
-	 */
-	public TestSwitchObject createNewSwitchForTest() {
-		TestSwitchObject sw = new TestSwitchObject();
-		switches.add(sw);
-		return sw;
-	}
-	
-	/**
-	 * Create new TestSwitchObject with specific DPID.
-	 * @param dpid DPID to be set
-	 * @return New TestSwitchObject
-	 */
-	public TestSwitchObject createNewSwitchForTest(String dpid) {
-		for(TestSwitchObject sw_loop : switches) {
-			if(sw_loop.getDPID().equals(dpid)) {
-				// Already created
-				log.error("switch already exists : " + dpid);
-				return sw_loop;
-			}
-		}
-
-		TestSwitchObject sw = new TestSwitchObject();
-		
-		sw.setDpidForTest(dpid);
-		switches.add(sw);
-		
-		return sw;
-	}
-	
-	/**
-	 * Create new empty TestPortObject.
-	 * @return New TestPortObject
-	 */
-	public TestPortObject createNewPortForTest() {
-		TestPortObject port = new TestPortObject();
-		ports.add(port);
-		return port;
-	}
-	
-	/**
-	 * Create new TestPortObject with specific DPID and port number.
-	 * @param dpid DPID to be set
-	 * @param number Port number to be set
-	 * @return New TestPortObject
-	 */
-	public TestPortObject createNewPortForTest(String dpid, Short number) {
-		TestSwitchObject sw = null;
-		
-		for(TestSwitchObject sw_loop : switches) {
-			if(sw_loop.getDPID().equals(dpid)) {
-				sw = sw_loop;
-			}
-		}
-		
-		if(sw != null) {
-			TestPortObject port = new TestPortObject();
-			port.setNumberForTest(number);
-			port.setSwitchForTest(sw);
-			sw.addPortForTest(port);
-			
-			ports.add(port);
-
-			return port;
-		} else {
-			return  null;
-		}
-	}
-	
-	/**
-	 * Link a TestPortObject to other TestPortObject.
-	 * @param src TestPortObjecgt of source port.
-	 * @param dst TestPortObjecgt of destination port.
-	 */
-	public void setLinkBetweenPortsForTest(TestPortObject src, TestPortObject dst) {
-		src.addLinkedPortForTest(dst);
-	}
-	
-	/**
-	 * Create new empty TestDeviceObject.
-	 * @return New TestDeviceObject
-	 */
-	public TestDeviceObject createNewDeviceForTest() {
-		TestDeviceObject dev = new TestDeviceObject();
-		
-		return dev;
-	}
-	
-	/**
-	 * Create new empty TestFlowPathObject.
-	 * @return New TestFlowPathObject
-	 */
-	public TestFlowPath createNewFlowPathForTest() {
-		TestFlowPath path = new TestFlowPath();
-		paths.add(path);
-		return path;
-	}
-
-	/**
-	 * Create new empty TestFlowEntryObject.
-	 * @return New TestFlowEntryObject
-	 */
-	public TestFlowEntry createNewFlowEntryForTest() {
-		TestFlowEntry entry = new TestFlowEntry();
-		entries.add(entry);
-		return entry;
-	}
-
-	
-	public boolean hasLinkBetween(String srcSw_str, Short srcNumber, String dstSw_str, Short dstNumber) {
-		IPortObject srcPort = null, dstPort = null;
-		long srcSw = HexString.toLong(srcSw_str);
-		long dstSw = HexString.toLong(dstSw_str);
-		
-		for(TestSwitchObject sw : switches) {
-			long swLong = HexString.toLong(sw.getDPID());
-			if(swLong == srcSw) {
-				for(IPortObject port : sw.getPorts()) {
-					if(port.getNumber().equals(srcNumber)) {
-						srcPort = port;
-					}
-				}
-			} else if(swLong == dstSw) {
-				for(IPortObject port : sw.getPorts()) {
-					if(port.getNumber().equals(dstNumber)) {
-						dstPort = port;
-					}
-				}
-			}
-		}
-		
-		if(srcPort != null && dstPort != null) {
-			for(IPortObject port : srcPort.getLinkedPorts()) {
-				if(port.equals(dstPort)) {
-					return true;
-				}
-			}
-		}
-		
-		return false;
-	}
-
-	// Overriding methods below are to mock GraphDBOperation class.
-	@Override
-	public ISwitchObject newSwitch(String dpid) {
-		TestSwitchObject sw = new TestSwitchObject();
-		sw.setDPID(dpid);
-		switchesToAdd.add(sw);
-		
-		return sw;
-	}
-
-	@Override
-	public ISwitchObject searchSwitch(String dpid_str) {
-		Long dpid = HexString.toLong(dpid_str);
-		
-		for(ISwitchObject sw : switches) {
-			if(HexString.toLong(sw.getDPID()) == dpid) {
-				return sw;
-			}
-		}
-		return null;
-	}
-
-	@Override
-	public ISwitchObject searchActiveSwitch(String dpid_str) {
-		Long dpid = HexString.toLong(dpid_str);
-
-		for(ISwitchObject sw : switches) {
-			if(HexString.toLong(sw.getDPID()) == dpid && sw.getState().equals("ACTIVE")) {
-				return sw;
-			}
-		}
-		return null;
-	}
-
-	@Override
-	public Iterable<ISwitchObject> getActiveSwitches() {
-		List<ISwitchObject> list = new ArrayList<ISwitchObject>();
-		
-		for(ISwitchObject sw : switches) {
-			if(sw.getState() != null && sw.getState().equals("ACTIVE")) {
-				list.add(sw);
-			}
-		}
-		return list.isEmpty() ? null : list;
-	}
-
-	@Override
-	public Iterable<ISwitchObject> getAllSwitches() {
-		List<ISwitchObject> list = new ArrayList<ISwitchObject>();
-		
-		for(ISwitchObject sw : switches) {
-			list.add(sw);
-		}
-		
-		return list.isEmpty() ? null : list;
-	}
-
-	@Override
-	public Iterable<ISwitchObject> getInactiveSwitches() {
-		List<ISwitchObject> list = new ArrayList<ISwitchObject>();
-		
-		for(ISwitchObject sw : switches) {
-			if(! sw.getState().equals("ACTIVE")) {
-				list.add(sw);
-			}
-		}
-		return list.isEmpty() ? null : list;
-	}
-
-	@Override
-	public Iterable<IFlowEntry> getAllSwitchNotUpdatedFlowEntries() {
-		List<IFlowEntry> list = new ArrayList<IFlowEntry>();
-		
-		for(TestFlowEntry entry : entries) {
-			if(entry.getSwitchState().equals("FE_SWITCH_NOT_UPDATED")) {
-				list.add(entry);
-			}
-		}
-		return list;
-	}
-
-	@Override
-	public void removeSwitch(ISwitchObject sw) {
-		if(switches.contains(sw)) {
-			switchesToRemove.add((TestSwitchObject)sw);
-		}
-	}
-
-	@Override
-	public IPortObject newPort(Short portNumber) {
-		TestPortObject port = new TestPortObject();
-		port.setNumber(portNumber);
-		
-		return port;
-	}
-
-	public IPortObject newPort(Long dpid, Short portNumber) {
-		TestPortObject port = null;
-		TestSwitchObject sw = (TestSwitchObject)searchSwitch(HexString.toHexString(dpid));
-		
-		if(sw != null) {
-			port = (TestPortObject)newPort(portNumber);
-			portsToAdd.add(port);
-			sw.addPort(port);
-		}
-		
-		return port;
-	}
-	
-	@Override
-	public IPortObject searchPort(String dpid_str, Short number) {
-		long dpid = HexString.toLong(dpid_str);
-		
-		for(TestSwitchObject sw : switches) {
-			if(HexString.toLong(sw.getDPID()) == dpid) {
-				for(IPortObject port : sw.getPorts()) {
-					if(port.getNumber().equals(number)) {
-						return port;
-					}
-				}
-			}
-		}
-		return null;
-	}
-
-	@Override
-	public void removePort(IPortObject port) {
-		for(TestSwitchObject sw : switches) {
-			for(IPortObject pt : sw.getPorts()) {
-				if(pt.equals(port)) {
-					sw.removePort(port);
-				}
-			}
-		}
-		portsToRemove.add((TestPortObject)port);
-	}
-
-	@Override
-	public IDeviceObject newDevice() {
-		TestDeviceObject dev = new TestDeviceObject();
-		devicesToAdd.add(dev);
-		
-		return dev;
-	}
-
-	@Override
-	public IDeviceObject searchDevice(String macAddr) {
-		for(IDeviceObject dev : devices) {
-			if(dev.getMACAddress().equals(macAddr)) {
-				return dev;
-			}
-		}
-		return null;
-	}
-
-	@Override
-	public Iterable<IDeviceObject> getDevices() {
-		List<IDeviceObject> list = new ArrayList<IDeviceObject>();
-		
-		for(TestDeviceObject dev : devices) {
-			list.add(dev);
-		}
-		
-		return list;
-	}
-
-	@Override
-	public void removeDevice(IDeviceObject dev) {
-		if(devices.contains((TestDeviceObject)dev)) {
-			devicesToRemove.add((TestDeviceObject)dev);
-		}
-	}
-
-	@Override
-	public IFlowPath newFlowPath() {
-		TestFlowPath path = new TestFlowPath();
-		pathsToAdd.add(path);
-		
-		return path;
-	}
-
-	@Override
-	public IFlowPath searchFlowPath(FlowId flowId) {
-		for(IFlowPath path : paths) {
-			if(path.getFlowId().equals(flowId)) {
-				return path;
-			}
-		}
-		return null;
-	}
-
-	@Override
-	public IFlowPath getFlowPathByFlowEntry(IFlowEntry flowEntry) {
-		for(IFlowPath path : paths) {
-			for(IFlowEntry entry : path.getFlowEntries()) {
-				if(entry.equals(flowEntry)) {
-					return path;
-				}
-			}
-
-		}
-		return null;
-	}
-
-	@Override
-	public Iterable<IFlowPath> getAllFlowPaths() {
-		List<IFlowPath> list = new ArrayList<IFlowPath>();
-		
-		for(IFlowPath path : paths) {
-			list.add(path);
-		}
-		
-		return list;
-	}
-
-	@Override
-	public void removeFlowPath(IFlowPath flowPath) {
-		if(paths.contains((TestFlowPath)flowPath)) {
-			pathsToRemove.add((TestFlowPath)flowPath);
-		}
-	}
-
-	@Override
-	public IFlowEntry newFlowEntry() {
-		TestFlowEntry entry = new TestFlowEntry();
-		entriesToAdd.add(entry);
-		return entry;
-	}
-
-	@Override
-	public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId) {
-		for(TestFlowEntry entry : entries) {
-			// TODO check if this matching works
-			if(entry.getFlowEntryId().equals(flowEntryId)) {
-				return entry;
-			}
-		}
-		return null;
-	}
-
-	@Override
-	public Iterable<IFlowEntry> getAllFlowEntries() {
-		List<IFlowEntry> list = new ArrayList<IFlowEntry>();
-		
-		for(TestFlowEntry entry : entries) {
-			list.add(entry);
-		}
-		
-		return list;
-	}
-
-	@Override
-	public void removeFlowEntry(IFlowEntry flowEntry) {
-		if(entries.contains((TestFlowEntry)flowEntry)) {
-			entriesToRemove.add((TestFlowEntry)flowEntry);
-		}
-	}
-
-	@Override
-	public IDBConnection getDBConnection() {
-		return super.getDBConnection();
-	}
-
-	@Override
-	public void commit() {
-		for(TestSwitchObject sw : switchesToAdd) {
-			switches.add(sw);
-		}
-		for(TestSwitchObject sw : switchesToRemove) {
-			sw.commit();
-			switches.remove(sw);
-		}
-		for(TestSwitchObject sw : switches) {
-			sw.commit();
-		}
-		
-		for(TestPortObject port : portsToAdd) {
-			ports.add(port);
-		}
-		for(TestPortObject port : portsToRemove) {
-			port.commit();
-			ports.remove(port);
-		}
-		for(TestPortObject port : ports) {
-			port.commit();
-		}
-		
-		for(TestDeviceObject dev : devicesToAdd) {
-			devices.add(dev);
-		}
-		for(TestDeviceObject dev : devicesToRemove) {
-			dev.commit();
-			devices.remove(dev);
-		}
-		for(TestDeviceObject dev : devices) {
-			dev.commit();
-		}
-		
-		clearUncommitedData();
-	}
-
-	@Override
-	public void rollback() {
-		clearUncommitedData();
-	}
-
-	@Override
-	public void close() {
-		// TODO Auto-generated method stub
-
-	}
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTest.java b/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTest.java
deleted file mode 100644
index d017546..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTest.java
+++ /dev/null
@@ -1,522 +0,0 @@
-package net.onrc.onos.ofcontroller.devicemanager.internal;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.SwitchPort;
-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.IIpv4Address;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
-import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
-
-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.openflow.util.HexString;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.net.InetAddresses;
-import com.thinkaurelius.titan.core.TitanFactory;
-
-//Add Powermock preparation
-@Ignore //TODO broken 11/19/13, should fix
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, DeviceStorageImpl.class})
-public class DeviceStorageImplTest{
-	
-	protected final static Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
-	
-	String conf;
-        String dbStore;
-	DeviceStorageImpl deviceImpl;
-    private GraphDBConnection mockConn;
-    private GraphDBOperation mockOpe;
-    
-	@Before
-	public void setUp() throws Exception {
-	    deviceImpl = new DeviceStorageImpl();	
-		conf = "/dummy/path/to/db";
-                dbStore = "dummyStore";
-				
-		PowerMock.mockStatic(GraphDBConnection.class);
-		mockConn = createMock(GraphDBConnection.class);
-		PowerMock.suppress(PowerMock.constructor(GraphDBConnection.class));
-		EasyMock.expect(GraphDBConnection.getInstance((String)EasyMock.anyObject())).andReturn(mockConn);
-		PowerMock.replay(GraphDBConnection.class);
-			
-		//PowerMock.mockStatic(GraphDBOperation.class);
-		mockOpe = PowerMock.createMock(GraphDBOperation.class);
-		PowerMock.expectNew(GraphDBOperation.class, new Class<?>[]{String.class}, conf).andReturn(mockOpe);
-		//mockOpe.close();
-		PowerMock.replay(GraphDBOperation.class);
-        // Replace the conf to dummy conf
-		// String conf = "/tmp/cassandra.titan";
-
-		deviceImpl.init(dbStore, conf);
-
-	}
-
-	@After
-	public void tearDown() throws Exception {	
-		verify(mockOpe);
-	}
-	
-	private IPortObject getMockPort(long dpid, short port) {
-		IPortObject mockPortObject = createMock(IPortObject.class);
-		expect(mockPortObject.getNumber()).andReturn(port).anyTimes();
-		expect(mockPortObject.getDesc()).andReturn("test port").anyTimes();
-		return mockPortObject;
-	}
-	
-	private IDevice getMockDevice(String strMacAddress, long attachmentDpid, 
-			short attachmentPort, int ipv4Address) {
-		IDevice mockIDevice = createMock(IDevice.class);
-		
-		
-		long longMacAddress = HexString.toLong(strMacAddress);
-		
-		SwitchPort[] attachmentSwitchPorts = {new SwitchPort(attachmentDpid, attachmentPort)};
-		
-		expect(mockIDevice.getMACAddress()).andReturn(longMacAddress).anyTimes();
-		expect(mockIDevice.getMACAddressString()).andReturn(strMacAddress).anyTimes();
-		expect(mockIDevice.getAttachmentPoints()).andReturn(attachmentSwitchPorts).anyTimes();
-		expect(mockIDevice.getIPv4Addresses()).andReturn(new Integer[] {ipv4Address}).anyTimes();
-		
-		replay(mockIDevice);
-		
-		return mockIDevice;
-	}
-	
-	/**
-	 * Description:
-	 *  Test method for addDevice method.
-	 * Condition:
-	 *  The device does not already exist in the database
-	 * Expect:
-	 * 	Get proper IDeviceObject
-	 */
-	@Test
-	public void testAddNewDevice() {
-		String strMacAddress = "99:99:99:99:99:99";
-		long attachmentDpid = HexString.toLong("00:00:00:00:00:00:0a:01");
-		short attachmentPort = 2;
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.100.1"));
-		
-		IDevice device = getMockDevice(strMacAddress, attachmentDpid, attachmentPort, intIpv4Address);
-		
-		IDeviceObject mockDeviceObject = createMock(IDeviceObject.class);
-		IPortObject mockPortObject = getMockPort(attachmentDpid, attachmentPort); 
-		IIpv4Address mockIpv4Address = createMock(IIpv4Address.class);
-		
-		expect(mockOpe.searchDevice(strMacAddress)).andReturn(null);
-		expect(mockOpe.newDevice()).andReturn(mockDeviceObject);
-		expect(mockDeviceObject.getAttachedPorts()).andReturn(Collections.<IPortObject>emptyList());
-		expect(mockOpe.searchPort(HexString.toHexString(attachmentDpid), attachmentPort)).andReturn(mockPortObject);
-		mockPortObject.setDevice(mockDeviceObject);
-		expect(mockDeviceObject.getIpv4Address(intIpv4Address)).andReturn(null);
-		expect(mockOpe.ensureIpv4Address(intIpv4Address)).andReturn(mockIpv4Address);
-		mockDeviceObject.addIpv4Address(mockIpv4Address);
-		expect(mockDeviceObject.getIpv4Addresses()).andReturn(Collections.singleton(mockIpv4Address));
-		expect(mockIpv4Address.getIpv4Address()).andReturn(intIpv4Address);
-		
-		mockDeviceObject.setMACAddress(strMacAddress);
-		mockDeviceObject.setType("device");
-		mockDeviceObject.setState("ACTIVE");
-		mockOpe.commit();
-		
-		replay(mockDeviceObject);
-		replay(mockPortObject);
-		replay(mockIpv4Address);
-		replay(mockOpe);
-		
-		IDeviceObject addedObject = deviceImpl.addDevice(device);
-		assertNotNull(addedObject);
-		
-		verify(mockDeviceObject);
-	}
-	
-	/**
-	 * Description:
-	 * 	Test method for addDevice method.
-	 * Condition:
-	 *  The device already exists in the database.
-	 * Expect:
-	 * 	Get proper IDeviceObject still.
-	 *  Check the IDeviceObject properties set expectedly. 
-	 */
-	@Test
-	public void testAddExistingDevice() {
-		String strMacAddress = "99:99:99:99:99:99";
-		long attachmentDpid = HexString.toLong("00:00:00:00:00:00:0a:01");
-		short attachmentPort = 2;
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.100.1"));
-		
-		IDevice device = getMockDevice(strMacAddress, attachmentDpid, attachmentPort, intIpv4Address);
-		
-		IDeviceObject mockDeviceObject = createMock(IDeviceObject.class);
-		IPortObject mockPortObject = getMockPort(attachmentDpid, attachmentPort); 
-		IIpv4Address mockIpv4Address = createMock(IIpv4Address.class);
-		
-		expect(mockOpe.searchDevice(strMacAddress)).andReturn(mockDeviceObject);
-		expect(mockDeviceObject.getAttachedPorts()).andReturn(Collections.singleton(mockPortObject));
-		expect(mockOpe.searchPort(HexString.toHexString(attachmentDpid), attachmentPort)).andReturn(mockPortObject);
-		expect(mockDeviceObject.getIpv4Address(intIpv4Address)).andReturn(mockIpv4Address);
-		expect(mockDeviceObject.getIpv4Addresses()).andReturn(Collections.singleton(mockIpv4Address));
-		expect(mockIpv4Address.getIpv4Address()).andReturn(intIpv4Address);
-		
-		mockDeviceObject.setMACAddress(strMacAddress);
-		mockDeviceObject.setType("device");
-		mockDeviceObject.setState("ACTIVE");
-		mockOpe.commit();
-		
-		replay(mockDeviceObject);
-		replay(mockPortObject);
-		replay(mockIpv4Address);
-		replay(mockOpe);
-		
-		IDeviceObject addedObject = deviceImpl.addDevice(device);
-		assertNotNull(addedObject);
-		
-		verify(mockDeviceObject);
-	}
-	
-	/**
-	 * Description:
-	 * 	Test method for updateDevice method.
-	 *  NB. this is the same test as testAddExistingDevice
-	 * Condition:
-	 * 	The MAC address and attachment point are the same. 
-	 *  All of the other parameter are different.
-	 * Expect:
-	 * 	Changed parameters are set expectedly.
-	 */
-	@Test
-	public void testAddUpdateDevice() {
-		String strMacAddress = "99:99:99:99:99:99";
-		long attachmentDpid = HexString.toLong("00:00:00:00:00:00:0a:01");
-		short attachmentPort = 2;
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.100.1"));
-		
-		IDevice device = getMockDevice(strMacAddress, attachmentDpid, attachmentPort, intIpv4Address);
-		
-		IDeviceObject mockDeviceObject = createMock(IDeviceObject.class);
-		IPortObject mockPortObject = getMockPort(attachmentDpid, attachmentPort); 
-		IIpv4Address mockIpv4Address = createMock(IIpv4Address.class);
-		
-		expect(mockOpe.searchDevice(strMacAddress)).andReturn(mockDeviceObject);
-		expect(mockDeviceObject.getAttachedPorts()).andReturn(Collections.singleton(mockPortObject));
-		expect(mockOpe.searchPort(HexString.toHexString(attachmentDpid), attachmentPort)).andReturn(mockPortObject);
-		expect(mockDeviceObject.getIpv4Address(intIpv4Address)).andReturn(mockIpv4Address);
-		expect(mockDeviceObject.getIpv4Addresses()).andReturn(Collections.singleton(mockIpv4Address));
-		expect(mockIpv4Address.getIpv4Address()).andReturn(intIpv4Address);
-		
-		mockDeviceObject.setMACAddress(strMacAddress);
-		mockDeviceObject.setType("device");
-		mockDeviceObject.setState("ACTIVE");
-		mockOpe.commit();
-		
-		replay(mockDeviceObject);
-		replay(mockPortObject);
-		replay(mockIpv4Address);
-		replay(mockOpe);
-		
-		IDeviceObject addedObject = deviceImpl.updateDevice(device);
-		assertNotNull(addedObject);
-		
-		verify(mockDeviceObject);
-
-	}
-
-	/**
-	 * Description:
-	 * 	Test method for testRemoveDevice method.
-	 * Condition:
-	 * 	1. Unregistered IDeviceObject argument is put. 
-	 * Expect:
-	 *  1. Nothing happen when unregistered IDeviceObject is put
-	 * 	2. IDeviceObject will be removed.
-	 */
-	@Test
-	public void testRemoveDevice() {
-		String strMacAddress = "99:99:99:99:99:99";
-		long attachmentDpid = HexString.toLong("00:00:00:00:00:00:0a:01");
-		short attachmentPort = 2;
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.100.1"));
-		
-		IIpv4Address ipv4AddressObject = createMock(IIpv4Address.class);
-		IDeviceObject deviceObject = createMock(IDeviceObject.class);
-		expect(deviceObject.getIpv4Addresses()).andReturn(Collections.singleton(ipv4AddressObject));
-		expect(deviceObject.getMACAddress()).andReturn(strMacAddress);
-		replay(deviceObject);
-		
-		expect(mockOpe.searchDevice(strMacAddress)).andReturn(deviceObject);
-		mockOpe.removeIpv4Address(ipv4AddressObject);
-		mockOpe.removeDevice(deviceObject);
-		mockOpe.commit();
-		replay(mockOpe);
-		
-		IDevice device = getMockDevice(strMacAddress, attachmentDpid, attachmentPort, intIpv4Address);
-
-		deviceImpl.removeDevice(device);
-		
-		verify(mockOpe);
-	}
-
-	/**
-	 * Description:
-	 * 	Test method for getDeviceByMac
-	 * Condition:
-	 * 	1. Unregistered MAC address argument is set
-	 * Expect:
-	 * 	1.Nothing happen when you put unregistered MAC address
-	 *  2.Get the proper IDeviceObject.
-	 *  3.Check the IDeviceObject properties set expectedly.
-	 */
-	@Test
-	public void testGetDeviceByMac() {
-		String mac = "99:99:99:99:99:99";
-		
-		IDeviceObject mockDevice = createMock(IDeviceObject.class);
-		
-		expect(mockOpe.searchDevice(mac)).andReturn(mockDevice);
-		
-		replay(mockOpe);
-		
-		IDeviceObject result = deviceImpl.getDeviceByMac(mac);
-		assertNotNull(result);
-		
-		verify(mockOpe);
-	}
-	
-	/**
-	 * Description:
-	 * 	Test method for getDeviceByIP method.
-	 * Condition:
-	 * 	1. Unregistered IP address argument is set
-	 * Expect:
-	 * 	1. Nothing happen when you put unregistered IP address
-	 * 	2. Get the proper IDeviceObject.
-	 *  3. Check the IDeviceObject properties set expectedly.
-	 */
-	@Test
-	public void testGetDeviceByIP() {
-		int nonExistingIp = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.10.50"));
-		int existingIp = InetAddresses.coerceToInteger(InetAddresses.forString("10.5.12.128"));
-		
-		IDeviceObject mockDevice = createMock(IDeviceObject.class);
-		IIpv4Address mockExistingIp = createMock(IIpv4Address.class);
-		expect(mockExistingIp.getDevice()).andReturn(mockDevice);
-		
-		expect(mockOpe.searchIpv4Address(nonExistingIp)).andReturn(null);
-		expect(mockOpe.searchIpv4Address(existingIp)).andReturn(mockExistingIp);
-		
-		replay(mockExistingIp);
-		replay(mockOpe);
-		
-		IDeviceObject result = deviceImpl.getDeviceByIP(nonExistingIp);
-		assertNull(result);
-		
-		result = deviceImpl.getDeviceByIP(existingIp);
-		assertNotNull(result);
-		
-		verify(mockOpe);
-	}
-
-	/**
-	 * Description:
-	 * 	Test method for testChangeDeviceAttachmentsIDevice
-	 * Condition:
-	 * 	1. The device is not currently attached to any point.
-	 * Expect:
-	 * 	1. Nothing happen when you put nonexistent attachment point.
-	 * 	2. Set the attachment point expectedly;
-	 */
-	@Test
-	public void testChangeDeviceAttachementsWhenUnattached() {
-		String strMacAddress = "99:99:99:99:99:99";
-		long attachmentDpid = HexString.toLong("00:00:00:00:00:00:0a:01");
-		short attachmentPort = 2;
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.100.1"));
-		
-		IDevice device = getMockDevice(strMacAddress, attachmentDpid, attachmentPort, intIpv4Address);
-		
-		IDeviceObject mockDeviceObject = createMock(IDeviceObject.class);
-		IPortObject mockPortObject = getMockPort(attachmentDpid, attachmentPort); 
-		
-		expect(mockOpe.searchDevice(strMacAddress)).andReturn(mockDeviceObject);
-		expect(mockDeviceObject.getAttachedPorts()).andReturn(Collections.<IPortObject>emptyList());
-		expect(mockOpe.searchPort(HexString.toHexString(attachmentDpid), attachmentPort)).andReturn(mockPortObject);
-		mockPortObject.setDevice(mockDeviceObject);
-		mockOpe.commit();
-		
-		replay(mockDeviceObject);
-		replay(mockPortObject);
-		replay(mockOpe);
-		
-		deviceImpl.changeDeviceAttachments(device);
-		
-		verify(mockDeviceObject);
-		verify(mockPortObject);
-		verify(mockOpe);
-	}
-	
-	/**
-	 * Description:
-	 * 	Test method for testChangeDeviceAttachmentsIDevice
-	 * Condition:
-	 * 	1. The device is currently attached to a switch, but this attachment point
-	 *     has now changed.
-	 * Expect:
-	 * 	1. The device should be removed from the old attachment point.
-	 * 	2. Set the attachment point expectedly;
-	 */
-	@Test
-	public void testChangeDeviceAttachementsWhenAttached() {
-		String strMacAddress = "99:99:99:99:99:99";
-		long attachmentDpid = HexString.toLong("00:00:00:00:00:00:0a:01");
-		short attachmentPort = 2;
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.100.1"));
-		
-		//Details for the port the device will be moved from
-		long alreadyAttachedDpid = HexString.toLong("00:00:00:00:00:00:0b:01");
-		short alreadyAttachedPort = 5;
-		
-		IDevice device = getMockDevice(strMacAddress, attachmentDpid, attachmentPort, intIpv4Address);
-		
-		IDeviceObject mockDeviceObject = createMock(IDeviceObject.class);
-		IPortObject mockPortObject = getMockPort(attachmentDpid, attachmentPort);
-		IPortObject alreadyAttachedPortObject = getMockPort(alreadyAttachedDpid, alreadyAttachedPort);
-		
-		expect(mockOpe.searchDevice(strMacAddress)).andReturn(mockDeviceObject);
-		expect(mockDeviceObject.getAttachedPorts()).andReturn(Collections.singletonList(alreadyAttachedPortObject));
-		expect(mockOpe.searchPort(HexString.toHexString(attachmentDpid), attachmentPort)).andReturn(mockPortObject);
-		mockPortObject.setDevice(mockDeviceObject);
-		alreadyAttachedPortObject.removeDevice(mockDeviceObject);
-		mockOpe.commit();
-		
-		replay(mockDeviceObject);
-		replay(alreadyAttachedPortObject);
-		replay(mockPortObject);
-		replay(mockOpe);
-		
-		deviceImpl.changeDeviceAttachments(device);
-		
-		verify(mockDeviceObject);
-		verify(alreadyAttachedPortObject);
-		verify(mockPortObject);
-		verify(mockOpe);
-	}
-
-	@Ignore
-	@Test
-	public void testChangeDeviceAttachmentsIDeviceIDeviceObject() {
-		//It is tested by the testChangeDeviceAttachmentsIDevice
-	}
-
-	/**
-	 * Description:
-	 * 	Test method for testChangeDeviceIPv4Address
-	 * Condition:
-	 * 	N/A
-	 * Expect:
-	 *  1. Set the IP address expectedly.
-	 */
-	@Test
-	public void testChangeDeviceIpv4Address() {
-		String strMacAddress = "99:99:99:99:99:99";
-		long attachmentDpid = HexString.toLong("00:00:00:00:00:00:0a:01");
-		short attachmentPort = 2;
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.100.1"));
-		
-		IDevice device = getMockDevice(strMacAddress, attachmentDpid, attachmentPort, intIpv4Address);
-		
-		IDeviceObject mockDeviceObject = createMock(IDeviceObject.class);
-		IIpv4Address mockIpv4Address = createMock(IIpv4Address.class);
-		
-		expect(mockOpe.searchDevice(strMacAddress)).andReturn(mockDeviceObject);
-		expect(mockDeviceObject.getIpv4Address(intIpv4Address)).andReturn(null);
-		expect(mockOpe.ensureIpv4Address(intIpv4Address)).andReturn(mockIpv4Address);
-		mockDeviceObject.addIpv4Address(mockIpv4Address);
-		expect(mockDeviceObject.getIpv4Addresses()).andReturn(Collections.singletonList(mockIpv4Address));
-		expect(mockIpv4Address.getIpv4Address()).andReturn(intIpv4Address);
-		mockOpe.commit();
-		
-		replay(mockDeviceObject);
-		replay(mockIpv4Address);
-		replay(mockOpe);
-		
-		deviceImpl.changeDeviceIPv4Address(device);
-		
-		verify(mockDeviceObject);
-		verify(mockIpv4Address);
-		verify(mockOpe);
-	}
-	
-	/**
-	 * Description:
-	 * 	Test method for testChangeDeviceIPv4Address
-	 * Condition:
-	 * 	1. The device had an old IP address which has now changed.
-	 * Expect:
-	 *  1. The old IP address should be removed from the device.
-	 *  2. Set the IP address expectedly.
-	 */
-	@Test
-	public void testChangeDeviceIpv4AddressAndRemoveExisting() {
-		String strMacAddress = "99:99:99:99:99:99";
-		long attachmentDpid = HexString.toLong("00:00:00:00:00:00:0a:01");
-		short attachmentPort = 2;
-		int intIpv4Address = InetAddresses.coerceToInteger(InetAddresses.forString("192.168.100.1"));
-		
-		IDevice device = getMockDevice(strMacAddress, attachmentDpid, attachmentPort, intIpv4Address);
-		
-		IDeviceObject mockDeviceObject = createMock(IDeviceObject.class);
-		
-		IIpv4Address mockIpv4Address = createMock(IIpv4Address.class);
-		IIpv4Address mockDeletingIpv4Address = createMock(IIpv4Address.class);
-		List<IIpv4Address> ipv4Vertices = new ArrayList<IIpv4Address>(2);
-		ipv4Vertices.add(mockIpv4Address);
-		ipv4Vertices.add(mockDeletingIpv4Address);
-		
-		expect(mockOpe.searchDevice(strMacAddress)).andReturn(mockDeviceObject);
-		expect(mockDeviceObject.getIpv4Address(intIpv4Address)).andReturn(null);
-		expect(mockOpe.ensureIpv4Address(intIpv4Address)).andReturn(mockIpv4Address);
-		expect(mockIpv4Address.getDevice()).andReturn(null);
-		mockDeviceObject.addIpv4Address(mockIpv4Address);
-		expect(mockDeviceObject.getIpv4Addresses()).andReturn(ipv4Vertices);
-		expect(mockIpv4Address.getIpv4Address()).andReturn(intIpv4Address);
-		expect(mockDeletingIpv4Address.getIpv4Address()).andReturn(1);
-		mockDeviceObject.removeIpv4Address(mockDeletingIpv4Address);
-		mockOpe.commit();
-		
-		replay(mockDeviceObject);
-		replay(mockIpv4Address);
-		replay(mockOpe);
-		
-		deviceImpl.changeDeviceIPv4Address(device);
-		
-		verify(mockDeviceObject);
-		verify(mockIpv4Address);
-		verify(mockOpe);
-	}
-
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTestBB.java b/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTestBB.java
deleted file mode 100644
index c80b52a..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTestBB.java
+++ /dev/null
@@ -1,674 +0,0 @@
-package net.onrc.onos.ofcontroller.devicemanager.internal;
-
-import static org.junit.Assert.*;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Arrays;
-import java.util.List;
-
-import net.floodlightcontroller.core.internal.TestDatabaseManager;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.SwitchPort;
-import net.floodlightcontroller.devicemanager.internal.Device;
-import net.floodlightcontroller.packet.IPv4;
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.IDeviceStorage;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
-import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
-
-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.openflow.util.HexString;
-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;
-
-/*
- * Jono, 11/4/2013
- * These tests are being ignored because they don't work because they
- * rely on test functionality that was written ages ago and hasn't been
- * updated as the database schema has evolved. 
- * These tests work by getting an in-memory Titan database and testing
- * the DeviceStorageImpl on top of that. In this regard they're not really
- * unit tests as they test the entire DB stack (i.e. GraphDBOperation and
- * GraphDBConnection), not just DeviceStorageImpl.
- * I've left them here as we may wish to resurrect this kind of 
- * integration testing of the DB layers in the future.
- */
-@Ignore
-//Add Powermock preparation
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
-public class DeviceStorageImplTestBB {
-	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
-
-	String conf;
-        String dbStore;
-    private GraphDBConnection conn = null;
-    private GraphDBOperation ope = null;
-    private TitanGraph titanGraph = null;
-    IDeviceStorage deviceImpl = null;
-    
-	@Before
-	public void setUp() throws Exception {
-		
-		deviceImpl = new DeviceStorageImpl();
-		conf = "/dummy/path/to/db";
-                dbStore = "dummyStore";
-		
-		// Make mock cassandra DB
-		// Replace TitanFactory.open() to return mock DB
-		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);
-		
-		deviceImpl.init(dbStore, conf);
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		titanGraph.shutdown();
-		TestDatabaseManager.deleteTestDatabase();
-
-		deviceImpl.close();
-		deviceImpl = null;
-	}
-
-	/**
-	 * Desc:
-	 *  Test method for addDevice method.
-	 * Codition:
-	 *  N/A
-	 * Expect:
-	 * 	Get proper IDeviceObject
-	 *  Check the IDeviceObject properties set
-	 */
-	@Test
-	public void testAddDevice() {
-		try 
-		{	   
-			//Make mockDevice
-			IDevice mockDev = EasyMock.createMock(Device.class);
-			// Mac addr for test device.
-			String macAddr = "99:99:99:99:99:99";
-			// IP addr for test device
-			String ip = "192.168.100.1";
-			Integer ipInt = IPv4.toIPv4Address(ip);
-			Integer[] ipaddrs = {ipInt};
-			// Mac addr for attached switch
-			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
-			long switchMacAddrL = HexString.toLong(switchMacAddr);
-			// Port number for attached switch
-			short portNum = 2; 
-			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
-			SwitchPort[] sps = {sp1};
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-
-			EasyMock.replay(mockDev);
-
-			//Add the device
-	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj);
-
-			//Test to take a Device from DB correctly
-			IDeviceObject devObj1 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, devObj1.getMACAddress());
-
-			//Test to take a attached sw  from DB correctly
-			for(ISwitchObject sw1: devObj1.getSwitch())
-			{
-				String swMacFromDB = sw1.getDPID();
-				assertEquals(switchMacAddr, swMacFromDB);
-			}
-
-			//Test to take a IP addr from DB
-			//TodoForGettingIPaddr. There may be bug in the test class.
-			
-			//XXX not updated to new interface
-			//String ipFromDB = devObj1.getIPAddress();
-			String ipFromDB = "foo";
-			
-			String[] ipsFromDB = ipFromDB.replace("[", "").replace("]", "").split(",");
-			List<String> ipsList = Arrays.asList(ipsFromDB);
-			assertTrue(ipsList.contains(ip));
-
-			//Test to take a attached port from DB
-			for(IPortObject port : devObj1.getAttachedPorts())
-			{
-
-				//In this implementing, the object was not set the port. So it must be null.
-				if(port.getNumber() != null)
-				{
-					String portNumFromDB = port.getNumber().toString();
-					assertEquals(String.valueOf(portNum), portNumFromDB);				
-				}
-			}	
-		} catch(Exception e) {
-			fail(e.getMessage());
-		}
-	}
-	
-	/**
-	 * Desc:
-	 * 	Test method for addDevice method.
-	 * Condition:
-	 * 	Already added device is existed.
-	 * Expect:
-	 * 	Get proper IDeviceObject still.
-	 *  Check the IDeviceObject properties set.
-	 */
-	@Test
-	public void testAddDeviceExisting() {
-		try 
-		{	   
-			IDevice mockDev = EasyMock.createMock(Device.class);
-			String macAddr = "99:99:99:99:99:99";
-			String ip = "192.168.100.1";
-			Integer ipInt = IPv4.toIPv4Address(ip);
-			Integer[] ipaddrs = {ipInt};
-			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
-			long switchMacAddrL = HexString.toLong(switchMacAddr);
-			short portNum = 2; 
-			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
-			SwitchPort[] sps = {sp1};
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.replay(mockDev);
-
-			//Add the device
-	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj);
-
-			//Test to take a Device from DB correctly
-			IDeviceObject devObj1 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, devObj1.getMACAddress());
-
-			//Add the same device
-	        IDeviceObject obj2 = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj2);
-
-			IDeviceObject devObj2 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, devObj2.getMACAddress());	
-
-			//Test to take a attached port from DB
-			for(IPortObject port : devObj2.getAttachedPorts())
-			{
-				//In this implementing, the object was not set the port. So it must be null.
-				if(port.getNumber() != null)
-				{
-
-					String portNumFromDB = port.getNumber().toString();
-					assertEquals(String.valueOf(portNum), portNumFromDB);
-
-				}
-			}	
-
-			//XXX not updated to new interface
-			//String ipFromDB = devObj2.getIPAddress();
-			String ipFromDB = "foo";
-			
-			String[] ipsFromDB = ipFromDB.replace("[", "").replace("]", "").split(",");
-			List<String> ipsList = Arrays.asList(ipsFromDB);
-			assertTrue(ipsList.contains(ip));
-
-			//Test to take a attached port from DB
-			for(IPortObject port : devObj2.getAttachedPorts())
-			{
-
-				//In this implementing, the object was not set the port. So it must be null.
-				if(port.getNumber() != null)
-				{
-					String portNumFromDB = port.getNumber().toString();
-					assertEquals(String.valueOf(portNum), portNumFromDB);				
-				}
-			}	
-		} catch(Exception e) {
-			fail(e.getMessage());
-		}
-	}
-	/**
-	 * Desc:
-	 * 	Test method for updateDevice method.
-	 * Condition:
-	 * 	The mac address and attachment point are the same. 
-	 *  All of the other parameter are different.
-	 * Expect:
-	 * 	Changed parameters are set properly.
-	 */
-	//@Ignore
-	@Test
-	public void testUpdateDevice() {
-		try
-		{
-			IDevice mockDev = EasyMock.createMock(Device.class);
-			String macAddr = "99:99:99:99:99:99";
-			String ip = "192.168.100.1";
-			Integer ipInt = IPv4.toIPv4Address(ip);
-			Integer[] ipaddrs = {ipInt};
-			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
-			long switchMacAddrL = HexString.toLong(switchMacAddr);
-			short portNum = 2; 
-			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
-			SwitchPort[] sps = {sp1};
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.replay(mockDev);
-
-			//Dev2 (attached port is the same)
-			IDevice mockDev2 = EasyMock.createMock(Device.class);
-			String macAddr2 = "99:aa:aa:aa:aa:aa";
-			Integer ip2 = IPv4.toIPv4Address("192.168.100.2");
-			Integer[] ipaddrs2 = {ip2};
-
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
-			EasyMock.expect(mockDev2.getIPv4Addresses()).andReturn(ipaddrs2);
-			EasyMock.expect(mockDev2.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
-			EasyMock.replay(mockDev2);
-
-	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj);
-
-			IDeviceObject dev1 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, dev1.getMACAddress());
-
-			//update theDevice
-			deviceImpl.updateDevice(mockDev2);
-			IDeviceObject dev2 = ope.searchDevice(macAddr2);
-			assertEquals(macAddr2, dev2.getMACAddress());
-			IPortObject iport = ope.searchPort(switchMacAddr, portNum);
-
-			//Test to take a attached port from DB
-			for(IDeviceObject dev : iport.getDevices())
-			{
-				String macAddrFromDB = dev.getMACAddress();	
-				if(macAddr2.equals(macAddrFromDB)){
-					//Nothing to do
-				}
-				else{
-					fail("notFoundTheDeviceOnThePort");			
-				}
-			}
-
-		} catch(Exception e) {
-			fail(e.getMessage());
-		}
-	}
-
-	/**
-	 * Desc:
-	 * 	Test method for testRemoveDevice method.
-	 * Condition:
-	 * 	1. Unregistered IDeviceObject argument is put. 
-	 * Expect:
-	 *  1. Nothing happen when unregistered IDeviceObject is put
-	 * 	2. IDeviceObject will be removed.
-	 */
-	//@Ignore
-	@Test
-	public void testRemoveDevice() {
-		try
-		{
-			IDevice mockDev = EasyMock.createMock(Device.class);
-			String macAddr = "99:99:99:99:99:99";
-			String ip = "192.168.100.1";
-			Integer ipInt = IPv4.toIPv4Address(ip);
-			Integer[] ipaddrs = {ipInt};
-			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
-			long switchMacAddrL = HexString.toLong(switchMacAddr);
-			short portNum = 2; 
-			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
-			SwitchPort[] sps = {sp1};
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.replay(mockDev);
-
-	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj);
-
-			IDeviceObject dev1 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, dev1.getMACAddress());
-
-			deviceImpl.removeDevice(mockDev);		
-		    IDeviceObject dev = deviceImpl.getDeviceByMac(macAddr);
-		    assertNull(dev);
-
-		} catch(Exception e) {
-			fail(e.getMessage());
-		}
-	}
-
-	/**
-	 * Desc:
-	 * 	Test method for getDeviceByMac
-	 * Condition:
-	 * 	1. Unregistered mac address argument is set
-	 * Expect:
-	 * 	1.Nothing happen when you put unregistered mac address
-	 *  2.Get the proper IDeviceObject.
-	 *  3.Check the IDeviceObject properties set.
-	 */
-	//@Ignore
-	@Test
-	public void testGetDeviceByMac() {
-		try
-		{
-			IDevice mockDev = EasyMock.createMock(Device.class);
-			String macAddr = "99:99:99:99:99:99";
-			String ip = "192.168.100.1";
-			Integer ipInt = IPv4.toIPv4Address(ip);
-			Integer[] ipaddrs = {ipInt};
-			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
-			long switchMacAddrL = HexString.toLong(switchMacAddr);
-			short portNum = 2; 
-			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
-			SwitchPort[] sps = {sp1};
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.replay(mockDev);
-
-	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj);
-
-			IDeviceObject dev1 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, dev1.getMACAddress());
-
-		    IDeviceObject dev = deviceImpl.getDeviceByMac(macAddr);
-		    assertNotNull(dev);
-			assertEquals(macAddr, dev.getMACAddress());
-
-		} catch(Exception e) {
-			fail(e.getMessage());
-		}
-	}
-
-	/**
-	 * Desc:
-	 * 	Test method for getDeviceByIP method.
-	 * Condition:
-	 * 	1. Unregistered ip address argument is set
-	 * Expect:
-	 * 	1. Nothing happen when you put unregistered mac address
-	 * 	2. Get the proper IDeviceObject.
-	 *  3. Check the IDeviceObject properties set.
-	 */
-	//@Ignore
-	@Test
-	public void testGetDeviceByIP() {
-		try
-		{
-			IDevice mockDev = EasyMock.createMock(Device.class);
-			String macAddr = "99:99:99:99:99:99";
-			String ip = "192.168.100.1";
-			Integer ipInt = IPv4.toIPv4Address(ip);
-			Integer[] ipaddrs = {ipInt};
-			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
-			long switchMacAddrL = HexString.toLong(switchMacAddr);
-			short portNum = 2; 
-			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
-			SwitchPort[] sps = {sp1};
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.replay(mockDev);
-
-	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj);
-
-			IDeviceObject dev1 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, dev1.getMACAddress());
-
-			int ip_int = getPackedIPv4Address(ip);
-			//XXX not updated to new interface
-		    IDeviceObject dev = deviceImpl.getDeviceByIP(ip_int);
-			//IDeviceObject dev = null;
-			
-		    assertNotNull(dev);
-		    
-		    //XXX not updated to new interface
-			//String ipFromDB = dev.getIPAddress();
-		    String ipFromDB = "foo";
-		    
-			String[] ipsFromDB = ipFromDB.replace("[", "").replace("]", "").split(",");
-			List<String> ipsList = Arrays.asList(ipsFromDB);
-			assertTrue(ipsList.contains(ip));
-
-		} catch(Exception e) {
-			fail(e.getMessage());
-		}
-	}
-
-	/**
-	 * Desc:
-	 * 	Test method for testChangeDeviceAttachmentsIDevice
-	 * Condition:
-	 * 	1. Unexisting attachment point argument is set
-	 * Expect:
-	 * 	1. Unexisting attachment point is ignored, so nothing happen.
-	 * 	2. Change the attachment point.
-	 */
-	//@Ignore
-	@Test
-	public void testChangeDeviceAttachmentsIDevice() {
-		try
-		{
-			IDevice mockDev = EasyMock.createMock(Device.class);
-			String macAddr = "99:99:99:99:99:99";
-			String ip = "192.168.100.1";
-			Integer ipInt = IPv4.toIPv4Address(ip);
-			Integer[] ipaddrs = {ipInt};
-			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
-			long switchMacAddrL = HexString.toLong(switchMacAddr);
-			short portNum = 2; 
-			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
-			SwitchPort[] sps = {sp1};
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.replay(mockDev);
-
-			//Dev2
-			IDevice mockDev2 = EasyMock.createMock(Device.class);
-			String switchMacAddr2 = "00:00:00:00:00:00:0a:02";
-			long lSwitchMacAddr2 = HexString.toLong(switchMacAddr2);
-			short portNum2 = 2; 
-			SwitchPort sp2 = new SwitchPort(lSwitchMacAddr2, portNum2);
-			SwitchPort sps2[] = {sp2};
-
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev2.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev2.getAttachmentPoints()).andReturn(sps2);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
-			EasyMock.replay(mockDev2);
-
-	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj);
-
-		    deviceImpl.changeDeviceAttachments(mockDev2);
-
-		    IDeviceObject dev = deviceImpl.getDeviceByMac(macAddr);
-		    assertNotNull(dev);
-
-			for(ISwitchObject sw1: dev.getSwitch())
-			{
-				String swMacFromDB = sw1.getDPID();
-				assertEquals(switchMacAddr2, swMacFromDB);
-			}
-		} catch(Exception e) {
-			fail(e.getMessage());
-		}
-	}
-
-	//@Ignore
-	@Test
-	public void testChangeDeviceAttachmentsIDeviceIDeviceObject() {
-		//It is tested by the testChangeDeviceAttachmentsIDevice
-	}
-
-	/**
-	 * Desc:
-	 * 	Test method for testChangeDeviceIPv4Address
-	 * Condition:
-	 * 	N/A
-	 * Expect:
-	 *  1. Check correctly changed the ipadress
-	 */
-	//@Ignore
-	@Test
-	public void testChangeDeviceIPv4Address() {
-		try
-		{
-			//Dev1
-			IDevice mockDev = EasyMock.createMock(Device.class);
-			String macAddr = "99:99:99:99:99:99";
-			String ip = "192.168.100.1";
-			Integer ipInt = IPv4.toIPv4Address(ip);
-			Integer[] ipaddrs = {ipInt};
-			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
-			long switchMacAddrL = HexString.toLong(switchMacAddr);
-			short portNum = 2; 
-			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
-			SwitchPort[] sps = {sp1};
-
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
-			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
-			EasyMock.replay(mockDev);
-
-	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
-			assertNotNull(obj);
-
-			IDevice mockDev2 = EasyMock.createMock(Device.class);
-			String ip2 = "192.168.100.2";
-			Integer ipInt2 = IPv4.toIPv4Address(ip2);
-			Integer[] ipaddrs2 = {ipInt2};
-			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
-			EasyMock.expect(mockDev2.getIPv4Addresses()).andReturn(ipaddrs2);
-			EasyMock.replay(mockDev2);
-
-			IDeviceObject dev1 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, dev1.getMACAddress());
-			
-			//XXX not updated to new interface
-			//String ipFromDB = dev1.getIPAddress();
-			String ipFromDB = "foo";
-			
-			String[] ipsFromDB = ipFromDB.replace("[", "").replace("]", "").split(",");
-			List<String> ipsList = Arrays.asList(ipsFromDB);
-			assertTrue(ipsList.contains(ip));
-
-	        deviceImpl.changeDeviceIPv4Address(mockDev2);	
-
-			IDeviceObject dev2 = ope.searchDevice(macAddr);
-			assertEquals(macAddr, dev2.getMACAddress());
-			
-			//XXX not updated to new interface
-			//String ipFromDB2 = dev2.getIPAddress();
-			String ipFromDB2 = "foo";
-			
-			String[] ipsFromDB2 = ipFromDB2.replace("[", "").replace("]", "").split(",");
-			List<String> ipsList2 = Arrays.asList(ipsFromDB2);
-			assertTrue(ipsList2.contains(ip2));
-		} 
-		catch(Exception e) {
-			fail(e.getMessage());
-		}
-	}
-
-	int getPackedIPv4Address(String ip) throws UnknownHostException {
-		byte[] bytes = InetAddress.getByName(ip).getAddress();
-
-		int val = 0;
-		  for (int i = 0; i < bytes.length; i++) {
-		    val <<= 8;
-		    val |= bytes[i] & 0xff;
-		  }
-		  return val;
-	}
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java b/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
deleted file mode 100644
index 73577c1..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
+++ /dev/null
@@ -1,808 +0,0 @@
-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.lang.reflect.Method;
-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.datagrid.IDatagridService;
-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.flowmanager.web.FlowWebRoutable;
-import net.onrc.onos.ofcontroller.topology.ITopologyNetService;
-import net.onrc.onos.ofcontroller.topology.TopologyManager;
-import net.onrc.onos.ofcontroller.util.*;
-
-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.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
- */
-@Ignore
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({FlowManager.class, FlowDatabaseOperation.class, GraphDBOperation.class, System.class, Executors.class})
-public class FlowManagerTest {
-	private static FloodlightModuleContext context;
-	private static IFloodlightProviderService floodlightProvider;
-	private static TopologyManager topologyManager;
-	private static IDatagridService datagridService;
-	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);
-		topologyManager = createMock(TopologyManager.class);
-		datagridService = createMock(IDatagridService.class);
-		restApi = createMock(IRestApiService.class);
-		op = createMock(GraphDBOperation.class);
-
-		// setup expectations
-		expect(context.getServiceImpl(IFloodlightProviderService.class)).andReturn(floodlightProvider);
-		expect(context.getServiceImpl(ITopologyNetService.class)).andReturn(topologyManager);
-		expect(context.getServiceImpl(IDatagridService.class)).andReturn(datagridService);
-		expect(context.getServiceImpl(IRestApiService.class)).andReturn(restApi);
-		expectNew(GraphDBOperation.class, new Class<?>[] {String.class}, EasyMock.isA(String.class)).andReturn(op);
-		expectNew(TopologyManager.class, new Class<?>[] {String.class}, EasyMock.isA(String.class)).andReturn(topologyManager);
-	}
-	
-	private IFlowPath createIFlowPathMock(long flowId, String installerID,
-			String flowPathType, String flowPathUserState,
-			long flowPathFlags, 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.getFlowPathType()).andReturn(flowPathType).anyTimes();
-		expect(iFlowPath.getFlowPathUserState()).andReturn(flowPathUserState).anyTimes();
-		expect(iFlowPath.getFlowPathFlags()).andReturn(new Long(flowPathFlags)).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,
-			String flowPathType, String flowPathUserState,
-			final long flowPathFlags,
-			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.setFlowPathType(FlowPathType.valueOf(flowPathType));
-		flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
-		flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
-		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", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 1, 1, 2, 2); 
-		FlowPath flowPath2 = createTestFlowPath(2, "caller id", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 1, 1, 2, 2); 
-		FlowPath flowPath3 = createTestFlowPath(3, "caller id", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 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)}.
-	 * @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);
-		FlowId result = fm.addFlow(flowPath);
-
-		// verify the test
-		verifyAll();
-		assertNotNull(result);
-	}
-
-	/**
-	 * Test method for {@link FlowManager#addFlow(FlowPath)}.
-	 * @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.setFlowPathType(FlowPathType.valueOf("FP_TYPE_SHORTEST_PATH"));
-		flowPath.setFlowPathUserState(FlowPathUserState.valueOf("FP_USER_ADD"));
-		flowPath.setFlowPathFlags(new FlowPathFlags(0));
-		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.setFlowPathType("FP_TYPE_SHORTEST_PATH");
-		createdFlowPath.setFlowPathUserState("FP_USER_ADD");
-		createdFlowPath.setFlowPathFlags(new Long((long)0));
-		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");
-		
-		expectPrivate(fm, addFlowEntry, createdFlowPath, flowEntry1)
-			.andReturn(createdFlowEntry1);
-		expectPrivate(fm, addFlowEntry, createdFlowPath, flowEntry2)
-			.andReturn(createdFlowEntry2);
-		
-		op.commit();
-		
-		// start the test
-		replayAll();
-		
-		fm.init(context);
-		FlowId result = fm.addFlow(flowPath);
-
-		// verify the test
-		verifyAll();
-		assertNotNull(result);
-	}
-
-	/**
-	 * Test method for {@link FlowManager#deleteFlow(FlowId)}.
-	 * @throws Exception
-	 */
-	@Test
-	public final void testDeleteFlowSuccessNormally() throws Exception {
-		// create mock objects
-		IFlowPath flowPath = createIFlowPathMock(123, "id", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 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.deleteFlow(flowId);
-
-		// verify the test
-		verifyAll();
-	}
-	
-	/**
-	 * 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#deleteAllFlows()}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testDeleteAllFlowsSuccessNormally() 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, "deleteFlow");
-		
-		// 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.deleteFlow(cmpEq(new FlowId(1)))).andReturn(true);
-		expect(fm.deleteFlow(cmpEq(new FlowId(3)))).andReturn(true);
-		
-		// start the test
-		replayAll();
-
-		fm.init(context);
-		Boolean result = fm.deleteAllFlows();
-		
-		// 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", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 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);
-		FlowPath flowPath = fm.getFlow(new FlowId(1));
-		String installerId = flowPath.installerId().toString();
-		String flowPathType = flowPath.flowPathType().toString();
-		String flowPathUserState = flowPath.flowPathUserState().toString();
-		long flowPathFlags = flowPath.flowPathFlags().flags();
-		
-		//verify the test
-		verifyAll();
-		assertEquals("caller id", installerId);
-		assertEquals("FP_TYPE_SHORTEST_PATH", flowPathType);
-		assertEquals("FP_USER_ADD", flowPathUserState);
-		assertEquals(0L, flowPathFlags);
-	}
-	
-	/**
-	 * Test method for {@link FlowManager#getAllFlowsSummary(FlowId, int)}.
-	 * @throws Exception 
-	 */
-	@Test
-	public final void testGetAllFlowsSummarySuccessNormally() throws Exception {
-		final String getAllFlowsWithDataPathSummary = "getAllFlowsWithDataPathSummary";
-		// create mock objects
-		FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, getAllFlowsWithDataPathSummary);
-		FlowPath flowPath1 = createTestFlowPath(1, "", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 1, 2, 3, 4);
-		FlowPath flowPath2 = createTestFlowPath(5, "", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 2, 3, 4, 5);
-		FlowPath flowPath3 = createTestFlowPath(10, "", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 3, 4, 5, 6);
-
-		// instantiate required objects
-		ArrayList<FlowPath> flows = new ArrayList<FlowPath>();
-		flows.add(flowPath3);
-		flows.add(flowPath1);
-		flows.add(flowPath2);
-		
-		// setup expectations
-		expectInitWithContext();
-		expectPrivate(fm, getAllFlowsWithDataPathSummary).andReturn(flows);
-
-		// start the test
-		replayAll();
-		
-		fm.init(context);
-		ArrayList<FlowPath> returnedFlows = fm.getAllFlowsSummary(null, 0);
-		
-		// verify the test
-		verifyAll();
-		assertEquals(3, returnedFlows.size());
-		assertEquals(1, new FlowId(returnedFlows.get(0).flowId().value()).value());
-		assertEquals(5, new FlowId(returnedFlows.get(1).flowId().value()).value());
-		assertEquals(10, new FlowId(returnedFlows.get(2).flowId().value()).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", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 1, 1, 2, 2); 
-		IFlowPath iFlowPath2 = createIFlowPathMock(2, "caller id", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 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
-	}
-		
-	// 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_store", "/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(4, md.size());
-		assertTrue(md.contains(IFloodlightProviderService.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#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", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 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 FlowEntryActions());
-		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 FlowEntryActions());
-		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(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);
-		// Use reflection to test the private method
-		// Boolean result = fm.reconcileFlow(iFlowPath1, dataPath);
-		Class<?> fmClass = FlowManager.class;
-		Method method = fmClass.getDeclaredMethod(
-			"reconcileFlow",
-			new Class[] { IFlowPath.class, DataPath.class });
-		method.setAccessible(true);
-		Boolean result = (Boolean)method.invoke(fm,
-			new Object[] { 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", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 1, 2, 3, 4); 
-		IFlowEntry iFlowEntry = createMock(IFlowEntry.class);
-		BasicFactory basicFactory = createMock(BasicFactory.class);
-		
-		// instantiate required objects
-		FlowManager fm = new FlowManager();
-		
-		FlowEntryAction action = new FlowEntryAction();
-		action.setActionOutput(new Port((short)2));
-		FlowEntryActions actions = new FlowEntryActions();
-		actions.addAction(action);
-
-		// 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.getMatchSrcMac()).andReturn("01:23:45:67:89:01");
-		expect(iFlowEntry.getMatchDstMac()).andReturn("01:23:45:67:89:02");
-		expect(iFlowEntry.getMatchEthernetFrameType()).andReturn(new Short((short)0x0800));
-		expect(iFlowEntry.getMatchVlanId()).andReturn(new Short((short)0x1234));
-		expect(iFlowEntry.getMatchVlanPriority()).andReturn(new Byte((byte)0x10));
-		expect(iFlowEntry.getMatchSrcIPv4Net()).andReturn("192.168.0.1");
-		expect(iFlowEntry.getMatchDstIPv4Net()).andReturn("192.168.0.2");
-		expect(iFlowEntry.getMatchIpProto()).andReturn(new Byte((byte)0x20));
-		expect(iFlowEntry.getMatchIpToS()).andReturn(new Byte((byte)0x3));
-		expect(iFlowEntry.getMatchSrcTcpUdpPort()).andReturn(new Short((short)40000));
-		expect(iFlowEntry.getMatchDstTcpUdpPort()).andReturn(new Short((short)80));
-		expect(iFlowEntry.getActions()).andReturn(actions.toString());
-		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);
-		// Use reflection to test the private method
-		// Boolean result = fm.installFlowEntry(iofSwitch, iFlowPath, iFlowEntry);
-		Class<?> fmClass = FlowManager.class;
-		Method method = fmClass.getDeclaredMethod(
-			"installFlowEntry",
-			new Class[] { IOFSwitch.class, IFlowPath.class, IFlowEntry.class });
-		method.setAccessible(true);
-		Boolean result = (Boolean)method.invoke(fm,
-			new Object[] { 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");
-	}
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizerTest.java b/src/test/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizerTest.java
deleted file mode 100644
index 68b4f1f..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizerTest.java
+++ /dev/null
@@ -1,313 +0,0 @@
-package net.onrc.onos.ofcontroller.flowprogrammer;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-
-import net.floodlightcontroller.core.IOFSwitch;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.flowmanager.FlowDatabaseOperation;
-import net.onrc.onos.ofcontroller.flowprogrammer.IFlowSyncService.SyncResult;
-import net.onrc.onos.ofcontroller.util.FlowEntry;
-import net.onrc.onos.ofcontroller.util.FlowEntryId;
-
-import org.easymock.EasyMock;
-import org.easymock.IAnswer;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFStatisticsRequest;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.statistics.OFFlowStatisticsReply;
-import org.openflow.protocol.statistics.OFStatistics;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({FlowSynchronizer.class, GraphDBOperation.class, FlowDatabaseOperation.class})
-public class FlowSynchronizerTest {
-	private FlowPusher pusher;
-	private FlowSynchronizer sync;
-	private List<Long> idAdded;
-	private List<Long> idRemoved;
-
-	@Before
-	public void setUp() throws Exception {
-		idAdded = new ArrayList<Long>();
-		idRemoved = new ArrayList<Long>();
-		
-		pusher = EasyMock.createMock(FlowPusher.class);
-		pusher.add(EasyMock.anyObject(IOFSwitch.class), EasyMock.anyObject(OFMessage.class));
-		EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
-				@Override
-				public Object answer() throws Throwable {
-					OFMessage msg = (OFMessage)EasyMock.getCurrentArguments()[1];
-					if (msg.getType().equals(OFType.FLOW_MOD)) {
-						OFFlowMod fm = (OFFlowMod)msg;
-						if (fm.getCommand() == OFFlowMod.OFPFC_DELETE_STRICT) {
-							idRemoved.add(fm.getCookie());
-						}
-					}
-					return null;
-				}
-			}).anyTimes();
-		pusher.pushFlowEntry(EasyMock.anyObject(IOFSwitch.class), EasyMock.anyObject(FlowEntry.class));
-		EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
-			@Override
-			public Object answer() throws Throwable {
-				FlowEntry flow = (FlowEntry)EasyMock.getCurrentArguments()[1];
-				idAdded.add(flow.flowEntryId().value());
-				return null;
-			}
-		}).anyTimes();
-		EasyMock.replay(pusher);
-	}
-
-	@After
-	public void tearDown() throws Exception {
-	}
-
-	/**
-	 * Test that synchronization doesn't affect anything in case either DB and
-	 * flow table has the same entries.
-	 */
-	@Test
-	public void testStable() {
-		// Create mock of flow table : flow 1
-		IOFSwitch sw = createMockSwitch(new long[] {1});
-		
-		// Create mock of flow entries : flow 1
-		initMockGraph(new long[] {1});
-		
-		// synchronize
-		doSynchronization(sw);
-		
-		// check if flow is not changed
-		assertEquals(0, idAdded.size());
-		assertEquals(0, idRemoved.size());
-	}
-
-	/**
-	 * Test that an flow is added in case DB has an extra FlowEntry.
-	 */
-	@Test
-	public void testSingleAdd() {
-		// Create mock of flow table : null
-		IOFSwitch sw = createMockSwitch(new long[] {});
-		
-		// Create mock of flow entries : flow 1
-		initMockGraph(new long[] {1});
-		
-		// synchronize
-		doSynchronization(sw);
-		
-		// check if single flow is installed
-		assertEquals(1, idAdded.size());
-		assertTrue(idAdded.contains((long)1));
-		assertEquals(0, idRemoved.size());
-	}
-
-	/**
-	 * Test that an flow is deleted in case switch has an extra FlowEntry.
-	 */
-	@Test
-	public void testSingleDelete() {
-		// Create mock of flow table : flow 1
-		IOFSwitch sw = createMockSwitch(new long[] {1});
-		
-		// Create mock of flow entries : null
-		initMockGraph(new long[] {});
-		
-		// synchronize
-		doSynchronization(sw);
-		
-		// check if single flow is deleted
-		assertEquals(0, idAdded.size());
-		assertEquals(1, idRemoved.size());
-		assertTrue(idRemoved.contains((long)1));
-	}
-	
-	/**
-	 * Test that appropriate flows are added and other appropriate flows are deleted
-	 * in case flows in DB are overlapping flows in switch.
-	 */
-	@Test
-	public void testMixed() {
-		// Create mock of flow table : flow 1,2,3
-		IOFSwitch sw = createMockSwitch(new long[] {1,2,3});
-		
-		// Create mock of flow entries : flow 2,3,4,5
-		initMockGraph(new long[] {2,3,4,5});
-		
-		// synchronize
-		doSynchronization(sw);
-		
-		// check if two flows {4,5} is installed and one flow {1} is deleted
-		assertEquals(2, idAdded.size());
-		assertTrue(idAdded.contains((long)4));
-		assertTrue(idAdded.contains((long)5));
-		assertEquals(1, idRemoved.size());
-		assertTrue(idRemoved.contains((long)1));
-	}
-	
-
-	@Test
-	public void testMassive() {
-		// Create mock of flow table : flow 0-1999
-		long [] swIdList = new long [2000];
-		for (long i = 0; i < 2000; ++i) {
-			swIdList[(int)i] = i;
-		}
-		IOFSwitch sw = createMockSwitch(swIdList);
-		
-		// Create mock of flow entries : flow 1500-3499
-		long [] dbIdList = new long [2000];
-		for (long i = 0; i < 2000; ++i) {
-			dbIdList[(int)i] = 1500 + i;
-		}
-		initMockGraph(dbIdList);
-
-		// synchronize
-		doSynchronization(sw);
-		
-		// check if 1500 flows {2000-3499} is installed and 1500 flows {0,...,1499} is deleted
-		assertEquals(1500, idAdded.size());
-		for (long i = 2000; i < 3500; ++i) {
-			assertTrue(idAdded.contains(i));
-		}
-		assertEquals(1500, idRemoved.size());
-		for (long i = 0; i < 1500; ++i) {
-			assertTrue(idRemoved.contains(i));
-		}
-	}
-
-	/**
-	 * Create mock IOFSwitch with flow table which has arbitrary flows.
-	 * @param cookieList List of FlowEntry IDs switch has.
-	 * @return Mock object.
-	 */
-	private IOFSwitch createMockSwitch(long[] cookieList) {
-		IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
-		EasyMock.expect(sw.getId()).andReturn((long)1).anyTimes();
-		
-		List<OFStatistics> stats = new ArrayList<OFStatistics>();
-		for (long cookie : cookieList) {
-			stats.add(createReply(cookie));
-		}
-		
-		@SuppressWarnings("unchecked")
-		Future<List<OFStatistics>> future = EasyMock.createMock(Future.class);
-		try {
-			EasyMock.expect(future.get()).andReturn(stats).once();
-		} catch (InterruptedException e1) {
-			fail("Failed in Future#get()");
-		} catch (ExecutionException e1) {
-			fail("Failed in Future#get()");
-		}
-		EasyMock.replay(future);
-		
-		try {
-			EasyMock.expect(sw.getStatistics(EasyMock.anyObject(OFStatisticsRequest.class)))
-				.andReturn(future).once();
-		} catch (IOException e) {
-			fail("Failed in IOFSwitch#getStatistics()");
-		}
-		
-		EasyMock.replay(sw);
-		return sw;
-	}
-	
-	/**
-	 * Create single OFFlowStatisticsReply object which is actually obtained from switch.
-	 * @param cookie Cookie value, which indicates ID of FlowEntry installed to switch.
-	 * @return Created object.
-	 */
-	private OFFlowStatisticsReply createReply(long cookie) {
-		OFFlowStatisticsReply stat = new OFFlowStatisticsReply();
-		OFMatch match = new OFMatch();
-		
-		stat.setCookie(cookie);
-		stat.setMatch(match);
-		stat.setPriority((short)1);
-
-		return stat;
-	}
-	
-	/**
-	 * Create mock GraphDBOperation and FlowDatabaseOperation to mock DB.
-	 * @param idList List of FlowEntry IDs stored in DB.
-	 */
-	private void initMockGraph(long[] idList) {
-		List<IFlowEntry> flowEntryList = new ArrayList<IFlowEntry>();
-		
-		for (long id : idList) {
-			IFlowEntry entry = EasyMock.createMock(IFlowEntry.class);
-			EasyMock.expect(entry.getFlowEntryId()).andReturn(String.valueOf(id)).anyTimes();
-			EasyMock.replay(entry);
-			flowEntryList.add(entry);
-		}
-		
-		ISwitchObject swObj = EasyMock.createMock(ISwitchObject.class);
-		EasyMock.expect(swObj.getFlowEntries()).andReturn(flowEntryList).once();
-		EasyMock.replay(swObj);
-		
-		GraphDBOperation mockOp = PowerMock.createMock(GraphDBOperation.class);
-		EasyMock.expect(mockOp.searchSwitch(EasyMock.anyObject(String.class))).andReturn(swObj).once();
-		
-		PowerMock.mockStatic(FlowDatabaseOperation.class);
-		for (IFlowEntry entry : flowEntryList) {
-			EasyMock.expect(FlowDatabaseOperation.extractFlowEntry(EasyMock.eq(entry)))
-				.andAnswer(new IAnswer<FlowEntry>() {
-					@Override
-					public FlowEntry answer() throws Throwable {
-						IFlowEntry iflow = (IFlowEntry)EasyMock.getCurrentArguments()[0];
-						long flowEntryId = Long.valueOf(iflow.getFlowEntryId());
-						
-						FlowEntry flow = EasyMock.createMock(FlowEntry.class);
-						EasyMock.expect(flow.flowEntryId()).andReturn(new FlowEntryId(flowEntryId)).anyTimes();
-						EasyMock.replay(flow);
-						return flow;
-					}
-					
-				}).anyTimes();
-			EasyMock.expect(mockOp.searchFlowEntry(EasyMock.eq(new FlowEntryId(entry.getFlowEntryId()))))
-				.andReturn(entry);
-		}
-		PowerMock.replay(FlowDatabaseOperation.class);
-		EasyMock.replay(mockOp);
-		
-		try {
-			PowerMock.expectNew(GraphDBOperation.class, "").andReturn(mockOp);
-		} catch (Exception e) {
-			fail("Failed to create GraphDBOperation");
-		}
-		PowerMock.replay(GraphDBOperation.class);
-	}
-	
-	/**
-	 * Instantiate FlowSynchronizer and sync flows.
-	 * @param sw Target IOFSwitch object
-	 */
-	private void doSynchronization(IOFSwitch sw) {
-		sync = new FlowSynchronizer();
-		sync.init(pusher);
-		Future<SyncResult> future = sync.synchronize(sw);
-		try {
-			future.get();
-		} catch (Exception e) {
-			fail("Failed to Future#get()");
-		}
-	}
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java b/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java
deleted file mode 100644
index 8d4ccc0..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java
+++ /dev/null
@@ -1,246 +0,0 @@
-package net.onrc.onos.ofcontroller.topology;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-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.powermock.modules.junit4.PowerMockRunner;
-
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.thinkaurelius.titan.core.TitanFactory;
-import net.onrc.onos.graph.DBConnection;
-import net.onrc.onos.graph.DBOperation;
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBManager;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
-import net.onrc.onos.ofcontroller.topology.TopologyManager;
-import net.onrc.onos.ofcontroller.util.DataPath;
-import net.onrc.onos.ofcontroller.util.Dpid;
-import net.onrc.onos.ofcontroller.util.FlowPathFlags;
-import net.onrc.onos.ofcontroller.util.Port;
-import net.onrc.onos.ofcontroller.util.SwitchPort;
-
-/**
- * A class for testing the TopologyManager class.
- * @see net.onrc.onos.ofcontroller.topology.TopologyManager
- */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, TopologyManager.class})
-public class TopologyManagerTest {
-    String conf;
-    String dbStore;
-    private DBConnection conn = null;
-    private DBOperation oper = null;
-    private TitanGraph titanGraph = null;
-    private TopologyManager topologyManager = null;
-
-    /**
-     * Setup the tests.
-     */
-    @Before
-    public void setUp() throws Exception {
-        dbStore = "dummyStore";
-	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);
-
-        oper = GraphDBManager.getDBOperation(dbStore, conf);
-	// Create the connection to the database
-	conn = GraphDBManager.getConnection(dbStore, conf);
-
-	// Populate the database
-	TestDatabaseManager.populateTestData(titanGraph);
-
-	// Prepare the TopologyManager instance
-	topologyManager = new TopologyManager(oper);
-    }
-
-    /**
-     * Cleanup after the tests.
-     */
-    @After
-    public void tearDown() throws Exception {
-	titanGraph.shutdown();
-	TestDatabaseManager.deleteTestDatabase();
-    }
-
-    /**
-     * Test method TopologyManager.getTopologyShortestPath()
-     *
-     * @see net.onrc.onos.ofcontroller.topology.TopologyManager#getTopologyShortestPath
-     */
-    @Test
-    public void test_getTopologyShortestPath() {
-	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
-	//
-	Topology topology = topologyManager.newDatabaseTopology();
-	dataPath = topologyManager.getTopologyShortestPath(topology,
-							   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 if we apply various Flow Path Flags
-	String expectedResult2 = "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;";
-	String expectedResult3 = "1/00:00:00:00:00:00:0a:03/2;";
-	FlowPathFlags flowPathFlags2 = new FlowPathFlags("DISCARD_FIRST_HOP_ENTRY");
-	FlowPathFlags flowPathFlags3 = new FlowPathFlags("KEEP_ONLY_FIRST_HOP_ENTRY");
-	//
-	dataPath.applyFlowPathFlags(flowPathFlags2);
-	dataPathSummaryStr = dataPath.dataPathSummary();
-	assertEquals(dataPathSummaryStr, expectedResult2);
-	//
-	dataPath.applyFlowPathFlags(flowPathFlags3);
-	dataPathSummaryStr = dataPath.dataPathSummary();
-	assertEquals(dataPathSummaryStr, expectedResult3);
-
-	//
-	// 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 = topologyManager.getTopologyShortestPath(topology,
-							   srcSwitchPort,
-							   noSuchDstSwitchPort);
-	assertTrue(dataPath == null);
-
-	topologyManager.dropTopology(topology);
-    }
-
-    /**
-     * Test method TopologyManager.getDatabaseShortestPath()
-     *
-     * @see net.onrc.onos.ofcontroller.routing.TopologyManager#getDatabaseShortestPath
-     */
-    @Test
-    public void test_getDatabaseShortestPath() {
-	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 = topologyManager.getDatabaseShortestPath(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 if we apply various Flow Path Flags
-	String expectedResult2 = "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;";
-	String expectedResult3 = "1/00:00:00:00:00:00:0a:03/2;";
-	FlowPathFlags flowPathFlags2 = new FlowPathFlags("DISCARD_FIRST_HOP_ENTRY");
-	FlowPathFlags flowPathFlags3 = new FlowPathFlags("KEEP_ONLY_FIRST_HOP_ENTRY");
-	//
-	dataPath.applyFlowPathFlags(flowPathFlags2);
-	dataPathSummaryStr = dataPath.dataPathSummary();
-	assertEquals(dataPathSummaryStr, expectedResult2);
-	//
-	dataPath.applyFlowPathFlags(flowPathFlags3);
-	dataPathSummaryStr = dataPath.dataPathSummary();
-	assertEquals(dataPathSummaryStr, expectedResult3);
-
-	//
-	// 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 = topologyManager.getDatabaseShortestPath(srcSwitchPort,
-							   noSuchDstSwitchPort);
-	assertTrue(dataPath == null);
-    }
-
-    /**
-     * Test method TopologyManager.routeExists()
-     *
-     * @see net.onrc.onos.ofcontroller.routing.TopologyManager#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 = topologyManager.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 = topologyManager.routeExists(srcSwitchPort,
-					     noSuchDstSwitchPort);
-	assertTrue(result != true);
-    }
-}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/util/FlowPathTest.java b/src/test/java/net/onrc/onos/ofcontroller/util/FlowPathTest.java
deleted file mode 100644
index 76ccf9f..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/util/FlowPathTest.java
+++ /dev/null
@@ -1,231 +0,0 @@
-package net.onrc.onos.ofcontroller.util;
-
-import static org.junit.Assert.*;
-import net.onrc.onos.ofcontroller.core.internal.TestableGraphDBOperation.TestFlowEntry;
-import net.onrc.onos.ofcontroller.core.internal.TestableGraphDBOperation.TestFlowPath;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class FlowPathTest {
-
-	FlowPath flowPath;
-	
-	@Before
-	public void setUp() throws Exception{
-		TestFlowPath iFlowPath = new TestFlowPath();
-		iFlowPath.setFlowIdForTest("0x1234");
-		iFlowPath.setInstallerIdForTest("installerId");
-		iFlowPath.setFlowPathTypeForTest("FP_TYPE_SHORTEST_PATH");
-		iFlowPath.setFlowPathUserStateForTest("FP_USER_ADD");
-		iFlowPath.setFlowPathFlagsForTest(0L);
-		iFlowPath.setIdleTimeoutForTest(5);
-		iFlowPath.setHardTimeoutForTest(10);
-		iFlowPath.setSrcSwForTest("CA:FE");
-		iFlowPath.setSrcPortForTest((short)1);
-		iFlowPath.setDstSwForTest("BA:BE");
-		iFlowPath.setDstPortForTest((short)2);
-		
-		iFlowPath.setActionsForTest("[[type=ACTION_OUTPUT action=[port=10 maxLen=11]];[type=ACTION_OUTPUT action=[port=12 maxLen=13]];]");
-		
-		TestFlowEntry iFlowEntry = new TestFlowEntry();
-		iFlowEntry.setEntryIdForTest("0x14");
-		iFlowEntry.setDpidForTest("BE:EF");
-		iFlowEntry.setActionsForTest("[[type=ACTION_OUTPUT action=[port=23 maxLen=24]];[type=ACTION_OUTPUT action=[port=25 maxLen=26]];]");
-		iFlowEntry.setUserStateForTest("FE_USER_MODIFY");
-		iFlowEntry.setSwitchStateForTest("FE_SWITCH_UPDATE_IN_PROGRESS");
-		iFlowPath.addFlowEntryForTest(iFlowEntry);
-		
-		flowPath = new FlowPath(iFlowPath);
-	}
-
-	@Test
-	public void testFlowPath(){
-		FlowPath flowPath = new FlowPath();
-		assertTrue ( flowPath.flowPathType() == FlowPathType.FP_TYPE_UNKNOWN);
-		assertTrue ( flowPath.flowPathUserState() == FlowPathUserState.FP_USER_UNKNOWN);
-		assertFalse( flowPath.flowPathFlags().isDiscardFirstHopEntry() );
-		assertFalse( flowPath.flowPathFlags().isKeepOnlyFirstHopEntry() );
-		assertTrue (flowPath.idleTimeout() == 0);
-		assertTrue (flowPath.hardTimeout() == 0);
-		assertTrue( flowPath.flowEntryActions().isEmpty() );
-	}
-
-	@Test
-	public void testFlowPathIFlowPath(){
-		TestFlowPath iFlowPath = new TestFlowPath();
-		iFlowPath.setFlowIdForTest("0x1234");
-		iFlowPath.setInstallerIdForTest("installerId");
-		iFlowPath.setFlowPathTypeForTest("FP_TYPE_SHORTEST_PATH");
-		iFlowPath.setFlowPathUserStateForTest("FP_USER_ADD");
-		iFlowPath.setFlowPathFlagsForTest(0L);
-		iFlowPath.setIdleTimeoutForTest(5);
-		iFlowPath.setHardTimeoutForTest(10);
-		iFlowPath.setSrcSwForTest("CA:FE");
-		iFlowPath.setSrcPortForTest((short)1);
-		iFlowPath.setDstSwForTest("BA:BE");
-		iFlowPath.setDstPortForTest((short)2);
-		
-		iFlowPath.setMatchSrcMacForTest("01:02:03:04:05:06");
-		iFlowPath.setMatchDstMacForTest("06:05:04:03:02:01");
-		iFlowPath.setMatchEthernetFrameTypeForTest((short)3);
-		iFlowPath.setMatchVlanIdForTest((short)4);
-		iFlowPath.setMatchVlanPriorityForTest((byte)5);
-		iFlowPath.setMatchSrcIpaddrForTest("127.0.0.1/32");
-		iFlowPath.setMatchDstIpaddrForTest("127.0.0.2/32");
-		iFlowPath.setMatchIpProtoForTest((byte)6);
-		iFlowPath.setMatchIpToSForTest((byte)7);
-		iFlowPath.setMatchSrcTcpUdpPortForTest((short)8);
-		iFlowPath.setMatchDstTcpUdpPortForTest((short)9);
-		
-		iFlowPath.setActionsForTest("[[type=ACTION_OUTPUT action=[port=10 maxLen=11]];[type=ACTION_OUTPUT action=[port=12 maxLen=13]];]");
-		
-		TestFlowEntry iFlowEntry = new TestFlowEntry();
-		iFlowEntry.setEntryIdForTest("0x14");
-		iFlowEntry.setDpidForTest("BE:EF");
-		iFlowEntry.setMatchInPortForTest((short)15);
-		iFlowEntry.setMatchSrcMacForTest("11:22:33:44:55:66");
-		iFlowEntry.setMatchDstMacForTest("66:55:44:33:22:11");
-		iFlowEntry.setMatchEtherFrameTypeForTest((short)16);
-		iFlowEntry.setMatchVlanIdForTest((short)17);
-		iFlowEntry.setMatchVlanPriorityForTest((byte)18);
-		iFlowEntry.setMatchSrcIpaddrForTest("127.0.0.3/32");
-		iFlowEntry.setMatchDstIpaddrForTest("127.0.0.4/32");
-		iFlowEntry.setMatchIpProtoForTest((byte)19);
-		iFlowEntry.setMatchIpToSForTest((byte)20);
-		iFlowEntry.setMatchSrcTcpUdpPortForTest((short)21);
-		iFlowEntry.setMatchDstTcpUdpPortForTest((short)22);
-		iFlowEntry.setActionsForTest("[[type=ACTION_OUTPUT action=[port=23 maxLen=24]];[type=ACTION_OUTPUT action=[port=25 maxLen=26]];]");
-		iFlowEntry.setUserStateForTest("FE_USER_MODIFY");
-		iFlowEntry.setSwitchStateForTest("FE_SWITCH_UPDATE_IN_PROGRESS");
-		iFlowPath.addFlowEntryForTest(iFlowEntry);
-		
-		FlowPath flowPath = new FlowPath(iFlowPath);
-		assertEquals(flowPath.flowId().value(), 0x1234);
-		assertEquals(flowPath.installerId().value(), "installerId");
-		assertEquals(flowPath.flowPathType(), FlowPathType.FP_TYPE_SHORTEST_PATH);
-		assertEquals(flowPath.flowPathUserState(), FlowPathUserState.FP_USER_ADD);
-		assertEquals(flowPath.flowPathFlags().flags(), 0);
-		assertEquals(flowPath.idleTimeout(), 5);
-		assertEquals(flowPath.hardTimeout(), 10);
-		assertEquals(flowPath.dataPath().srcPort().dpid().value(), 0xCAFE);
-		assertEquals(flowPath.dataPath().srcPort().port().value(), 1);
-		assertEquals(flowPath.dataPath().dstPort().dpid().value(), 0xBABE);
-		assertEquals(flowPath.dataPath().dstPort().port().value(), 2);
-		
-		assertEquals(flowPath.flowEntryMatch().srcMac().toString(), "01:02:03:04:05:06");
-		assertEquals(flowPath.flowEntryMatch().dstMac().toString(), "06:05:04:03:02:01");
-		assertEquals(flowPath.flowEntryMatch().ethernetFrameType().shortValue(), 3);
-		assertEquals(flowPath.flowEntryMatch().vlanId().shortValue(), 4);
-		assertEquals(flowPath.flowEntryMatch().vlanPriority().shortValue(), 5);
-		assertEquals(flowPath.flowEntryMatch().srcIPv4Net().address().toString(), "127.0.0.1");
-		assertEquals(flowPath.flowEntryMatch().srcIPv4Net().prefixLen() , 32);
-		assertEquals(flowPath.flowEntryMatch().dstIPv4Net().address().toString(), "127.0.0.2");
-		assertEquals(flowPath.flowEntryMatch().dstIPv4Net().prefixLen() , 32);
-		assertEquals(flowPath.flowEntryMatch().ipProto().byteValue(), 6);
-		assertEquals(flowPath.flowEntryMatch().ipToS().byteValue(), 7);
-		assertEquals(flowPath.flowEntryMatch().srcTcpUdpPort().shortValue(), 8);
-		assertEquals(flowPath.flowEntryMatch().dstTcpUdpPort().shortValue(), 9);
-		
-		assertEquals(flowPath.flowEntryActions().toString(),"[[type=ACTION_OUTPUT action=[port=10 maxLen=11]];[type=ACTION_OUTPUT action=[port=12 maxLen=13]];]");
-		
-		assertEquals(0x14, flowPath.dataPath().flowEntries().get(0).flowEntryId().value() );
-		assertEquals(0xBEEF, flowPath.dataPath().flowEntries().get(0).dpid().value() );
-		assertEquals(0, flowPath.dataPath().flowEntries().get(0).idleTimeout() );
-		assertEquals(0, flowPath.dataPath().flowEntries().get(0).hardTimeout() );
-		assertEquals(15, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().inPort().value() );
-		assertEquals("11:22:33:44:55:66", flowPath.dataPath().flowEntries().get(0).flowEntryMatch().srcMac().toString());
-		assertEquals("66:55:44:33:22:11", flowPath.dataPath().flowEntries().get(0).flowEntryMatch().dstMac().toString());
-		assertEquals(16, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().ethernetFrameType().shortValue());
-		assertEquals(17, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().vlanId().shortValue());
-		assertEquals(18, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().vlanPriority().byteValue());
-		assertEquals("127.0.0.3", flowPath.dataPath().flowEntries().get(0).flowEntryMatch().srcIPv4Net().address().toString());
-		assertEquals(32, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().srcIPv4Net().prefixLen());
-		assertEquals("127.0.0.4", flowPath.dataPath().flowEntries().get(0).flowEntryMatch().dstIPv4Net().address().toString());
-		assertEquals(32, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().dstIPv4Net().prefixLen());
-		assertEquals(19, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().ipProto().byteValue());
-		assertEquals(20, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().ipToS().byteValue());
-		assertEquals(21, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().srcTcpUdpPort().shortValue());
-		assertEquals(22, flowPath.dataPath().flowEntries().get(0).flowEntryMatch().dstTcpUdpPort().shortValue());
-		assertEquals("[[type=ACTION_OUTPUT action=[port=23 maxLen=24]];[type=ACTION_OUTPUT action=[port=25 maxLen=26]];]", flowPath.dataPath().flowEntries().get(0).flowEntryActions().toString());
-		assertEquals("FE_USER_MODIFY", flowPath.dataPath().flowEntries().get(0).flowEntryUserState().toString());
-		assertEquals("FE_SWITCH_UPDATE_IN_PROGRESS", flowPath.dataPath().flowEntries().get(0).flowEntrySwitchState().toString());
-	}
-
-	@Test
-	public void testSetFlowPathType(){
-		FlowPath flowPath = new FlowPath();
-		FlowPathType type = FlowPathType.FP_TYPE_SHORTEST_PATH;
-		flowPath.setFlowPathType( type );
-		assertTrue( flowPath.flowPathType() == FlowPathType.FP_TYPE_SHORTEST_PATH );
-	}
-
-	@Test
-	public void testSetFlowPathUserState(){
-		FlowPath flowPath = new FlowPath();
-		FlowPathUserState state = FlowPathUserState.FP_USER_ADD;
-		flowPath.setFlowPathUserState( state );
-		assertTrue( flowPath.flowPathUserState() == FlowPathUserState.FP_USER_ADD );
-	}
-
-	@Test
-	public void testFlowPathFlags(){
-		FlowPath flowPath = new FlowPath();
-		FlowPathFlags flags = new FlowPathFlags();
-		flags.setFlags(0);
-		flowPath.setFlowPathFlags( flags );
-		assertFalse( flowPath.flowPathFlags().isDiscardFirstHopEntry() );
-		assertFalse( flowPath.flowPathFlags().isKeepOnlyFirstHopEntry() );
-	}
-
-	@Test
-	public void testSetFlowPathFlags(){
-		FlowPath flowPath = new FlowPath();
-		FlowPathFlags flags = new FlowPathFlags("DISCARD_FIRST_HOP_ENTRY");
-		flags.setFlagsStr("KEEP_ONLY_FIRST_HOP_ENTRY");
-		flowPath.setFlowPathFlags( flags );
-		assertFalse( flowPath.flowPathFlags().isDiscardFirstHopEntry() );
-		assertTrue( flowPath.flowPathFlags().isKeepOnlyFirstHopEntry() );
-	}
-
-	@Test
-	public void testSetIdleTimeout(){
-		FlowPath flowPath = new FlowPath();
-		int idleTimeout = 15;
-		flowPath.setIdleTimeout( idleTimeout );
-		assertTrue( flowPath.idleTimeout() == 15 );
-	}
-
-	@Test
-	public void testSetHardTimeout(){
-		FlowPath flowPath = new FlowPath();
-		int hardTimeout = 20;
-		flowPath.setHardTimeout( hardTimeout );
-		assertTrue( flowPath.hardTimeout() == 20 );
-	}
-
-	@Test
-	public void testSetDataPath(){
-		FlowPath flowPath = new FlowPath();
-		DataPath dataPath = new DataPath();
-		flowPath.setDataPath( dataPath );
-		assertEquals(flowPath.dataPath(), dataPath );
-	}
-
-	@Test
-	public void testToString(){
-
-		assertEquals("[flowId=0x1234 installerId=installerId flowPathType=FP_TYPE_SHORTEST_PATH flowPathUserState=FP_USER_ADD flowPathFlags=[flags=] idleTimeout=5 hardTimeout=10 dataPath=[src=00:00:00:00:00:00:ca:fe/1 flowEntry=[flowEntryId=0x14 idleTimeout=0 hardTimeout=0 flowEntryMatch=[] flowEntryActions=[[type=ACTION_OUTPUT action=[port=23 maxLen=24]];[type=ACTION_OUTPUT action=[port=25 maxLen=26]];] dpid=00:00:00:00:00:00:be:ef flowEntryUserState=FE_USER_MODIFY flowEntrySwitchState=FE_SWITCH_UPDATE_IN_PROGRESS] dst=00:00:00:00:00:00:ba:be/2] flowEntryMatch=[] flowEntryActions=[[type=ACTION_OUTPUT action=[port=10 maxLen=11]];[type=ACTION_OUTPUT action=[port=12 maxLen=13]];]]", flowPath.toString());
-	}
-
-	@Test
-	public void testCompareTo(){
-		FlowPath flowPath1 = new FlowPath();
-		flowPath1.setFlowId( new FlowId(1));
-		FlowPath flowPath2 = new FlowPath();
-		flowPath2.setFlowId( new FlowId(2));
-		
-		assertTrue( flowPath1.compareTo(flowPath2) < 0);
-	}
-
-}
