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
new file mode 100644
index 0000000..31a4bb0
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableGraphDBOperation.java
@@ -0,0 +1,1331 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.annotations.gremlin.GremlinParam;
+
+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.util.FlowEntryId;
+import net.onrc.onos.ofcontroller.util.FlowId;
+import net.onrc.onos.util.GraphDBConnection;
+import net.onrc.onos.util.GraphDBOperation;
+import net.onrc.onos.util.IDBConnection;
+
+/**
+ * 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 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<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>();
+			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 void removeLink(IPortObject dest_port) { linkedPortsToRemove.add(dest_port); }
+
+		@Override
+		public void setLinkPort(IPortObject dest_port) { linkedPortsToAdd.add(dest_port); }
+	}
+		
+	public static class TestDeviceObject implements IDeviceObject {
+		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; }
+	}
+	
+	public static class TestFlowPath implements IFlowPath {
+		private String state,type,flowId,installerId,srcSw,dstSw;
+		private String dataPathSummary,userState;
+		private String matchSrcMac,matchDstMac,matchSrcIpaddr,matchDstIpaddr;
+		private Short srcPort,dstPort,matchEthernetFrameType;
+		
+		private List<IFlowEntry> entries;
+		private List<ISwitchObject> switches;
+
+		private String stateToUpdate,typeToUpdate,flowIdToUpdate,installerIdToUpdate,srcSwToUpdate,dstSwToUpdate;
+		private String dataPathSummaryToUpdate,userStateToUpdate;
+		private String matchSrcMacToUpdate,matchDstMacToUpdate,matchSrcIpaddrToUpdate,matchDstIpaddrToUpdate;
+		private Short srcPortToUpdate,dstPortToUpdate,matchEthernetFrameTypeToUpdate;
+
+		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(srcSwToUpdate != null) { srcSw = srcSwToUpdate; }
+			if(dstSwToUpdate != null) { dstSw = dstSwToUpdate; }
+			if(dataPathSummaryToUpdate != null) { dataPathSummary = dataPathSummaryToUpdate; }
+			if(userStateToUpdate != null) { userState = userStateToUpdate; }
+			if(matchSrcMacToUpdate != null) { matchSrcMac = matchSrcMacToUpdate; }
+			if(matchDstMacToUpdate != null) { matchDstMac = matchDstMacToUpdate; }
+			if(matchSrcIpaddrToUpdate != null) { matchSrcIpaddr = matchSrcIpaddrToUpdate; }
+			if(matchDstIpaddrToUpdate != null) { matchDstIpaddr = matchDstIpaddrToUpdate; }
+			if(srcPortToUpdate != null) { srcPort = srcPortToUpdate; }
+			if(dstPortToUpdate != null) { dstPort = dstPortToUpdate; }
+			if(matchEthernetFrameTypeToUpdate != null) { matchEthernetFrameType = matchEthernetFrameTypeToUpdate; }
+		}
+		
+		public void rollback() {
+			clear();
+		}
+		
+		public void clear() {
+			flowsToAdd.clear();
+			flowsToRemove.clear();
+			
+			stateToUpdate = typeToUpdate = flowIdToUpdate = installerIdToUpdate = null;
+			srcSwToUpdate = dstSwToUpdate = dataPathSummaryToUpdate = userStateToUpdate = null;
+			matchSrcMacToUpdate = matchDstMacToUpdate = matchSrcIpaddrToUpdate = matchDstIpaddrToUpdate = null;
+			srcPortToUpdate = dstPortToUpdate = matchEthernetFrameTypeToUpdate = 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 setSrcSwForTest(String srcSw) { this.srcSw = srcSw; }
+		public void setDstSwForTest(String dstSw) { this.dstSw = dstSw; }
+		public void setDataPathSummaryForTest(String dataPathSummary) { this.dataPathSummary = dataPathSummary; }
+		public void setUserStateForTest(String userState) { this.userState = userState; }
+		public void setMatchSrcMacForTest(String matchSrcMac) { this.matchSrcMac = matchSrcMac; }
+		public void setMatchDstMacForTest(String matchDstMac) { this.matchDstMac = matchDstMac; }
+		public void setMatchSrcIpaddrForTest(String matchSrcIpaddr) { this.matchSrcIpaddr = matchSrcIpaddr; }
+		public void setMatchDstIpaddrForTest(String matchDstIpaddr) { this.matchDstIpaddr = matchDstIpaddr; }
+		public void setSrcPortForTest(Short srcPort) { this.srcPort = srcPort; }
+		public void setDstPortForTest(Short dstPort) { this.dstPort = dstPort; }
+		public void setMatchEthernetFrameTypeForTest(Short matchEthernetFrameType) { this.matchEthernetFrameType = matchEthernetFrameType; }
+		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 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 Short getMatchEthernetFrameType() { return matchEthernetFrameType; }
+
+		@Override
+		public void setMatchEthernetFrameType(Short matchEthernetFrameType) {
+			matchEthernetFrameTypeToUpdate = matchEthernetFrameType; }
+
+		@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 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 Iterable<ISwitchObject> getSwitches() { return switches; }
+
+		@Override
+		public String getUserState() { return userState; }
+
+		@Override
+		public void setUserState(String userState) { userStateToUpdate = userState; }
+	}
+
+	public static class TestFlowEntry implements IFlowEntry {
+		private String state,type,entryId,dpid,userState,switchState,errorStateType,errorStateCode;
+		private String matchSrcMac,matchDstMac,matchSrcIpaddr,matchDstIpaddr;
+		private Short matchInPort,matchEtherFrameType,actionOutput;
+		
+		private IFlowPath flowPath;
+		private ISwitchObject sw;
+		private IPortObject inport,outport;
+	
+		private String stateToUpdate,typeToUpdate,entryIdToUpdate,dpidToUpdate,
+			userStateToUpdate,switchStateToUpdate,errorStateTypeToUpdate,errorStateCodeToUpdate;
+		private String matchSrcMacToUpdate,matchDstMacToUpdate,matchSrcIpaddrToUpdate,matchDstIpaddrToUpdate;
+	
+		private Short matchInPortToUpdate,matchEtherFrameTypeToUpdate,actionOutputToUpdate;
+	
+		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(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(matchSrcMacToUpdate != null) { matchSrcMac = matchSrcMacToUpdate; }
+			if(matchDstMacToUpdate != null) { matchDstMac = matchDstMacToUpdate; }
+			if(matchSrcIpaddrToUpdate != null) { matchSrcIpaddr = matchSrcIpaddrToUpdate; }
+			if(matchDstIpaddrToUpdate != null) { matchDstIpaddr = matchDstIpaddrToUpdate; }
+			if(matchInPortToUpdate != null) { matchInPort = matchInPortToUpdate; }
+			if(matchEtherFrameTypeToUpdate != null) { matchEtherFrameType = matchEtherFrameTypeToUpdate; }
+			if(actionOutputToUpdate != null) { actionOutput = actionOutputToUpdate; }
+			
+			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;
+			userStateToUpdate = switchStateToUpdate = errorStateTypeToUpdate = errorStateCodeToUpdate = null;
+			matchSrcMacToUpdate = matchDstMacToUpdate = matchSrcIpaddrToUpdate = matchDstIpaddrToUpdate = null;
+			matchInPortToUpdate = matchEtherFrameTypeToUpdate = actionOutputToUpdate = 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 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 setMatchSrcMacForTest(String matchSrcMac) { this.matchSrcMac = matchSrcMac; }
+		public void setMatchDstMacForTest(String matchDstMac) { this.matchDstMac = matchDstMac; }
+		public void setMatchSrcIpaddrForTest(String matchSrcIpaddr) { this.matchSrcIpaddr = matchSrcIpaddr; }
+		public void setMatchDstIpaddrForTest(String matchDstIpaddr) { this.matchDstIpaddr = matchDstIpaddr; }
+		public void setMatchInPortForTest(Short matchInPort) { this.matchInPort = matchInPort; }
+		public void setMatchEtherFrameTypeForTest(Short matchEtherFrameType) { this.matchEtherFrameType = matchEtherFrameType; }
+		public void setActionOutputForTest(Short actionOutput) { this.actionOutput = actionOutput; }
+		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 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 Short getMatchEthernetFrameType() {return matchEtherFrameType; }
+	
+		@Override
+		public void setMatchEthernetFrameType(Short matchEthernetFrameType) { matchEtherFrameTypeToUpdate = matchEthernetFrameType; }
+		
+		@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 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 Short getActionOutput() { return actionOutput; }
+	
+		@Override
+		public void setActionOutput(Short actionOutput) { actionOutputToUpdate = actionOutput; }
+	
+		@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
+
+	}
+}
