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 {
		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

	}
}
