Merge branch 'ONOS-ONRC2014-Measurements' of github.com:OPENNETWORKINGLAB/ONOS into RAMCloud-new_dynamics
diff --git a/blueprints-README.md b/blueprints-README.md
new file mode 100644
index 0000000..787bd36
--- /dev/null
+++ b/blueprints-README.md
@@ -0,0 +1,160 @@
+blueprints-ramcloud-graph
+=========================
+
+A TinkerPop Blueprints implementation for RAMCloud
+
+Setup
+=====
+ - Copy `src/main/java/edu/stanford/ramcloud/JRamCloud.java` and `src/main/cpp/edu_stanford_ramcloud_JRamCloud.cc` to your `ramcloud/bindinds/java/edu/stanford/ramcloud` directory, overwriting what is already there.
+
+ - Generate the C++ header files containing the function signatures for all the native methods in the Java RamCloud library:
+
+```
+javah -cp ../../../ edu.stanford.ramcloud.JRamCloud
+```
+
+ - Compile the ramcloud C++ library (assuming ramcloud is in your ${HOME} directory and you have already compiled ramcloud):
+
+```
+c++ -Wall -O3 -shared -fPIC -std=c++0x -I/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/include/ -I/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/include/linux/ -I${HOME}/ramcloud/src/ -I${HOME}/ramcloud/obj.master/ -I${HOME}/ramcloud/logcabin/ -I${HOME}/ramcloud/gtest/include/ -L${HOME}/ramcloud/obj.master -o libedu_stanford_ramcloud_JRamCloud.so edu_stanford_ramcloud_JRamCloud.cc -lramcloud
+```
+
+ - Update `LD_LIBRARY_PATH` (assuming ramcloud is in your ${HOME} directory) to include the library and also any other ramcloud libraries:
+
+```
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${HOME}/ramcloud/bindings/java/edu/stanford/ramcloud:${HOME}/ramcloud/obj.master
+```
+
+ - Startup a ramcloud cluster somewhere and modify RamCloudGraph.java to point to the coordinator.
+
+ - Compile this package (blueprints-ramcloud-graph) using maven and run :)
+
+Using Rexster
+=============
+ - git clone the rexster repository:
+
+```
+git clone https://github.com/tinkerpop/rexster.git
+```
+
+ - Compile rexster
+
+```
+cd rexster/
+mvn compile
+```
+
+ - Compile packaged rexster server
+
+```
+cd rexster-server/
+mvn package
+```
+
+ - Edit rexster-server config file
+
+```
+cd target/rexster-server-2.5.0-SNAPSHOT-standalone/
+vim config/rexster.xml
+```
+
+ - Change web-root to be your public web-root directory
+
+ - Add a ramcloud graph to the set of graphs to load up:
+
+```
+<graph>
+    <graph-enabled>true</graph-enabled>
+    <graph-name>ramcloudgraph</graph-name>
+    <graph-type>com.tinkerpop.rexster.config.RamCloudGraphConfiguration</graph-type>
+</graph>
+```
+
+ - Go back to the blueprints-ramcloud-graph directory and compile jar with depdencies:
+
+```
+mvn assembly:assembly -DdescriptorId=jar-with-dependencies
+```
+
+ - Copy resulting jar file into the compiled rexster-server library directory:
+
+```
+cp blueprints-ramcloud-graph-2.0.0-jar-with-depdencies.jar ~/git/rexster/rexster-server/target/rexster-server-2.5.0-SNAPSHOT-standalone/lib
+```
+
+ - Startup a ramcloud cluster (maybe using the cluster.py script):
+
+```
+./cluster.py --verbose --servers=5 --replicas=3 --backups=1 --masterArgs="--totalMasterMemory 80% --masterServiceThreads 4" --clients=1 --client=../obj.master/client --debug
+```
+
+ - Startup the rexster server:
+
+```
+./bin/rexster.sh -start &
+```
+
+ - Connect to rexster server at:
+
+```
+localhost:8182
+```
+
+
+Using Gremlin
+=============
+ - git clone the gremlin repository:
+
+```
+git clone https://github.com/tinkerpop/gremlin.git
+```
+
+ - Compile gremlin
+
+```
+cd rexster/
+mvn package
+```
+
+ - Go back to the blueprints-ramcloud-graph directory and compile jar with depdencies:
+
+```
+mvn assembly:assembly -DdescriptorId=jar-with-dependencies
+```
+
+ - Copy resulting jar file into the compiled gremlin-groovy library directory:
+
+```
+cp blueprints-ramcloud-graph-2.0.0-jar-with-depdencies.jar ~/git/gremlin/gremlin-groovy/target/gremlin-groovy-2.5.0-SNAPSHOT-standalone/lib
+```
+
+ - Startup a ramcloud cluster (maybe using the cluster.py script):
+
+```
+./cluster.py --verbose --servers=5 --replicas=3 --backups=1 --masterArgs="--totalMasterMemory 80% --masterServiceThreads 4" --clients=1 --client=../obj.master/client --debug
+```
+
+ - Startup gremlin shell:
+
+```
+./bin/gremlin.sh
+```
+
+ - Import RamCloudGraph java libraries and create RamCloudGraph:
+
+```
+         \,,,/
+         (o o)
+-----oOOo-(_)-oOOo-----
+gremlin> g = new com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraph()
+```
+
+ - Have fun!
+
+Using Furnace
+=============
+ - See `com.tinkerpop.blueprints.impls.ramcloud.FurnaceExamples` for some examples of using Furnace
+
+Using JUNG
+==========
+ - See `com.tinkerpop.blueprints.impls.ramcloud.JUNGExamples` for some examples of using the JUNG ouplementation (mostly taken from https://github.com/tinkerpop/blueprints/wiki/JUNG-Ouplementation).
diff --git a/cluster-mgmt/template/onsdemo_edge_template.py b/cluster-mgmt/template/onsdemo_edge_template.py
index c3d0287..b5a76f5 100755
--- a/cluster-mgmt/template/onsdemo_edge_template.py
+++ b/cluster-mgmt/template/onsdemo_edge_template.py
@@ -113,7 +113,7 @@
     #  controllers.append(rc)
 
     #net.controllers=controllers
-    net.build()
+    #net.build()
 
     host = []
     for i in range (NR_NODES):
diff --git a/conf/onos.properties b/conf/onos.properties
index e77e6e0..f1244df 100644
--- a/conf/onos.properties
+++ b/conf/onos.properties
@@ -12,5 +12,7 @@
 net.floodlightcontroller.core.FloodlightProvider.workerthreads = 16
 net.floodlightcontroller.forwarding.Forwarding.idletimeout = 5
 net.floodlightcontroller.forwarding.Forwarding.hardtimeout = 0
-net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher.dbconf = /tmp/cassandra.titan
+#net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher.dbconf = /tmp/cassandra.titan
 net.onrc.onos.datagrid.HazelcastDatagrid.datagridConfig = conf/hazelcast.xml
+net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher.dbconf = /tmp/ramcloud.conf
+net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher.graph_db_store = ramcloud
diff --git a/conf/ramcloud.conf b/conf/ramcloud.conf
new file mode 100644
index 0000000..b69fcd2
--- /dev/null
+++ b/conf/ramcloud.conf
@@ -0,0 +1,4 @@
+ramcloud.coordinatorIp=fast+udp:host=192.168.56.11
+ramcloud.coordinatorPort=port=12246
+ramcloud.serverIp=fast+udp:host=192.168.56.11
+ramcloud.serverPort=port=12242
diff --git a/kryo2/.gitignore b/kryo2/.gitignore
deleted file mode 100644
index 916e17c..0000000
--- a/kryo2/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-dependency-reduced-pom.xml
diff --git a/kryo2/pom.xml b/kryo2/pom.xml
deleted file mode 100644
index 788f952..0000000
--- a/kryo2/pom.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <groupId>net.onrc.onos</groupId>
-  <artifactId>kryo2</artifactId>
-  <version>2.22</version>
-  <packaging>jar</packaging>
-
-  <name>kryo2</name>
-  <url>http://maven.apache.org</url>
-
-  <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-  </properties>
-
-  <dependencies>
-    <dependency>
-      <groupId>com.esotericsoftware.kryo</groupId>
-      <artifactId>kryo</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-shade-plugin</artifactId>
-        <version>2.1</version>
-        <configuration>
-              <relocations>
-                <relocation>
-                  <pattern>com.esotericsoftware.kryo</pattern>
-                  <shadedPattern>com.esotericsoftware.kryo2</shadedPattern>
-                  <excludes>
-                  </excludes>
-                </relocation>
-              </relocations>
-        </configuration>
-        <executions>
-          <execution>
-            <phase>package</phase>
-            <goals>
-              <goal>shade</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>exec-maven-plugin</artifactId>
-        <version>1.2.1</version>
-        <executions>
-          <execution>
-            <id>kryo2</id>
-            <goals>
-              <goal>exec</goal>
-            </goals>
-          </execution>
-        </executions>
-            <configuration>
-              <executable>mvn</executable>
-              <commandlineArgs>install:install-file -DlocalRepositoryPath=${basedir}/../repo -DcreateChecksum=true -Dpackaging=jar -Dfile=${basedir}/target/${project.build.finalName}.jar -DgroupId=${project.groupId} -DartifactId=${project.artifactId} -Dversion=${project.version}</commandlineArgs>
-            </configuration>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/logcabin.patch b/logcabin.patch
new file mode 100644
index 0000000..100697c
--- /dev/null
+++ b/logcabin.patch
@@ -0,0 +1,21 @@
+diff --git a/Core/Time.h b/Core/Time.h
+index 1dd2e00..a9deddd 100644
+--- a/Core/Time.h
++++ b/Core/Time.h
+@@ -25,6 +25,7 @@ namespace std {
+ /**
+  * Prints std::time_point values in a way that is useful for unit tests.
+  */
++/*
+ template<typename Clock, typename Duration>
+ std::ostream&
+ operator<<(std::ostream& os,
+@@ -45,7 +46,7 @@ operator<<(std::ostream& os,
+                         microsSinceUnixEpoch / 1000000,
+                         microsSinceUnixEpoch % 1000000);
+ }
+-
++*/
+ }
+ 
+ namespace LogCabin {
diff --git a/perf-scripts/flow-sync-perf.py b/perf-scripts/flow-sync-perf.py
index b782333..61a204b 100755
--- a/perf-scripts/flow-sync-perf.py
+++ b/perf-scripts/flow-sync-perf.py
@@ -35,7 +35,9 @@
 print "ONOS Log File:", ONOS_LOG
 
 # Verify that tcpkill is installed
-if not Popen( 'which tcpkill', stdout=PIPE, shell=True).communicate():
+tcpkill_check = Popen( 'which tcpkill', stdout=PIPE, shell=True)
+tcpkill_check.communicate()
+if tcpkill_check.returncode != 0:
   print '* Installing tcpkill'
   call( 'apt-get install -y dsniff', stdout=PIPE, shell=True )
 
diff --git a/pom.xml b/pom.xml
index 39e9f30..b62b934 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
   <artifactId>onos</artifactId>
   <version>0.1.0</version>
   <packaging>jar</packaging>
-  <name>ONOS</name>
+  <name>ONOS-RAMCloud</name>
   <url>http://onlab.us/</url>
   <repositories>
     <!-- In Project repository -->
@@ -265,22 +265,11 @@
     </plugins>
   </reporting>
   <dependencies>
-    <!-- Commenting out original kryo 2.X
-         and using shaded version (net.onrc.onos.kryo2)
-         to workaround conflict with kryo 1.X in titan's dependency.(#443)
-    -->
-    <!--
     <dependency>
       <groupId>com.esotericsoftware.kryo</groupId>
       <artifactId>kryo</artifactId>
       <version>2.22</version>
     </dependency>
-    -->
-    <dependency>
-      <groupId>net.onrc.onos</groupId>
-      <artifactId>kryo2</artifactId>
-      <version>2.22</version>
-    </dependency>
     <!-- ONOS's direct dependencies -->
     <dependency>
       <groupId>org.apache.cassandra</groupId>
@@ -291,7 +280,7 @@
     <dependency>
       <groupId>com.thinkaurelius.titan</groupId>
       <artifactId>titan-all</artifactId>
-      <version>0.2.1</version>
+      <version>0.4.2</version>
       <exclusions>
 	<exclusion>
           <groupId>org.slf4j</groupId>
@@ -302,7 +291,7 @@
     <dependency>
       <groupId>com.tinkerpop</groupId>
       <artifactId>frames</artifactId>
-      <version>2.3.1</version>
+      <version>2.4.0</version>
     </dependency>
     <dependency>
       <groupId>com.tinkerpop.blueprints</groupId>
@@ -310,6 +299,21 @@
       <version>2.3.0</version>
     </dependency>
     <dependency>
+        <groupId>com.tinkerpop.rexster</groupId>
+        <artifactId>rexster-core</artifactId>
+        <version>2.4.0</version>
+    </dependency>
+    <dependency>
+        <groupId>com.tinkerpop.blueprints</groupId>
+        <artifactId>blueprints-test</artifactId>
+        <version>2.4.0</version>
+    </dependency>
+    <dependency>
+        <groupId>com.google.protobuf</groupId>
+        <artifactId>protobuf-java</artifactId>
+        <version>2.5.0</version>
+    </dependency>
+    <dependency>
       <groupId>com.hazelcast</groupId>
       <artifactId>hazelcast</artifactId>
       <version>3.0.2</version>
diff --git a/ramcloud.patch b/ramcloud.patch
new file mode 100644
index 0000000..d3a17e3
--- /dev/null
+++ b/ramcloud.patch
@@ -0,0 +1,13 @@
+diff --git a/src/MasterService.cc b/src/MasterService.cc
+index ba7fdf1..fa041e0 100644
+--- a/src/MasterService.cc
++++ b/src/MasterService.cc
+@@ -606,7 +606,7 @@ MasterService::multiWrite(const WireFormat::MultiOp::Request* reqHdr,
+             reqOffset, currentReq->valueLength);
+         reqOffset += currentReq->valueLength;
+ 
+-        if (stringKey == NULL || value == NULL) {
++        if (stringKey == NULL) {
+             respHdr->common.status = STATUS_REQUEST_FORMAT_ERROR;
+             break;
+         }
diff --git a/rebuild-local-repo.sh b/rebuild-local-repo.sh
index 4ea1fbf..1baa27b 100755
--- a/rebuild-local-repo.sh
+++ b/rebuild-local-repo.sh
@@ -15,11 +15,6 @@
     MVN="mvn"
 fi
 
-# Install Kryo2 workaround to local repo
-# - Shaded(rename package name to allow mixing 2 different Kryo version)
-# - Install created sharded jar to local repo
-${MVN} -f kryo2/pom.xml package exec:exec
-
 # Install modified curators to local repo
 ${MVN} install:install-file -Dfile=./curator/curator-framework-1.3.5-SNAPSHOT.jar -DgroupId=com.netflix.curator -DartifactId=curator-framework -Dversion=1.3.5-SNAPSHOT -Dpackaging=jar -DgeneratePom=true -DlocalRepositoryPath=./repo -DcreateChecksum=true
 ${MVN} install:install-file -Dfile=./curator/curator-client-1.3.5-SNAPSHOT.jar -DgroupId=com.netflix.curator -DartifactId=curator-client -Dversion=1.3.5-SNAPSHOT -Dpackaging=jar -DgeneratePom=true -DlocalRepositoryPath=./repo -DcreateChecksum=true
diff --git a/scripts/all-linkup.sh b/scripts/all-linkup.sh
index 9067012..290a17d 100755
--- a/scripts/all-linkup.sh
+++ b/scripts/all-linkup.sh
@@ -3,11 +3,6 @@
 controller=`hostname`
 switches=`sudo ovs-vsctl list-br`
 
-function host2ip (){
-   ip=`grep $1 /etc/hosts |grep -v "ip6"|  awk '{print $1}'`
-   echo $ip
-}
-
 for s in $switches; do
   ports=`sudo ovs-vsctl --pretty list-ports $s`
   for p in $ports; do
diff --git a/scripts/ctrl-local.sh b/scripts/ctrl-local.sh
index 023a9db..1418a2c 100755
--- a/scripts/ctrl-local.sh
+++ b/scripts/ctrl-local.sh
@@ -1,9 +1,8 @@
 #! /bin/bash
 controller=`hostname`
-switches=`ifconfig -a | grep sw |grep -v eth | awk '{print $1}'`
-
+switches=`sudo ovs-vsctl list-br`
 function host2ip (){
-   ip=`grep $1 /etc/hosts |grep -v "ip6"|  awk '{print $1}'`
+   ip=`getent hosts $1 |  awk '{print $1}' | tail -n 1`
    echo $ip
 }
 
diff --git a/scripts/ctrl-none.sh b/scripts/ctrl-none.sh
index 74349e3..fb8d2a0 100755
--- a/scripts/ctrl-none.sh
+++ b/scripts/ctrl-none.sh
@@ -1,9 +1,8 @@
 #! /bin/bash
 controller=""
-switches=`ifconfig -a | grep sw |grep -v eth | awk '{print $1}'`
-
+switches=`sudo ovs-vsctl list-br`
 function host2ip (){
-   ip=`grep $1 /etc/hosts |grep -v "ip6"|  awk '{print $1}'`
+   ip=`getent hosts $1 |  awk '{print $1}' | tail -n 1`
    echo $ip
 }
 
diff --git a/scripts/ctrl-one.sh b/scripts/ctrl-one.sh
index 207d3f2..9fe8341 100755
--- a/scripts/ctrl-one.sh
+++ b/scripts/ctrl-one.sh
@@ -8,10 +8,9 @@
 
 #controller=`hostname`
 controller=$1
-switches=`ifconfig -a | grep sw |grep -v eth | awk '{print $1}'`
-
+switches=`sudo ovs-vsctl list-br`
 function host2ip (){
-   ip=`grep $1 /etc/hosts |grep -v "ip6"|  awk '{print $1}'`
+   ip=`getent hosts $1 |  awk '{print $1}' | tail -n 1`
    echo $ip
 }
 
diff --git a/scripts/link.sh b/scripts/link.sh
index dc202e7..57323ef 100755
--- a/scripts/link.sh
+++ b/scripts/link.sh
@@ -1,7 +1,7 @@
 #! /bin/bash
 
 controller=`hostname`
-switches=`ifconfig -a | grep sw |grep -v eth | awk '{print $1}'`
+switches=`sudo ovs-vsctl list-br`
 
 function host2ip (){
    ip=`grep $1 /etc/hosts |grep -v "ip6"|  awk '{print $1}'`
@@ -12,14 +12,16 @@
 
 if [ $# != 3 ];then
  echo "usage: $0 <dpid> <port> <up|down>"
+ echo " example: $0 00:00:00:00:ba:5e:ba:11 1 up"
+ exit
 fi
 
-src_dpid="dpid:"`echo $1 | sed s'/://g'`
+src_dpid=`echo $1 | sed s'/://g'`
 src_port=$2
 cmd=$3
 
 for s in $switches; do
-    dpid=`sudo ovs-ofctl  show  $s |grep dpid | awk '{print $4}'`
+    dpid=`sudo ovs-ofctl show  $s |grep dpid | awk '{if(match($0,/dpid:[0-9|a-d]*/)){ print substr($0,RSTART+5,RLENGTH)}}'`
     if [  "x$dpid" == "x$src_dpid" ]; then
 
 #       intf=`sudo ovs-ofctl show $s |grep addr | awk -v p=$src_port 'BEGIN {pat="^ "p"\("}
diff --git a/scripts/showdpid.sh b/scripts/showdpid.sh
index 1dff291..14b6345 100755
--- a/scripts/showdpid.sh
+++ b/scripts/showdpid.sh
@@ -2,17 +2,6 @@
 controller=""
 #switches=`ifconfig -a | grep sw |grep -v eth | awk '{print $1}'`
 switches=`sudo ovs-vsctl list-br`
-
-function host2ip (){
-   ip=`grep $1 /etc/hosts |grep -v "ip6"|  awk '{print $1}'`
-   echo $ip
-}
-
-url=""
-for c in $controller; do
-  url="$url tcp:`host2ip $c`:6633"
-done
-echo $url
 for s in $switches; do
     echo -n "$s : "
     sudo ovs-ofctl  show  $s |grep dpid
diff --git a/scripts/showflow.sh b/scripts/showflow.sh
index 15824d7..63b82b7 100755
--- a/scripts/showflow.sh
+++ b/scripts/showflow.sh
@@ -2,11 +2,6 @@
 controller=""
 switches=`sudo ovs-vsctl list-br`
 
-function host2ip (){
-   ip=`grep $1 /etc/hosts |grep -v "ip6"|  awk '{print $1}'`
-   echo $ip
-}
-
 dpids=()
 for s in $switches; do
     i=`sudo ovs-ofctl  show  $s |grep dpid | awk -F ":" '{print $4}'`
diff --git a/setup-ramcloud.sh b/setup-ramcloud.sh
new file mode 100755
index 0000000..758bb0c
--- /dev/null
+++ b/setup-ramcloud.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+set -x
+
+ONOS_HOME=~/ONOS
+RAMCLOUD_HOME=~/ramcloud
+
+# clone ramcloud
+git clone https://github.com/y-higuchi/ramcloud.git ${RAMCLOUD_HOME}
+cd ${RAMCLOUD_HOME}
+git checkout blueprint-java
+git checkout 64462be50b9b0add25cf16beea75eb40bf89f62c
+
+# install some app
+sudo apt-get -y install build-essential git-core libcppunit-dev libcppunit-doc doxygen libboost-all-dev libpcre3-dev protobuf-compiler libprotobuf-dev libcrypto++-dev libevent-dev scons libssl-dev
+
+# compile ramcloud
+git submodule update --init --recursive
+patch ${RAMCLOUD_HOME}/src/MasterService.cc < ${ONOS_HOME}/ramcloud.patch 
+patch ${RAMCLOUD_HOME}/logcabin/Core/Time.h < ${ONOS_HOME}/logcabin.patch
+make logcabin
+make
+
+ln -s ${RAMCLOUD_HOME}/obj obj.blueprint-java
+
+# crate ramcloud lib
+cp ${ONOS_HOME}/src/main/java/edu/stanford/ramcloud/JRamCloud.java ${HOME}/ramcloud/bindings/java/edu/stanford/ramcloud/
+cp ${ONOS_HOME}/src/main/cpp/edu_stanford_ramcloud_JRamCloud.cc ${HOME}/ramcloud/bindings/java/edu/stanford/ramcloud/
+cd ${HOME}/ramcloud/bindings/java/edu/stanford/ramcloud/
+javac JRamCloud.java
+./build_so.sh
+jar cvf ${RAMCLOUD_HOME}/bindings/java/RamCloud.jar ${RAMCLOUD_HOME}/bindings/java/edu/stanford/ramcloud/*.class
diff --git a/src/apps/java/com/tinkerpop/blueprints/impls/ramcloud/FurnaceExamples.java b/src/apps/java/com/tinkerpop/blueprints/impls/ramcloud/FurnaceExamples.java
new file mode 100644
index 0000000..0da987e
--- /dev/null
+++ b/src/apps/java/com/tinkerpop/blueprints/impls/ramcloud/FurnaceExamples.java
@@ -0,0 +1,72 @@
+/* Copyright (c) 2013 Stanford University
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package com.tinkerpop.blueprints.impls.ramcloud;
+
+import java.util.logging.Level;
+
+import com.tinkerpop.blueprints.Graph;
+import com.tinkerpop.furnace.generators.CommunityGenerator;
+import com.tinkerpop.furnace.generators.DistributionGenerator;
+import com.tinkerpop.furnace.generators.NormalDistribution;
+
+public class FurnaceExamples {
+
+  public FurnaceExamples() {
+    // TODO Auto-generated constructor stub
+  }
+
+  public static int generateCommunityGraph(Graph graph, String label) {
+    CommunityGenerator cg = new CommunityGenerator(label);
+    int numEdges;
+    
+    for(int i = 0; i<30; i++) {
+      graph.addVertex(null);
+    }
+    
+    cg.setCommunityDistribution(new NormalDistribution(2.0));
+    cg.setDegreeDistribution(new NormalDistribution(2.0));
+    numEdges = cg.generate(graph, 3, 60);
+    
+    return numEdges;
+  }
+  
+  public static int generateDistributionGraph(Graph graph, String label) {
+    DistributionGenerator dg = new DistributionGenerator(label);
+    int numEdges;
+    
+    for(int i = 0; i<10; i++) {
+      graph.addVertex(null);
+    }
+    
+    dg.setAllowLoops(true);
+    dg.setInDistribution(new NormalDistribution(2.0));
+    dg.setOutDistribution(new NormalDistribution(2.0));
+    numEdges = dg.generate(graph, 20);
+    
+    return numEdges;
+  }
+  
+  public static void main(String[] args) {
+    Graph graph = new RamCloudGraph(Level.FINER);
+    
+    //generateCommunityGraph(graph, "HippieCommune");
+    
+    //generateDistributionGraph(graph, "HippieRefuge");
+    
+    graph.shutdown();
+  }
+
+}
diff --git a/src/apps/java/com/tinkerpop/blueprints/impls/ramcloud/JUNGExamples.java b/src/apps/java/com/tinkerpop/blueprints/impls/ramcloud/JUNGExamples.java
new file mode 100644
index 0000000..9645854
--- /dev/null
+++ b/src/apps/java/com/tinkerpop/blueprints/impls/ramcloud/JUNGExamples.java
@@ -0,0 +1,104 @@
+/* Copyright (c) 2013 Stanford University
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package com.tinkerpop.blueprints.impls.ramcloud;
+
+import java.awt.Dimension;
+import java.util.logging.Level;
+
+import javax.swing.JFrame;
+
+import org.apache.commons.collections15.Transformer;
+
+import com.tinkerpop.blueprints.Edge;
+import com.tinkerpop.blueprints.Graph;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.oupls.jung.GraphJung;
+
+import edu.uci.ics.jung.algorithms.layout.BalloonLayout;
+import edu.uci.ics.jung.algorithms.layout.CircleLayout;
+import edu.uci.ics.jung.algorithms.layout.DAGLayout;
+import edu.uci.ics.jung.algorithms.layout.FRLayout;
+import edu.uci.ics.jung.algorithms.layout.FRLayout2;
+import edu.uci.ics.jung.algorithms.layout.ISOMLayout;
+import edu.uci.ics.jung.algorithms.layout.KKLayout;
+import edu.uci.ics.jung.algorithms.layout.Layout;
+import edu.uci.ics.jung.algorithms.scoring.PageRank;
+import edu.uci.ics.jung.visualization.BasicVisualizationServer;
+
+public class JUNGExamples {
+
+  public JUNGExamples() {
+    // TODO Auto-generated constructor stub
+  }
+  
+  public static void calculatePageRank(Graph graph) {
+    PageRank<Vertex,Edge> pageRank = new PageRank<Vertex, Edge>(new GraphJung(graph), 0.15d);
+    pageRank.evaluate();
+    
+    for (Vertex vertex : graph.getVertices()) {
+      System.out.println("The PageRank score of " + vertex + " is: " + pageRank.getVertexScore(vertex));
+    }
+  }
+
+  public static void displayGraph(Graph graph) {
+    GraphJung gj = new GraphJung(graph);
+    
+    Layout<Vertex, Edge> layout = new CircleLayout<Vertex, Edge>(gj);
+    layout.setSize(new Dimension(600, 600));
+    BasicVisualizationServer<Vertex, Edge> viz = new BasicVisualizationServer<Vertex, Edge>(layout);
+    viz.setPreferredSize(new Dimension(650, 650));
+
+    Transformer<Vertex, String> vertexLabelTransformer = new Transformer<Vertex, String>() {
+      public String transform(Vertex vertex) {
+        return (String) vertex.getProperty("name");
+      }
+    };
+
+    Transformer<Edge, String> edgeLabelTransformer = new Transformer<Edge, String>() {
+      public String transform(Edge edge) {
+        return edge.getLabel();
+      }
+    };
+
+    viz.getRenderContext().setEdgeLabelTransformer(edgeLabelTransformer);
+    viz.getRenderContext().setVertexLabelTransformer(vertexLabelTransformer);
+
+    JFrame frame = new JFrame("TinkerPop");
+    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+    frame.getContentPane().add(viz);
+    frame.pack();
+    frame.setVisible(true);
+    
+    try {
+      System.in.read();
+    } catch(Exception e) {
+      // poop
+    }
+  }
+  
+  public static void main(String[] args) {
+    Graph graph = new RamCloudGraph(Level.FINER);
+    
+    FurnaceExamples.generateDistributionGraph(graph, "ex");
+    
+    //calculatePageRank(graph);
+    
+    displayGraph(graph);
+    
+    graph.shutdown();
+  }
+
+}
diff --git a/src/main/cpp/edu_stanford_ramcloud_JRamCloud.cc b/src/main/cpp/edu_stanford_ramcloud_JRamCloud.cc
new file mode 100755
index 0000000..fc93cb4
--- /dev/null
+++ b/src/main/cpp/edu_stanford_ramcloud_JRamCloud.cc
@@ -0,0 +1,766 @@
+/* Copyright (c) 2013 Stanford University
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <RamCloud.h>
+#include <TableEnumerator.h>
+#include <Object.h>
+#include "edu_stanford_ramcloud_JRamCloud.h"
+#include "edu_stanford_ramcloud_JRamCloud_TableEnumerator.h"
+
+using namespace RAMCloud;
+
+/// Our JRamCloud java library is packaged under "edu.stanford.ramcloud".
+/// We will need this when using FindClass, etc.
+#define PACKAGE_PATH "edu/stanford/ramcloud/"
+
+#define check_null(var, msg)                                                \
+    if (var == NULL) {                                                      \
+        throw Exception(HERE, "JRamCloud: NULL returned: " msg "\n");       \
+    }
+
+/**
+ * This class provides a simple means of extracting C-style strings
+ * from a jstring and cleans up when the destructor is called. This
+ * avoids having to manually do the annoying GetStringUTFChars /
+ * ReleaseStringUTFChars dance. 
+ */
+class JStringGetter {
+  public:
+    JStringGetter(JNIEnv* env, jstring jString)
+        : env(env)
+        , jString(jString)
+        , string(env->GetStringUTFChars(jString, 0))
+    {
+        check_null(string, "GetStringUTFChars failed");
+    }
+    
+    ~JStringGetter()
+    {
+        if (string != NULL)
+            env->ReleaseStringUTFChars(jString, string);
+    }
+
+  private:    
+    JNIEnv* env;
+    jstring jString;
+
+  public:
+    const char* const string;
+};
+
+/**
+ * This class provides a simple means of accessing jbyteArrays as
+ * C-style void* buffers and cleans up when the destructor is called.
+ * This avoids having to manually do the annoying GetByteArrayElements /
+ * ReleaseByteArrayElements dance.
+ */
+class JByteArrayGetter {
+  public:
+    JByteArrayGetter(JNIEnv* env, jbyteArray jByteArray)
+        : env(env)
+        , jByteArray(jByteArray)
+        , pointer(static_cast<void*>(env->GetByteArrayElements(jByteArray, 0)))
+        , length(env->GetArrayLength(jByteArray))
+    {
+        check_null(pointer, "GetByteArrayElements failed");
+    }
+    
+    ~JByteArrayGetter()
+    {
+        if (pointer != NULL) {
+            env->ReleaseByteArrayElements(jByteArray,
+                                          reinterpret_cast<jbyte*>(pointer),
+                                          0);
+        }
+    }
+
+  private:    
+    JNIEnv* env;
+    jbyteArray jByteArray;
+
+  public:
+    void* const pointer;
+    const jsize length;
+};
+
+class JByteArrayReference {
+  public:
+    JByteArrayReference(JNIEnv* env, jbyteArray jByteArray)
+        : env(env)
+        , jByteArray(jByteArray)
+        , pointer(static_cast<const void*>(env->GetByteArrayElements(jByteArray, 0)))
+        , length(env->GetArrayLength(jByteArray))
+    {
+        check_null(pointer, "GetByteArrayElements failed");
+    }
+
+    ~JByteArrayReference()
+    {
+        if (pointer != NULL) {
+            env->ReleaseByteArrayElements(jByteArray,
+                                          (jbyte*)pointer,
+                                          JNI_ABORT);
+        }
+    }
+
+  private:
+    JNIEnv* env;
+    jbyteArray jByteArray;
+
+  public:
+    const void* const pointer;
+    const jsize length;
+};
+
+static RamCloud*
+getRamCloud(JNIEnv* env, jobject jRamCloud)
+{
+    const static jclass cls = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud"));
+    const static jfieldID fieldId = env->GetFieldID(cls, "ramcloudObjectPointer", "J");
+    return reinterpret_cast<RamCloud*>(env->GetLongField(jRamCloud, fieldId));
+}
+
+static TableEnumerator*
+getTableEnumerator(JNIEnv* env, jobject jTableEnumerator)
+{
+    const static jclass cls = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$TableEnumerator"));
+    const static jfieldID fieldId = env->GetFieldID(cls, "tableEnumeratorObjectPointer", "J");
+    return reinterpret_cast<TableEnumerator*>(env->GetLongField(jTableEnumerator, fieldId));    
+}
+
+static void
+createException(JNIEnv* env, jobject jRamCloud, const char* name)
+{
+    // Need to specify the full class name, including the package. To make it
+    // slightly more complicated, our exceptions are nested under the JRamCloud
+    // class.
+    string fullName = PACKAGE_PATH;
+    fullName += "JRamCloud$";
+    fullName += name;
+
+    // This would be much easier if we didn't make our Exception classes nested
+    // under JRamCloud since env->ThrowNew() could be used instead. The problem
+    // is that ThrowNew assumes a particular method signature that happens to
+    // be incompatible with the nested classes' signatures.
+    jclass cls = env->FindClass(fullName.c_str());
+    check_null(cls, "FindClass failed");
+
+    jmethodID methodId = env->GetMethodID(cls,
+                                          "<init>",
+                                          "(L" PACKAGE_PATH "JRamCloud;Ljava/lang/String;)V");
+    check_null(methodId, "GetMethodID failed");
+
+    jstring jString = env->NewStringUTF("");
+    check_null(jString, "NewStringUTF failed");
+
+    jthrowable exception = reinterpret_cast<jthrowable>(
+        env->NewObject(cls, methodId, jRamCloud, jString));
+    check_null(exception, "NewObject failed");
+
+    env->Throw(exception);
+}
+
+/**
+ * This macro is used to catch C++ exceptions and convert them into Java
+ * exceptions. Be sure to wrap the individual RamCloud:: calls in try blocks,
+ * rather than the entire methods, since doing so with functions that return
+ * non-void is a bad idea with undefined(?) behaviour. 
+ *
+ * _returnValue is the value that should be returned from the JNI function
+ * when an exception is caught and generated in Java. As far as I can tell,
+ * the exception fires immediately upon returning from the JNI method. I
+ * don't think anything else would make sense, but the JNI docs kind of
+ * suck.
+ */
+#define EXCEPTION_CATCHER(_returnValue)                                        \
+    catch (TableDoesntExistException& e) {                                     \
+        createException(env, jRamCloud, "TableDoesntExistException");          \
+        return _returnValue;                                                   \
+    } catch (ObjectDoesntExistException& e) {                                  \
+        createException(env, jRamCloud, "ObjectDoesntExistException");         \
+        return _returnValue;                                                   \
+    } catch (ObjectExistsException& e) {                                       \
+        createException(env, jRamCloud, "ObjectExistsException");              \
+        return _returnValue;                                                   \
+    } catch (WrongVersionException& e) {                                       \
+        createException(env, jRamCloud, "WrongVersionException");              \
+        return _returnValue;                                                   \
+    } catch (RejectRulesException& e) {                                        \
+        createException(env, jRamCloud, "RejectRulesException");               \
+        return _returnValue;                                                   \
+    } catch (InvalidObjectException& e) {                                      \
+        createException(env, jRamCloud, "InvalidObjectException");             \
+        return _returnValue;                                                   \
+    }
+
+/*
+ * Class:     edu_stanford_ramcloud_JRamCloud
+ * Method:    connect
+ * Signature: (Ljava/lang/String;)J
+ */
+JNIEXPORT jlong 
+JNICALL Java_edu_stanford_ramcloud_JRamCloud_connect(JNIEnv *env,
+                               jclass jRamCloud,
+                               jstring coordinatorLocator)
+{
+    JStringGetter locator(env, coordinatorLocator);
+    RamCloud* ramcloud = NULL;
+    try {
+        ramcloud = new RamCloud(locator.string);
+    } EXCEPTION_CATCHER(NULL);
+    return reinterpret_cast<jlong>(ramcloud);
+}
+
+/*
+ * Class:     edu_stanford_ramcloud_JRamCloud
+ * Method:    disconnect
+ * Signature: (J)V
+ */
+JNIEXPORT void
+JNICALL Java_edu_stanford_ramcloud_JRamCloud_disconnect(JNIEnv *env,
+                                  jclass jRamCloud,
+                                  jlong ramcloudObjectPointer)
+{
+    delete reinterpret_cast<RamCloud*>(ramcloudObjectPointer);
+}
+
+/*
+ * Class:     edu_stanford_ramcloud_JRamCloud
+ * Method:    createTable
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jlong
+JNICALL Java_edu_stanford_ramcloud_JRamCloud_createTable__Ljava_lang_String_2(JNIEnv *env,
+                                                        jobject jRamCloud,
+                                                        jstring jTableName)
+{
+    return Java_edu_stanford_ramcloud_JRamCloud_createTable__Ljava_lang_String_2I(env,
+                                                            jRamCloud,
+                                                            jTableName,
+                                                            1);
+}
+
+/*
+ * Class:     edu_stanford_ramcloud_JRamCloud
+ * Method:    createTable
+ * Signature: (Ljava/lang/String;I)I
+ */
+JNIEXPORT jlong
+JNICALL Java_edu_stanford_ramcloud_JRamCloud_createTable__Ljava_lang_String_2I(JNIEnv *env,
+                                                         jobject jRamCloud,
+                                                         jstring jTableName,
+                                                         jint jServerSpan)
+{
+    RamCloud* ramcloud = getRamCloud(env, jRamCloud);
+    JStringGetter tableName(env, jTableName);
+    uint64_t tableId;
+    try {
+        tableId = ramcloud->createTable(tableName.string, jServerSpan);
+    } EXCEPTION_CATCHER(-1);
+    return static_cast<jlong>(tableId);
+}
+
+/*
+ * Class:     edu_stanford_ramcloud_JRamCloud
+ * Method:    dropTable
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT void
+JNICALL Java_edu_stanford_ramcloud_JRamCloud_dropTable(JNIEnv *env,
+                                 jobject jRamCloud,
+                                 jstring jTableName)
+{
+    RamCloud* ramcloud = getRamCloud(env, jRamCloud);
+    JStringGetter tableName(env, jTableName);
+    try {
+        ramcloud->dropTable(tableName.string);
+    } EXCEPTION_CATCHER();
+}
+
+/*
+ * Class:     edu_stanford_ramcloud_JRamCloud
+ * Method:    getTableId
+ * Signature: (Ljava/lang/String;)J
+ */
+JNIEXPORT jlong
+JNICALL Java_edu_stanford_ramcloud_JRamCloud_getTableId(JNIEnv *env,
+                                  jobject jRamCloud,
+                                  jstring jTableName)
+{
+    RamCloud* ramcloud = getRamCloud(env, jRamCloud);
+    JStringGetter tableName(env, jTableName);
+    uint64_t tableId;
+    try {
+        tableId = ramcloud->getTableId(tableName.string);
+    } EXCEPTION_CATCHER(-1);
+    return tableId;
+}
+
+/*
+ * Class:     edu_stanford_ramcloud_JRamCloud
+ * Method:    read
+ * Signature: (J[B)LJRamCloud/Object;
+ */
+JNIEXPORT jobject
+JNICALL Java_edu_stanford_ramcloud_JRamCloud_read__J_3B(JNIEnv *env,
+                                  jobject jRamCloud,
+                                  jlong jTableId,
+                                  jbyteArray jKey)
+{
+    RamCloud* ramcloud = getRamCloud(env, jRamCloud);
+    JByteArrayReference key(env, jKey);
+
+    Buffer buffer;
+    uint64_t version;
+    try {
+        ramcloud->read(jTableId, key.pointer, key.length, &buffer, NULL, &version);
+    } EXCEPTION_CATCHER(NULL);
+
+    jbyteArray jValue = env->NewByteArray(buffer.getTotalLength());
+    check_null(jValue, "NewByteArray failed");
+    JByteArrayGetter value(env, jValue);
+    buffer.copy(0, buffer.getTotalLength(), value.pointer);
+
+    // Note that using 'javap -s' on the class file will print out the method
+    // signatures (the third argument to GetMethodID).
+    const static jclass cls = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$Object"));
+    check_null(cls, "FindClass failed");
+
+    const static jmethodID methodId = env->GetMethodID(cls,
+                                          "<init>",
+                                          "(L" PACKAGE_PATH "JRamCloud;[B[BJ)V");
+    check_null(methodId, "GetMethodID failed");
+
+    return env->NewObject(cls,
+                          methodId,
+                          jRamCloud,
+                          jKey,
+                          jValue,
+                          static_cast<jlong>(version));
+}
+
+/*
+ * Class:     edu_stanford_ramcloud_JRamCloud
+ * Method:    read
+ * Signature: (J[BLJRamCloud/RejectRules;)LJRamCloud/Object;
+ */
+JNIEXPORT jobject
+JNICALL Java_edu_stanford_ramcloud_JRamCloud_read__J_3BLJRamCloud_RejectRules_2(JNIEnv *env,
+                                                          jobject jRamCloud,
+                                                          jlong jTableId,
+                                                          jbyteArray jKey,
+                                                          jobject jRejectRules)
+{
+    // XXX-- implement me by generalising the other read() method.
+    return NULL;
+}
+
+/*
+ * Class:     edu_stanford_ramcloud_JRamCloud
+ * Method:    multiRead
+ * Signature: ([Ledu/stanford/ramcloud/JRamCloud$multiReadObject;I)[Ledu/stanford/ramcloud/JRamCloud$Object;
+ */
+JNIEXPORT jobjectArray
+JNICALL Java_edu_stanford_ramcloud_JRamCloud_multiRead(JNIEnv *env,   
+                                                        jobject jRamCloud,
+                                                        jobjectArray jmultiReadArray){
+
+    RamCloud* ramcloud = getRamCloud(env, jRamCloud);
+    const jint requestNum = env->GetArrayLength(jmultiReadArray);
+    MultiReadObject objects[requestNum];
+    Tub<Buffer> values[requestNum];
+    jbyteArray jKey[requestNum];
+    MultiReadObject* requests[requestNum];
+
+    const static jclass jc_multiReadObject = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$multiReadObject"));
+    const static jfieldID jf_tableId = env->GetFieldID(jc_multiReadObject, "tableId", "J");
+    const static jfieldID jf_key = env->GetFieldID(jc_multiReadObject, "key", "[B");
+
+    for (int i = 0 ; i < requestNum ; i++){
+        jobject obj = env->GetObjectArrayElement(jmultiReadArray, i);
+        check_null(obj, "GetObjectArrayElement failed");
+        jlong jTableId = env->GetLongField(obj, jf_tableId);
+
+        jKey[i] = (jbyteArray)env->GetObjectField(obj, jf_key);
+
+        jbyte* data = env->GetByteArrayElements(jKey[i], NULL);
+        check_null(data, "GetByteArrayElements failed");
+
+        objects[i].tableId = jTableId;
+        objects[i].key = data;
+        objects[i].keyLength = env->GetArrayLength(jKey[i]);
+        objects[i].value = &values[i];
+        requests[i] = &objects[i];
+    }
+
+    try {
+        ramcloud->multiRead(requests, requestNum);
+    } EXCEPTION_CATCHER(NULL);
+    
+    const static jclass jc_RcObject = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$Object"));
+    check_null(jc_RcObject, "FindClass failed");
+    const static jmethodID jm_init = env->GetMethodID(jc_RcObject,
+                                        "<init>",
+                                        "(L" PACKAGE_PATH "JRamCloud;[B[BJ)V");
+
+    jobjectArray outJNIArray = env->NewObjectArray(requestNum, jc_RcObject , NULL);
+    check_null(outJNIArray, "NewObjectArray failed");
+    
+    for (int i = 0 ; i < requestNum ; i++) {
+	if (objects[i].status == 0) {
+	    jbyteArray jValue = env->NewByteArray(values[i].get()->getTotalLength());
+	    check_null(jValue, "NewByteArray failed");
+	    JByteArrayGetter value(env, jValue);
+	    values[i].get()->copy(0, values[i].get()->getTotalLength(), value.pointer);
+	    jobject obj = env->NewObject(jc_RcObject, jm_init, jRamCloud, jKey[i], jValue);
+	    check_null(obj, "NewObject failed");
+	    env->SetObjectArrayElement(outJNIArray, i, obj);
+	}
+	// keys are read only so no need to copy back to Java side: JNI_ABORT
+	env->ReleaseByteArrayElements(jKey[i], (jbyte *) objects[i].key, JNI_ABORT);
+    }
+    return outJNIArray;
+}
+
+
+/*
+ * Class:     edu_stanford_ramcloud_JRamCloud
+ * Method:    remove
+ * Signature: (J[B)J
+ */
+JNIEXPORT jlong
+JNICALL Java_edu_stanford_ramcloud_JRamCloud_remove__J_3B(JNIEnv *env,
+                                    jobject jRamCloud,
+                                    jlong jTableId,
+                                    jbyteArray jKey)
+{
+    RamCloud* ramcloud = getRamCloud(env, jRamCloud);
+    JByteArrayReference key(env, jKey);
+    uint64_t version;
+    try {
+        ramcloud->remove(jTableId, key.pointer, key.length, NULL, &version);
+    } EXCEPTION_CATCHER(-1);
+    return static_cast<jlong>(version);
+}
+
+/*
+ * Class:     edu_stanford_ramcloud_JRamCloud
+ * Method:    remove
+ * Signature: (J[BLJRamCloud/RejectRules;)J
+ */
+JNIEXPORT jlong
+JNICALL Java_edu_stanford_ramcloud_JRamCloud_remove__J_3BLJRamCloud_RejectRules_2(JNIEnv *env,
+                                                           jobject jRamCloud,
+                                                           jlong jTableId,
+                                                           jbyteArray jKey,
+                                                           jobject jRejectRules)
+{
+    // XXX- handle RejectRules
+    RamCloud* ramcloud = getRamCloud(env, jRamCloud);
+    JByteArrayReference key(env, jKey);
+    uint64_t version;
+    try {
+        ramcloud->remove(jTableId, key.pointer, key.length, NULL, &version);
+    } EXCEPTION_CATCHER(-1);
+    return static_cast<jlong>(version);
+}
+
+/*
+ * Class:     edu_stanford_ramcloud_JRamCloud
+ * Method:    write
+ * Signature: (J[B[B)J
+ */
+JNIEXPORT jlong
+JNICALL Java_edu_stanford_ramcloud_JRamCloud_write__J_3B_3B(JNIEnv *env,
+                                      jobject jRamCloud,
+                                      jlong jTableId,
+                                      jbyteArray jKey,
+                                      jbyteArray jValue)
+{
+    RamCloud* ramcloud = getRamCloud(env, jRamCloud);
+    JByteArrayReference key(env, jKey);
+    JByteArrayGetter value(env, jValue);
+    uint64_t version;
+    try {
+        ramcloud->write(jTableId,
+                        key.pointer, key.length,
+                        value.pointer, value.length,
+                        NULL,
+                        &version);
+    } EXCEPTION_CATCHER(-1);
+    return static_cast<jlong>(version);
+}
+
+/*
+ * Class:     edu_stanford_ramcloud_JRamCloud
+ * Method:    write
+ * Signature: (J[B[BLJRamCloud/RejectRules;)J
+ */
+JNIEXPORT jlong
+JNICALL Java_edu_stanford_ramcloud_JRamCloud_write__J_3B_3BLJRamCloud_RejectRules_2(JNIEnv *env,
+                                                           jobject jRamCloud,
+                                                           jlong jTableId,
+                                                           jbyteArray jKey,
+                                                           jbyteArray jValue,
+                                                           jobject jRejectRules)
+{
+    // XXX- handle RejectRules    
+    RamCloud* ramcloud = getRamCloud(env, jRamCloud);
+    JByteArrayReference key(env, jKey);
+    JByteArrayGetter value(env, jValue);
+    RejectRules rules;
+    jclass ruleClass = env->GetObjectClass(jRejectRules);
+    jfieldID fid = env->GetFieldID(ruleClass, "doesntExist", "Z");
+    rules.doesntExist = (uint8_t) env->GetBooleanField(jRejectRules, fid);
+
+    fid = env->GetFieldID(ruleClass, "exists", "Z");
+    rules.exists = (uint8_t) env->GetBooleanField(jRejectRules, fid);
+
+    fid = env->GetFieldID(ruleClass, "givenVersion", "J");
+    rules.givenVersion = env->GetLongField(jRejectRules, fid);
+
+    fid = env->GetFieldID(ruleClass, "versionLeGiven", "Z");
+    rules.versionLeGiven = (uint8_t) env->GetBooleanField(jRejectRules, fid);
+
+    fid = env->GetFieldID(ruleClass, "versionNeGiven", "Z");
+    rules.versionNeGiven = (uint8_t) env->GetBooleanField(jRejectRules, fid);
+
+    uint64_t version;
+    try {
+        ramcloud->write(jTableId,
+                key.pointer, key.length,
+                value.pointer, value.length,
+                &rules,
+                &version);
+    }
+    EXCEPTION_CATCHER(-1);
+    return static_cast<jlong> (version);
+}
+
+JNIEXPORT jlong
+JNICALL Java_edu_stanford_ramcloud_JRamCloud_writeRule(JNIEnv *env,
+        jobject jRamCloud,
+        jlong jTableId,
+        jbyteArray jKey,
+        jbyteArray jValue,
+        jobject jRejectRules) {
+    RamCloud* ramcloud = getRamCloud(env, jRamCloud);
+    JByteArrayReference key(env, jKey);
+    JByteArrayGetter value(env, jValue);
+    uint64_t version;
+    RejectRules rules = {};
+    const static jclass jc_RejectRules = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$RejectRules"));
+
+    const static jfieldID jf_doesntExist = env->GetFieldID(jc_RejectRules, "doesntExist", "Z");
+    check_null(jf_doesntExist, "doesentExist field id is null");
+    jboolean ruleBool;
+    ruleBool = env->GetBooleanField(jRejectRules, jf_doesntExist);
+    rules.doesntExist = ruleBool ? 1 : 0;
+
+    const static jfieldID jf_exists = env->GetFieldID(jc_RejectRules, "exists", "Z");
+    check_null(jf_exists, "exists field id is null");
+    ruleBool = env->GetBooleanField(jRejectRules, jf_exists);
+    rules.exists = ruleBool ? 1 : 0;
+
+    const static jfieldID jf_givenVersion = env->GetFieldID(jc_RejectRules, "givenVersion", "J");
+    check_null(jf_givenVersion, "givenVersion field id is null");
+    rules.givenVersion = env->GetLongField(jRejectRules, jf_givenVersion);
+
+    const static jfieldID jf_versionLeGiven = env->GetFieldID(jc_RejectRules, "versionLeGiven", "Z");
+    check_null(jf_versionLeGiven, "versionLeGiven field id is null");
+    ruleBool = env->GetBooleanField(jRejectRules, jf_versionLeGiven);
+    rules.versionLeGiven = ruleBool ? 1 : 0;
+
+    const static jfieldID jf_versionNeGiven = env->GetFieldID(jc_RejectRules, "versionNeGiven", "Z");
+    check_null(jf_versionNeGiven, "versionNeGiven field id is null");
+    ruleBool = env->GetBooleanField(jRejectRules, jf_versionNeGiven);
+    rules.versionNeGiven = ruleBool ? 1 : 0;
+    try {
+        ramcloud->write(jTableId,
+                key.pointer, key.length,
+                value.pointer, value.length,
+                &rules,
+                &version);
+    }
+    EXCEPTION_CATCHER(-1);
+    return static_cast<jlong> (version);
+}
+
+/*
+ * Class:     edu_stanford_ramcloud_JRamCloud_TableEnumerator
+ * Method:    init
+ * Signature: (J)V
+ */
+JNIEXPORT jlong JNICALL Java_edu_stanford_ramcloud_JRamCloud_00024TableEnumerator_init(JNIEnv *env, 
+                                                                                      jobject jTableEnumerator, 
+                                                                                      jlong jTableId)
+{
+    const static jclass cls = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$TableEnumerator"));
+    const static jfieldID fieldId = env->GetFieldID(cls, "ramCloudObjectPointer", "J");
+    RamCloud* ramcloud = reinterpret_cast<RamCloud*>(env->GetLongField(jTableEnumerator, fieldId));
+  
+    return reinterpret_cast<jlong>(new TableEnumerator(*ramcloud, jTableId));
+}
+
+/*
+ * Class:     edu_stanford_ramcloud_JRamCloud_TableEnumerator
+ * Method:    hasNext
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_edu_stanford_ramcloud_JRamCloud_00024TableEnumerator_hasNext( JNIEnv *env, 
+                                                                                              jobject jTableEnumerator)
+{
+    TableEnumerator* tableEnum = getTableEnumerator(env, jTableEnumerator);
+    return static_cast<jboolean>(tableEnum->hasNext());
+}
+
+/*
+ * Class:     edu_stanford_ramcloud_JRamCloud_TableEnumerator
+ * Method:    next
+ * Signature: ()Ledu/stanford/ramcloud/JRamCloud/Object;
+ */
+JNIEXPORT jobject JNICALL Java_edu_stanford_ramcloud_JRamCloud_00024TableEnumerator_next( JNIEnv *env, 
+                                                                                          jobject jTableEnumerator)
+{
+    TableEnumerator* tableEnum = getTableEnumerator(env, jTableEnumerator);
+
+    if(tableEnum->hasNext()) 
+    {
+        uint32_t size = 0;
+        const void* buffer = 0;
+        uint64_t version = 0;
+
+        tableEnum->next(&size, &buffer);
+        Object object(buffer, size);
+
+        jbyteArray jKey = env->NewByteArray(object.getKeyLength());
+        jbyteArray jValue = env->NewByteArray(object.getDataLength());
+        
+        JByteArrayGetter key(env, jKey);
+        JByteArrayGetter value(env, jValue);
+
+        memcpy(key.pointer, object.getKey(), object.getKeyLength());
+        memcpy(value.pointer, object.getData(), object.getDataLength());
+
+        version = object.getVersion();
+        
+        const static jclass cls = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$Object"));
+        check_null(cls, "FindClass failed");
+        const static jmethodID methodId = env->GetMethodID(cls,
+                                          "<init>",
+                                          "(L" PACKAGE_PATH "JRamCloud;[B[BJ)V");
+        check_null(methodId, "GetMethodID failed");
+        return env->NewObject(cls,
+                              methodId,
+                              jTableEnumerator,
+                              jKey,
+                              jValue,
+                              static_cast<jlong>(version));        
+    } else 
+        return NULL;
+}
+
+/*
+ * Class:     edu_stanford_ramcloud_JRamCloud
+ * Method:    multiWrite
+ * Signature: ([Ledu/stanford/ramcloud/JRamCloud/MultiWriteObject;)[Ledu/stanford/ramcloud/JRamCloud/MultiWriteRspObject;
+ */
+JNIEXPORT jobjectArray JNICALL Java_edu_stanford_ramcloud_JRamCloud_multiWrite(JNIEnv *env, jobject jRamCloud, jobjectArray jmultiWriteArray) {
+    jint requestNum = env->GetArrayLength(jmultiWriteArray);
+    RamCloud* ramcloud = getRamCloud(env, jRamCloud);
+    Tub<MultiWriteObject> objects[requestNum];
+    MultiWriteObject *requests[requestNum];
+    RejectRules rules[requestNum];
+    jbyteArray jKey[requestNum];
+    jbyteArray jValue[requestNum];
+    
+    const static jclass jc_multiWriteObject = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$MultiWriteObject"));
+    const static jclass jc_RejectRules = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$RejectRules"));
+    const static jfieldID jf_tableId = env->GetFieldID(jc_multiWriteObject, "tableId", "J");
+    const static jfieldID jf_key = env->GetFieldID(jc_multiWriteObject, "key", "[B");
+    const static jfieldID jf_value = env->GetFieldID(jc_multiWriteObject, "value", "[B");
+    const static jfieldID jf_reject_rules = env->GetFieldID(jc_multiWriteObject, "rules", "L" PACKAGE_PATH "JRamCloud$RejectRules;");
+
+    const static jfieldID jf_doesntExist = env->GetFieldID(jc_RejectRules, "doesntExist", "Z");
+    check_null(jf_doesntExist, "doesentExist field id is null");
+    const static jfieldID jf_exists = env->GetFieldID(jc_RejectRules, "exists", "Z");
+    check_null(jf_exists, "exists field id is null");
+    const static jfieldID jf_givenVersion = env->GetFieldID(jc_RejectRules, "givenVersion", "J");
+    check_null(jf_givenVersion, "givenVersion field id is null");
+    const static jfieldID jf_versionLeGiven = env->GetFieldID(jc_RejectRules, "versionLeGiven", "Z");
+    check_null(jf_versionLeGiven, "versionLeGiven field id is null");
+    const static jfieldID jf_versionNeGiven = env->GetFieldID(jc_RejectRules, "versionNeGiven", "Z");
+    check_null(jf_versionNeGiven, "versionNeGiven field id is null");
+
+    for (int i = 0; i < requestNum; i++) {
+        jobject obj = env->GetObjectArrayElement(jmultiWriteArray, i);
+        check_null(obj, "multi write GetObjectArrayElement failed");
+
+        uint64_t tableId = env->GetLongField(obj, jf_tableId);
+
+        jKey[i] = (jbyteArray)env->GetObjectField(obj, jf_key);
+        jbyte* keyData = env->GetByteArrayElements(jKey[i], NULL);
+        uint16_t keyLength = env->GetArrayLength(jKey[i]);
+
+        jValue[i] = (jbyteArray)env->GetObjectField(obj, jf_value);
+        jbyte* valueData = env->GetByteArrayElements(jValue[i], NULL);
+        uint32_t valueLength = env->GetArrayLength(jValue[i]);
+
+        jobject jRejectRules = env->GetObjectField(obj, jf_reject_rules);
+        rules[i] = {};
+
+        if (jRejectRules != NULL) {
+            jboolean ruleBool;
+
+            ruleBool = env->GetBooleanField(jRejectRules, jf_doesntExist);
+            rules[i].doesntExist = ruleBool ? 1 : 0;
+
+            ruleBool = env->GetBooleanField(jRejectRules, jf_exists);
+            rules[i].exists = ruleBool ? 1 : 0;
+
+            rules[i].givenVersion = env->GetLongField(jRejectRules, jf_givenVersion);
+
+            ruleBool = env->GetBooleanField(jRejectRules, jf_versionLeGiven);
+            rules[i].versionLeGiven = ruleBool ? 1 : 0;
+
+            ruleBool = env->GetBooleanField(jRejectRules, jf_versionNeGiven);
+            rules[i].versionNeGiven = ruleBool ? 1 : 0;
+        }
+        objects[i].construct(tableId, keyData, keyLength, valueData, valueLength, &rules[i]);
+        requests[i] = objects[i].get();
+    }
+    try {
+        ramcloud->multiWrite(requests, requestNum);
+    } EXCEPTION_CATCHER(NULL);
+ 
+    const static jclass jc_RcObject = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$MultiWriteRspObject"));
+    check_null(jc_RcObject, "FindClass failed");
+    const static jmethodID jm_init = env->GetMethodID(jc_RcObject,
+                                        "<init>",
+                                        "(L" PACKAGE_PATH "JRamCloud;IJ)V");
+
+    jobjectArray outJNIArray = env->NewObjectArray(requestNum, jc_RcObject , NULL);
+    check_null(outJNIArray, "NewObjectArray failed");
+    
+    for (int i = 0 ; i < requestNum ; i++) {
+        jobject obj = env->NewObject(jc_RcObject, jm_init, jRamCloud, objects[i]->status, objects[i]->version);
+        check_null(obj, "NewObject failed");
+        env->SetObjectArrayElement(outJNIArray, i, obj);
+        env->ReleaseByteArrayElements(jKey[i], (jbyte *)requests[i]->key, JNI_ABORT);
+        env->ReleaseByteArrayElements(jValue[i], (jbyte *)requests[i]->value, JNI_ABORT);
+        objects[i].destroy();
+    }
+    return outJNIArray;
+}
diff --git a/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/PerfMon.java b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/PerfMon.java
new file mode 100644
index 0000000..158a3c8
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/PerfMon.java
@@ -0,0 +1,747 @@
+package com.tinkerpop.blueprints.impls.ramcloud;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+// Singleton class
+public final class PerfMon {
+    private static final ThreadLocal<PerfMon> instance = new ThreadLocal<PerfMon>() {
+	@Override
+	protected PerfMon initialValue() {
+	    return new PerfMon();
+	}
+    };
+
+   public final long measureAllTimeProp = Long.valueOf(System.getProperty("benchmark.measureAll", "0"));
+   private final static Logger log = LoggerFactory.getLogger(PerfMon.class);
+
+   private static final int debug = 0;
+
+   private long read_latency_sum;
+   private long read_latency_cnt;
+   private int read_flag;
+
+   private long multiread_latency_sum;
+   private long multiread_latency_cnt;
+   private int multiread_flag;
+
+   private long multiwrite_latency_sum;
+   private long multiwrite_latency_cnt;
+   private int multiwrite_flag;
+
+   private long indexread_latency_sum;
+   private long indexread_latency_cnt;
+   private int indexread_flag;
+
+   private long write_latency_sum;
+   private long write_latency_cnt;
+
+   private int write_flag;
+
+   private long indexwrite_latency_sum;
+   private long indexwrite_latency_cnt;
+   private int indexwrite_flag;
+
+   private long serialize_latency_sum;
+   private long serialize_latency_cnt;
+   private int ser_flag;
+
+   private long indexserialize_latency_sum;
+   private long indexserialize_latency_cnt;
+   private int indexser_flag;
+
+   private long proto_serialize_latency_sum;
+   private long proto_serialize_latency_cnt;
+   private int protoser_flag;
+
+   private long deserialize_latency_sum;
+   private long deserialize_latency_cnt;
+   private int deser_flag;
+
+   private long indexdeserialize_latency_sum;
+   private long indexdeserialize_latency_cnt;
+   private int indexdeser_flag;
+
+   private long proto_deserialize_latency_sum;
+   private long proto_deserialize_latency_cnt;
+   private int protodeser_flag;
+
+   private long addsw_time;
+   private long addport_time;
+   private long addlink_time;
+   private long addport_cnt;
+   private long addflowpath_time;
+   private long addflowentry_time;
+   private long addflowentry_cnt;
+
+   private long ser_time;
+   private long indexser_time;
+   private long protoser_time;
+
+   private long deser_time;
+   private long indexdeser_time;
+   private long protodeser_time;
+
+   private long write_time;
+   private long multiwrite_time;
+   private long write_condfails;
+   private long indexwrite_time;
+   private long indexwrite_condfails;
+   private long read_time;
+   private long multiread_time;
+   private long indexread_time;
+   private long read_whole_topology_time;
+
+   public static PerfMon getInstance() {
+        return instance.get();
+    }
+   private PerfMon(){
+   }
+
+   private void clear(){
+   	read_latency_sum=0L;
+   	read_latency_cnt=0L;
+	multiread_latency_sum=0L;
+   	multiread_latency_cnt=0L;
+	multiwrite_latency_sum=0L;
+   	multiwrite_latency_cnt=0L;
+   	indexread_latency_sum=0L;
+   	indexread_latency_cnt=0L;
+	write_latency_sum=0L;
+   	write_latency_cnt=0L;
+	indexwrite_latency_sum=0L;
+   	indexwrite_latency_cnt=0L;
+   	serialize_latency_sum=0L;
+   	serialize_latency_cnt=0L;
+	indexserialize_latency_sum=0L;
+   	indexserialize_latency_cnt=0L;
+   	deserialize_latency_sum=0L;
+   	deserialize_latency_cnt=0L;
+   	indexdeserialize_latency_sum=0L;
+   	indexdeserialize_latency_cnt=0L;
+	read_flag=multiread_flag=indexread_flag=write_flag=indexwrite_flag=deser_flag=indexdeser_flag=ser_flag=indexser_flag=0;
+	addflowpath_time = addflowentry_time = addflowentry_cnt = 0;
+	write_condfails = indexwrite_condfails = 0;
+	read_whole_topology_time = 0;
+	protoser_time = protodeser_time = 0;
+	proto_deserialize_latency_cnt = proto_deserialize_latency_sum = proto_serialize_latency_cnt = proto_serialize_latency_sum = 0;
+        //log.error("flag cleared");
+   }
+
+   private long getSum(){
+       return read_latency_sum + multiread_latency_sum + indexread_latency_sum + write_latency_sum + indexwrite_latency_sum + serialize_latency_sum + indexserialize_latency_sum + deserialize_latency_sum + indexdeserialize_latency_sum;
+   }
+
+   public void addswitch_start(){
+        if(measureAllTimeProp==0)
+		return;
+
+	clear();
+	addsw_time = System.nanoTime();
+   }
+   public void addswitch_end(){
+        if(measureAllTimeProp==0)
+		return;
+
+        long delta;
+        long sum;
+
+        delta = System.nanoTime() - addsw_time;
+	sum = getSum();
+        log.error("Performance add_switch {}"
+        	+ " read {} ({})"
+        	+ " multiread {} ({})"
+        	+ " index_read {} ({})"
+        	+ " write {} ({})"
+        	+ " multiwrite {} ({})"
+        	+ " index_write {} ({})"
+        	+ " serialize {} ({})"
+        	+ " indexserialize {} ({})"
+        	+ " proto_serialize {} ({})"
+        	+ " deserialize {} ({})"
+        	+ " indexdeserialize {} ({})"
+        	+ " proto_deserialize {} ({})"
+        	+ " rwsd total {} other {} ({})"
+        	+ " writefail ({}) indexwritefail({})",
+	       delta,
+	       read_latency_sum, read_latency_cnt,
+	       multiread_latency_sum, multiread_latency_cnt,
+	       indexread_latency_sum, indexread_latency_cnt,
+	       write_latency_sum, write_latency_cnt,
+	       multiwrite_latency_sum, multiwrite_latency_cnt,
+	       indexwrite_latency_sum, indexwrite_latency_cnt,
+	       serialize_latency_sum, serialize_latency_cnt,
+	       indexserialize_latency_sum, indexserialize_latency_cnt,
+	       proto_serialize_latency_sum, proto_serialize_latency_cnt,
+	       deserialize_latency_sum, deserialize_latency_cnt,
+	       indexdeserialize_latency_sum, indexdeserialize_latency_cnt,
+	       proto_deserialize_latency_sum, proto_deserialize_latency_cnt,
+	       sum, delta - sum, (delta - sum) * 100.0 / (delta),
+	       write_condfails, indexwrite_condfails);
+   }
+   public void addport_start(){
+        if(measureAllTimeProp==0)
+		return;
+	clear();
+        addport_cnt = 0;
+	addport_time = System.nanoTime();
+   }
+   public void addport_incr(){
+        if(measureAllTimeProp==0)
+		return;
+        addport_cnt ++;
+   }
+   public void addport_end(){
+        if(measureAllTimeProp==0)
+		return;
+        long delta;
+        long sum;
+        delta = System.nanoTime() - addport_time;
+	sum = getSum();
+        log.error("Performance add_port {} ( {} ports )"
+        	+ " read {} ({})"
+        	+ " multiread {} ({})"
+        	+ " index_read {} ({})"
+        	+ " write {} ({})"
+        	+ " multiwrite {} ({})"
+        	+ " index_write {} ({})"
+        	+ " serialize {} ({})"
+        	+ " indexserialize {} ({})"
+        	+ " proto_serialize {} ({})"
+        	+ " deserialize {} ({})"
+        	+ " indexdeserialize {} ({})"
+        	+ " proto_deserialize {} ({})"
+        	+ " rwsd total {} other {} ({})"
+        	+ " writefail ({}) indexwritefail({})",
+	       delta, addport_cnt,
+	       read_latency_sum, read_latency_cnt,
+	       multiread_latency_sum, multiread_latency_cnt,
+	       indexread_latency_sum, indexread_latency_cnt,
+	       write_latency_sum, write_latency_cnt,
+	       multiwrite_latency_sum, multiwrite_latency_cnt,
+	       indexwrite_latency_sum, indexwrite_latency_cnt,
+	       serialize_latency_sum, serialize_latency_cnt,
+	       indexserialize_latency_sum, indexserialize_latency_cnt,
+	       proto_serialize_latency_sum, proto_serialize_latency_cnt,
+	       deserialize_latency_sum, deserialize_latency_cnt,
+	       indexdeserialize_latency_sum, indexdeserialize_latency_cnt,
+	       proto_deserialize_latency_sum, proto_deserialize_latency_cnt,
+	       sum, delta - sum, (delta - sum) * 100.0 / (delta),
+	       write_condfails, indexwrite_condfails);
+   }
+   public void addlink_start(){
+        if(measureAllTimeProp==0)
+		return;
+	clear();
+	addlink_time = System.nanoTime();
+   }
+   public void addlink_end(){
+        if(measureAllTimeProp==0)
+		return;
+        long delta;
+        long sum;
+        delta = System.nanoTime() - addlink_time;
+	sum = getSum();
+        log.error("Performance add_link {}"
+        	+ " read {} ({})"
+        	+ " multiread {} ({})"
+        	+ " index_read {} ({})"
+        	+ " write {} ({})"
+        	+ " multiwrite {} ({})"
+        	+ " index_write {} ({})"
+        	+ " serialize {} ({})"
+        	+ " indexserialize {} ({})"
+        	+ " proto_serialize {} ({})"
+        	+ " deserialize {} ({})"
+        	+ " indexdeserialize {} ({})"
+        	+ " proto_deserialize {} ({})"
+        	+ " rwsd total {} other {} ({})"
+        	+ " writefail ({}) indexwritefail({})",
+	       delta,
+	       read_latency_sum, read_latency_cnt,
+	       multiread_latency_sum, multiread_latency_cnt,
+	       indexread_latency_sum, indexread_latency_cnt,
+	       write_latency_sum, write_latency_cnt,
+	       multiwrite_latency_sum, multiwrite_latency_cnt,
+	       indexwrite_latency_sum, indexwrite_latency_cnt,
+	       serialize_latency_sum, serialize_latency_cnt,
+	       indexserialize_latency_sum, indexserialize_latency_cnt,
+	       proto_serialize_latency_sum, proto_serialize_latency_cnt,
+	       deserialize_latency_sum, deserialize_latency_cnt,
+	       indexdeserialize_latency_sum, indexdeserialize_latency_cnt,
+	       proto_deserialize_latency_sum, proto_deserialize_latency_cnt,
+	       sum, delta - sum, (delta - sum) * 100.0 / (delta),
+	       write_condfails, indexwrite_condfails);
+   }
+
+   public void addflowpath_start(){
+	if(measureAllTimeProp==0) return;
+	clear();
+	addflowpath_time = System.nanoTime();
+   }
+   public void addflowpath_end(){
+       if(measureAllTimeProp==0) return;
+       long delta;
+       long sum;
+       delta = System.nanoTime() - addflowpath_time;
+       sum = getSum();
+       log.error("Performance add_flowpath {}"
+        	+ " read {} ({})"
+        	+ " multiread {} ({})"
+        	+ " index_read {} ({})"
+        	+ " write {} ({})"
+        	+ " multiwrite {} ({})"
+        	+ " index_write {} ({})"
+        	+ " serialize {} ({})"
+        	+ " indexserialize {} ({})"
+        	+ " proto_serialize {} ({})"
+        	+ " deserialize {} ({})"
+        	+ " indexdeserialize {} ({})"
+        	+ " proto_deserialize {} ({})"
+        	+ " rwsd total {} other {} ({})"
+        	+ " writefail ({}) indexwritefail({})",
+	       delta,
+	       read_latency_sum, read_latency_cnt,
+	       multiread_latency_sum, multiread_latency_cnt,
+	       indexread_latency_sum, indexread_latency_cnt,
+	       write_latency_sum, write_latency_cnt,
+	       multiwrite_latency_sum, multiwrite_latency_cnt,
+	       indexwrite_latency_sum, indexwrite_latency_cnt,
+	       serialize_latency_sum, serialize_latency_cnt,
+	       indexserialize_latency_sum, indexserialize_latency_cnt,
+	       proto_serialize_latency_sum, proto_serialize_latency_cnt,
+	       deserialize_latency_sum, deserialize_latency_cnt,
+	       indexdeserialize_latency_sum, indexdeserialize_latency_cnt,
+	       proto_deserialize_latency_sum, proto_deserialize_latency_cnt,
+	       sum, delta - sum, (delta - sum) * 100.0 / (delta),
+	       write_condfails, indexwrite_condfails);
+   }
+
+   public void addflowentry_start(){
+       if(measureAllTimeProp==0) return;
+	clear();
+	if ( debug==1 )
+		log.error("addflowentry_start");
+	addflowentry_time = System.nanoTime();
+   }
+   public void addflowentry_incr(){
+       if(measureAllTimeProp==0) return;
+       addflowentry_cnt++;
+   }
+   public void addflowentry_end(){
+       if(measureAllTimeProp==0) return;
+       long delta;
+       long sum;
+       delta = System.nanoTime() - addflowentry_time;
+       sum = getSum();
+       log.error("Performance add_flowentry {} ( {} flows )"
+        	+ " read {} ({})"
+        	+ " multiread {} ({})"
+        	+ " index_read {} ({})"
+        	+ " write {} ({})"
+        	+ " multiwrite {} ({})"
+        	+ " index_write {} ({})"
+        	+ " serialize {} ({})"
+        	+ " indexserialize {} ({})"
+        	+ " proto_serialize {} ({})"
+        	+ " deserialize {} ({})"
+        	+ " indexdeserialize {} ({})"
+        	+ " proto_deserialize {} ({})"
+        	+ " rwsd total {} other {} ({})"
+        	+ " writefail ({}) indexwritefail({})",
+	       delta, addflowentry_cnt,
+	       read_latency_sum, read_latency_cnt,
+	       multiread_latency_sum, multiread_latency_cnt,
+	       indexread_latency_sum, indexread_latency_cnt,
+	       write_latency_sum, write_latency_cnt,
+	       multiwrite_latency_sum, multiwrite_latency_cnt,
+	       indexwrite_latency_sum, indexwrite_latency_cnt,
+	       serialize_latency_sum, serialize_latency_cnt,
+	       indexserialize_latency_sum, indexserialize_latency_cnt,
+	       proto_serialize_latency_sum, proto_serialize_latency_cnt,
+	       deserialize_latency_sum, deserialize_latency_cnt,
+	       indexdeserialize_latency_sum, indexdeserialize_latency_cnt,
+	       proto_deserialize_latency_sum, proto_deserialize_latency_cnt,
+	       sum, delta - sum, (delta - sum) * 100.0 / (delta),
+	       write_condfails, indexwrite_condfails);
+   }
+
+   public void read_whole_topology_start(){
+       if(measureAllTimeProp==0) return;
+	if ( debug==1 )
+	    log.error("read_whole_topology_start");
+
+	clear();
+	read_whole_topology_time = System.nanoTime();
+   }
+   public void read_whole_topology_end(){
+       if(measureAllTimeProp==0) return;
+       long delta;
+       long sum;
+       delta = System.nanoTime() - read_whole_topology_time;
+       sum = getSum();
+       log.error("Performance read_whole_topology {}"
+        	+ " read {} ({})"
+        	+ " multiread {} ({})"
+        	+ " index_read {} ({})"
+        	+ " write {} ({})"
+        	+ " multiwrite {} ({})"
+        	+ " index_write {} ({})"
+        	+ " serialize {} ({})"
+        	+ " indexserialize {} ({})"
+        	+ " proto_serialize {} ({})"
+        	+ " deserialize {} ({})"
+        	+ " indexdeserialize {} ({})"
+        	+ " proto_deserialize {} ({})"
+        	+ " rwsd total {} other {} ({})"
+        	+ " writefail ({}) indexwritefail({})",
+	       delta,
+	       read_latency_sum, read_latency_cnt,
+	       multiread_latency_sum, multiread_latency_cnt,
+	       indexread_latency_sum, indexread_latency_cnt,
+	       write_latency_sum, write_latency_cnt,
+	       multiwrite_latency_sum, multiwrite_latency_cnt,
+	       indexwrite_latency_sum, indexwrite_latency_cnt,
+	       serialize_latency_sum, serialize_latency_cnt,
+	       indexserialize_latency_sum, indexserialize_latency_cnt,
+	       proto_serialize_latency_sum, proto_serialize_latency_cnt,
+	       deserialize_latency_sum, deserialize_latency_cnt,
+	       indexdeserialize_latency_sum, indexdeserialize_latency_cnt,
+	       proto_deserialize_latency_sum, proto_deserialize_latency_cnt,
+	       sum, delta - sum, (delta - sum) * 100.0 / (delta),
+	       write_condfails, indexwrite_condfails);
+   }
+
+
+   public void read_start(String key){
+        if(measureAllTimeProp==0)
+		return;
+	if ( debug==1 )
+            log.error("read_start {}", key);
+        if ( read_flag != 0){
+            log.error("read_start called twice");
+	}
+	read_flag = 1;
+
+	read_time=System.nanoTime();
+   }
+   public void read_end(String key){
+        if(measureAllTimeProp==0)
+		return;
+	if ( debug==1 )
+            log.error("read_end {}", key);
+
+	read_latency_sum += System.nanoTime() - read_time;
+	read_latency_cnt ++;
+
+        if ( read_flag != 1){
+            log.error("read_end called before read_start");
+	}
+	read_flag = 0;
+   }
+   public void multiread_start(String key){
+        if(measureAllTimeProp==0)
+		return;
+	if ( debug==1 )
+            log.error("multiread_start {}", key);
+	if ( multiread_flag != 0){
+            log.error("multiread_start called twice");
+	}
+	multiread_flag = 1;
+
+	multiread_time=System.nanoTime();
+   }
+   public void multiread_end(String key){
+        if(measureAllTimeProp==0)
+		return;
+
+	multiread_latency_sum += System.nanoTime() - multiread_time;
+        multiread_latency_cnt ++;
+
+	if ( debug==1 )
+            log.error("multiread_end {}", key);
+        if ( multiread_flag != 1){
+            log.error("multiread_end called before multiread_start");
+	}
+	multiread_flag = 0;
+   }
+   public void multiwrite_start(String key){
+       if(measureAllTimeProp==0)
+		return;
+	if ( debug==1 )
+           log.error("multiwrite_start {}", key);
+	if ( multiwrite_flag != 0){
+           log.error("multiwrite_start called twice");
+	}
+	multiwrite_flag = 1;
+
+	multiwrite_time=System.nanoTime();
+  }
+  public void multiwrite_end(String key){
+       if(measureAllTimeProp==0)
+		return;
+
+	multiwrite_latency_sum += System.nanoTime() - multiwrite_time;
+       multiwrite_latency_cnt ++;
+
+	if ( debug==1 )
+           log.error("multiwrite_end {}", key);
+       if ( multiwrite_flag != 1){
+           log.error("multiwrite_end called before multiwrite_start");
+	}
+	multiwrite_flag = 0;
+  }
+   public void indexread_start(String key){
+        if(measureAllTimeProp==0)
+		return;
+	if ( debug==1 )
+            log.error("indexread_start {}", key);
+        if ( indexread_flag != 0){
+            log.error("indexread_start called twice");
+	}
+	indexread_flag = 1;
+
+    	indexread_time=System.nanoTime();
+   }
+   public void indexread_end(String key){
+        if(measureAllTimeProp==0)
+		return;
+
+	indexread_latency_sum += System.nanoTime() - indexread_time;
+        indexread_latency_cnt ++;
+
+	if ( debug==1 )
+            log.error("indexread_end {}", key);
+        if ( indexread_flag != 1){
+            log.error("indexread_end called before indexread_start");
+	}
+	indexread_flag = 0;
+   }
+   public void write_start(String key){
+        if(measureAllTimeProp==0)
+		return;
+	if ( debug==1 )
+            log.error("write start_{}", key);
+        if ( write_flag != 0){
+            log.error("write_start called twice");
+	}
+	write_flag = 1;
+
+	write_time = System.nanoTime();
+   }
+   public void write_end(String key){
+        if(measureAllTimeProp==0)
+		return;
+
+        write_latency_sum += System.nanoTime() - write_time;
+        write_latency_cnt ++;
+
+        if ( debug==1 )
+            log.error("write_end {}", key);
+        if ( write_flag != 1){
+            log.error("write_end called before write_start");
+	}
+	write_flag = 0;
+   }
+   public void write_condfail(String key){
+       if(measureAllTimeProp==0)
+		return;
+       write_condfails++;
+   }
+
+   public void indexwrite_start(String key){
+        if(measureAllTimeProp==0)
+		return;
+	if ( debug==1 )
+            log.error("index_write start {}", key);
+        if ( indexwrite_flag != 0){
+            log.error("indexwrite_start called twice");
+	}
+	indexwrite_flag = 1;
+	indexwrite_time = System.nanoTime();
+   }
+   public void indexwrite_end(String key){
+        if(measureAllTimeProp==0)
+		return;
+
+	indexwrite_latency_sum += System.nanoTime() - indexwrite_time;
+        indexwrite_latency_cnt ++;
+
+        if ( debug==1 )
+            log.error("indexwrite_end {}", key);
+        if ( indexwrite_flag != 1){
+            log.error("indexwrite_end called before indexwrite_start");
+	}
+	indexwrite_flag = 0;
+   }
+   public void indexwrite_condfail(String key){
+       if(measureAllTimeProp==0)
+		return;
+       indexwrite_condfails++;
+   }
+
+   public void ser_start(String key){
+        if(measureAllTimeProp==0)
+		return;
+	if ( debug==1 )
+            log.error("ser_start {}", key);
+        if ( ser_flag != 0 ){
+            	log.error("ser_start called twice");
+	}
+	ser_flag = 1;
+
+	ser_time = System.nanoTime();
+   }
+   public void ser_end(String key){
+        if(measureAllTimeProp==0)
+		return;
+
+	serialize_latency_sum += System.nanoTime() - ser_time;
+        serialize_latency_cnt ++;
+
+        if ( debug==1 )
+            log.error("ser_end {}", key);
+        if ( ser_flag != 1 ){
+            	log.error("ser_end called before ser_start");
+	}
+	ser_flag = 0;
+   }
+
+   public void indexser_start(String key){
+        if(measureAllTimeProp==0)
+		return;
+
+	indexser_time = System.nanoTime();
+
+	if ( debug==1 )
+            log.error("indexser_start {}", key);
+        if ( indexser_flag != 0 ){
+            	log.error("indexser_start called twice");
+	}
+	indexser_flag = 1;
+   }
+   public void indexser_end(String key){
+        if(measureAllTimeProp==0)
+		return;
+
+	indexserialize_latency_sum += System.nanoTime() - indexser_time;
+        indexserialize_latency_cnt ++;
+
+        if ( debug==1 )
+            log.error("indexser_end {}", key);
+        if ( indexser_flag != 1 ){
+            	log.error("indexser_end called before indexser_start");
+	}
+	indexser_flag = 0;
+
+   }
+
+   public void deser_start(String key){
+        if(measureAllTimeProp==0)
+		return;
+	if ( debug==1 )
+            log.error("deser_start {}", key);
+        if ( deser_flag != 0){
+            log.error("deser_start called twice");
+	}
+	deser_flag = 1;
+
+	deser_time = System.nanoTime();
+   }
+   public void deser_end(String key){
+        if(measureAllTimeProp==0)
+		return;
+
+        deserialize_latency_sum += System.nanoTime() - deser_time;
+        deserialize_latency_cnt ++;
+
+        if ( debug==1 )
+            log.error("deser_end {}", key);
+        if ( deser_flag != 1){
+            log.error("deser_end called before deser_start");
+	}
+	deser_flag = 0;
+   }
+
+   public void indexdeser_start(String key){
+        if(measureAllTimeProp==0)
+		return;
+	if ( debug==1 )
+            log.error("indexdeser_start {}", key);
+        if ( indexdeser_flag != 0){
+            log.error("indexdeser_start called twice");
+	}
+	indexdeser_flag = 1;
+
+	indexdeser_time = System.nanoTime();
+   }
+   public void indexdeser_end(String key){
+        if(measureAllTimeProp==0)
+		return;
+
+        indexdeserialize_latency_sum += System.nanoTime() - indexdeser_time;
+        indexdeserialize_latency_cnt ++;
+
+        if ( debug==1 )
+            log.error("indexdeser_end {}", key);
+        if ( indexdeser_flag != 1){
+            log.error("indexdeser_end called before indexdeser_start");
+	}
+	indexdeser_flag = 0;
+   }
+
+   public void protoser_start(String key){
+       if(measureAllTimeProp==0)
+	   return;
+
+       if ( debug==1 )
+	   log.error("protoser_start {}", key);
+       if ( protoser_flag != 0){
+	   log.error("protoser_start called twice");
+       }
+       protoser_flag = 1;
+
+       protoser_time = System.nanoTime();
+   }
+   public void protoser_end(String key){
+       if(measureAllTimeProp==0)
+	   return;
+
+       proto_serialize_latency_sum += System.nanoTime() - protoser_time;
+       proto_serialize_latency_cnt ++;
+
+       if ( debug==1 )
+	   log.error("protoser_end {}", key);
+       if ( protoser_flag != 1){
+	   log.error("protoser_end called before protoser_start");
+       }
+       protoser_flag = 0;
+   }
+   public void protodeser_start(String key){
+       if(measureAllTimeProp==0)
+	   return;
+       if ( debug==1 )
+	   log.error("protodeser_start {}", key);
+       if ( protodeser_flag != 0){
+	   log.error("protoser_start called twice");
+       }
+       protodeser_flag = 1;
+
+       protodeser_time = System.nanoTime();
+   }
+   public void protodeser_end(String key){
+       if(measureAllTimeProp==0)
+	   return;
+
+       proto_deserialize_latency_sum += System.nanoTime() - protodeser_time;
+       proto_deserialize_latency_cnt ++;
+
+       if ( debug==1 )
+	   log.error("protodeser_end {}", key);
+       if ( protodeser_flag != 1){
+	   log.error("protodeser_end called before protodeser_start");
+       }
+       protodeser_flag = 0;
+   }
+
+}
diff --git a/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/PerfMon.java.hashversion b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/PerfMon.java.hashversion
new file mode 100644
index 0000000..9847cbd
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/PerfMon.java.hashversion
@@ -0,0 +1,290 @@
+package com.tinkerpop.blueprints.impls.ramcloud;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import sun.reflect.Reflection;
+
+
+public final class PerfMon {
+   private static final PerfMon instance = new PerfMon();
+   public final long measureAllTimeProp = Long.valueOf(System.getProperty("benchmark.measureAll", "0"));
+   private final static Logger log = LoggerFactory.getLogger(PerfMon.class);
+
+   private static final int debug = 0;
+
+   private static long read_latency_sum;
+   private static long read_latency_cnt;
+   private static int read_flag;
+
+   private static long write_latency_sum;
+   private static long write_latency_cnt;
+   private static int write_flag;
+
+   private static long serialize_latency_sum;
+   private static long serialize_latency_cnt;
+   private static HashMap<String, Long> ser_flag = new HashMap<String, Long>();
+   //private static int ser_flag;
+
+   private static long deserialize_latency_sum;
+   private static long deserialize_latency_cnt;
+   private static int deser_flag;
+
+   private static long addsw_time;
+   private static long addport_time;
+   private static long addlink_time;
+   private static long addport_cnt;
+   private static HashMap<String, Long> ser_time = new HashMap<String, Long>();
+   private static HashMap<String, Long> deser_time = new HashMap<String, Long>();
+   private static HashMap<String, Long> write_time = new HashMap<String, Long>();
+   private static HashMap<String, Long> read_time = new HashMap<String, Long>();
+
+   public static PerfMon getInstance() {
+        return instance;
+    }
+   private PerfMon(){
+   }
+
+   private void clear(){
+        if(! Thread.currentThread().getName().equals("main")){
+		return;
+        }
+   	read_latency_sum=0L;
+   	read_latency_cnt=0L;
+   	write_latency_sum=0L;
+   	write_latency_cnt=0L;
+   	serialize_latency_sum=0L;
+   	serialize_latency_cnt=0L;
+   	deserialize_latency_sum=0L;
+   	deserialize_latency_cnt=0L;
+	read_flag=write_flag=deser_flag=0;
+        for (Iterator<Map.Entry<String, Long>> it = ser_flag.entrySet().iterator(); it.hasNext(); ) {
+            Map.Entry<String, Long> entry = it.next();
+	    entry.setValue(0L);
+        }
+        //log.error("flag cleared");
+   }
+   public void addswitch_start(){
+        if(measureAllTimeProp==0)
+		return;
+
+        if(! Thread.currentThread().getName().equals("main")){
+		return;
+        }
+	clear();
+	addsw_time = System.nanoTime();
+   }
+   public void addswitch_end(){
+        if(measureAllTimeProp==0)
+		return;
+
+        long delta;
+        long sum;
+
+        if(! Thread.currentThread().getName().equals("main")){
+		return;
+        }
+        delta = System.nanoTime() - addsw_time;
+        sum = read_latency_sum + write_latency_sum + serialize_latency_sum +  deserialize_latency_sum;
+        log.error("Performance add_switch {} read {} ({}) write {} ({}) serialize {} ({}) deserialize {} ({}) rwsd total {} other {} ({})", 
+	delta, read_latency_sum, read_latency_cnt, write_latency_sum, write_latency_cnt, serialize_latency_sum, serialize_latency_cnt, deserialize_latency_sum, deserialize_latency_cnt, sum, delta-sum, ((float)(delta-sum))*100.0/((float) delta));
+   }
+   public void addport_start(){
+        if(measureAllTimeProp==0)
+		return;
+        if(! Thread.currentThread().getName().equals("main")){
+		return;
+        }
+	clear();
+        addport_cnt = 0;
+	addport_time = System.nanoTime();
+   }
+   public void addport_incr(){
+        if(measureAllTimeProp==0)
+		return;
+        if(! Thread.currentThread().getName().equals("main")){
+		return;
+        }
+	clear();
+       addport_cnt ++;
+   }
+   public void addport_end(){
+        if(measureAllTimeProp==0)
+		return;
+        long delta;
+        long sum;
+        if(! Thread.currentThread().getName().equals("main")){
+		return;
+        }
+        delta = System.nanoTime() - addport_time;
+        sum = read_latency_sum + write_latency_sum + serialize_latency_sum +  deserialize_latency_sum;
+        log.error("Performance add_port {} ( {} ports ) read {} ({}) write {} ({}) serialize {} ({}) deserialize {} ({}) rwsd total {} other {} ({})", 
+	delta, addport_cnt, read_latency_sum, read_latency_cnt, write_latency_sum, write_latency_cnt, serialize_latency_sum, serialize_latency_cnt, deserialize_latency_sum, deserialize_latency_cnt, sum, delta-sum, ((float)(delta-sum))*100.0/((float) delta));
+   }
+   public void addlink_start(){
+        if(measureAllTimeProp==0)
+		return;
+        if(! Thread.currentThread().getName().equals("main")){
+		return;
+        }
+	clear();
+	addlink_time = System.nanoTime();
+   }
+   public void addlink_end(){
+        if(measureAllTimeProp==0)
+		return;
+        long delta;
+        long sum;
+        if(! Thread.currentThread().getName().equals("main")){
+		return;
+        }
+        delta = System.nanoTime() - addlink_time;
+        sum = read_latency_sum + write_latency_sum + serialize_latency_sum +  deserialize_latency_sum;
+        log.error("Performance add_link {} read {} ({}) write {} ({}) serialize {} ({}) deserialize {} ({}) rwsd total {} other {} ({})", 
+	delta, read_latency_sum, read_latency_cnt, write_latency_sum, write_latency_cnt, serialize_latency_sum, serialize_latency_cnt, deserialize_latency_sum, deserialize_latency_cnt, sum, delta-sum, ((float)(delta-sum))*100.0/((float) delta));
+   }
+
+   public void read_start(String key){
+        if(measureAllTimeProp==0)
+		return;
+        if(! Thread.currentThread().getName().equals("main")){
+		return;
+        } 
+	if ( debug==1 )
+            log.error("read start {}", key);
+	read_time.put(key, System.nanoTime());
+	//read_time = System.nanoTime();
+        if ( read_flag != 0){
+            log.error("read is already started");
+	}
+	read_flag = 1;
+   }
+   public void read_end(String key){
+        if(measureAllTimeProp==0)
+		return;
+        long delta;
+        if(! Thread.currentThread().getName().equals("main")){
+		return;
+        }
+        //read_latency_sum += System.nanoTime() - read_time;
+	if ( debug==1 )
+            log.error("read end {}", key);
+        delta = System.nanoTime() - read_time.get(key);
+        read_latency_sum += delta;
+        read_latency_cnt ++;
+        if ( read_flag != 1){
+            log.error("read is not started");
+	}
+	read_flag = 0;
+   }
+   public void write_start(String key){
+        if(measureAllTimeProp==0)
+		return;
+        if(! Thread.currentThread().getName().equals("main")){
+		return;
+        }
+	if ( debug==1 )
+            log.error("write start {}", key);
+	write_time.put(key, System.nanoTime());
+	//write_time = System.nanoTime();
+        if ( write_flag != 0){
+            log.error("write is already started");
+	}
+	write_flag = 1;
+   }
+   public void write_end(String key){
+        if(measureAllTimeProp==0)
+		return;
+        if(! Thread.currentThread().getName().equals("main")){
+		return;
+        }
+	if ( debug==1 )
+            log.error("write end {}", key);
+        write_latency_sum += (System.nanoTime() - write_time.get(key));
+        //write_latency_sum += System.nanoTime() - write_time;
+        write_latency_cnt ++;
+        if ( write_flag != 1){
+            log.error("write is not started");
+	}
+	write_flag = 0;
+   }
+   public void ser_add(long time){
+        if(measureAllTimeProp==0)
+		return;
+        if(! Thread.currentThread().getName().equals("main")){
+		return;
+        }
+        serialize_latency_sum += time;
+        serialize_latency_cnt ++;
+   }
+   public void ser_start(String key){
+        if(measureAllTimeProp==0)
+		return;
+        if(! Thread.currentThread().getName().equals("main")){
+		return;
+        }
+	//ser_time = System.nanoTime();
+	if ( debug==1 )
+            log.error("ser start {}", key);
+	ser_time.put(key, System.nanoTime());
+//        log.error("ser {} start at {} flag {}", key, ser_time, ser_flag);
+        if ( ser_flag.containsKey(key) ){
+        	if ( ser_flag.get(key) != 0L){
+            		log.error("ser {} sarted but has been already started", key);
+		}
+	}
+	ser_flag.put(key, 1L);
+   }
+   public void ser_end(String key){
+        if(measureAllTimeProp==0)
+		return;
+        if(! Thread.currentThread().getName().equals("main")){
+		return;
+        }
+	if ( debug==1 )
+            log.error("ser end {}", key);
+        //serialize_latency_sum += System.nanoTime() - ser_time;
+        serialize_latency_sum += (System.nanoTime() - ser_time.get(key));
+        serialize_latency_cnt ++;
+ //       log.error("ser {} end at {} flag {}", key, ser_time, ser_flag);
+        if ( ser_flag.containsKey(key) ){
+        	if ( ser_flag.get(key) != 1L){
+            		log.error("ser {} ended but hasn't started", key);
+		}
+	}
+	ser_flag.put(key, 0L);
+   }
+   public void deser_start(String key){
+        if(measureAllTimeProp==0)
+		return;
+        if(! Thread.currentThread().getName().equals("main")){
+		return;
+        }
+	if ( debug==1 )
+            log.error("deser start {}", key);
+	deser_time.put(key, System.nanoTime());
+	//deser_time = System.nanoTime();
+        if ( deser_flag != 0){
+            log.error("deser is already started");
+	}
+	deser_flag = 1;
+   }
+   public void deser_end(String key){
+        if(measureAllTimeProp==0)
+		return;
+        if(! Thread.currentThread().getName().equals("main")){
+		return;
+        }
+	if ( debug==1 )
+            log.error("deser end {}", key);
+        //deserialize_latency_sum += System.nanoTime() - deser_time;
+        deserialize_latency_sum += System.nanoTime() - deser_time.get(key);
+        deserialize_latency_cnt ++;
+        if ( deser_flag != 1){
+            log.error("deser is not started");
+	}
+	deser_flag = 0;
+   }
+}
diff --git a/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudEdge.java b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudEdge.java
new file mode 100644
index 0000000..c0346c3
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudEdge.java
@@ -0,0 +1,237 @@
+/* Copyright (c) 2013 Stanford University
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package com.tinkerpop.blueprints.impls.ramcloud;
+
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.jersey.core.util.Base64;
+import com.tinkerpop.blueprints.Direction;
+import com.tinkerpop.blueprints.Edge;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.util.ExceptionFactory;
+import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
+import edu.stanford.ramcloud.JRamCloud;
+
+public class RamCloudEdge extends RamCloudElement implements Edge {
+
+    private final static Logger log = LoggerFactory.getLogger(RamCloudGraph.class);
+    private RamCloudVertex outVertex;
+    private RamCloudVertex inVertex;
+    private String label;
+    private byte[] rcKey;
+    private RamCloudGraph graph;
+
+    public RamCloudEdge(RamCloudVertex outVertex, RamCloudVertex inVertex, String label, RamCloudGraph graph) {
+	super(edgeToRcKey(outVertex, inVertex, label), graph.edgePropTableId, graph);
+
+	this.outVertex = outVertex;
+	this.inVertex = inVertex;
+	this.label = label;
+	this.rcKey = edgeToRcKey(outVertex, inVertex, label);
+	this.graph = graph;
+    }
+
+    public RamCloudEdge(byte[] rcKey, RamCloudGraph graph) {
+	super(rcKey, graph.edgePropTableId, graph);
+
+	ByteBuffer edgeId = ByteBuffer.wrap(rcKey).order(ByteOrder.LITTLE_ENDIAN);
+	outVertex = new RamCloudVertex(edgeId.getLong(), graph);
+	inVertex = new RamCloudVertex(edgeId.getLong(), graph);
+	label = new String(rcKey, 16, rcKey.length - 16);
+
+	this.rcKey = rcKey;
+	this.graph = graph;
+    }
+
+    private static byte[] edgeToRcKey(RamCloudVertex outVertex, RamCloudVertex inVertex, String label) {
+	return ByteBuffer.allocate(16 + label.length()).order(ByteOrder.LITTLE_ENDIAN).putLong((Long) outVertex.getId()).putLong((Long) inVertex.getId()).put(label.getBytes()).array();
+    }
+
+    @Override
+    public Vertex getVertex(Direction direction) throws IllegalArgumentException {
+	if (direction.equals(Direction.OUT)) {
+	    return outVertex;
+	} else if (direction.equals(Direction.IN)) {
+	    return inVertex;
+	} else {
+	    throw ExceptionFactory.bothIsNotSupported();
+	}
+    }
+
+    @Override
+    public String getLabel() {
+	return label;
+    }
+
+    public boolean isLoop() {
+	return outVertex.equals(inVertex);
+    }
+
+    public Vertex getNeighbor(Vertex vertex) {
+	if (outVertex.equals(vertex)) {
+	    return inVertex;
+	} else if (inVertex.equals(vertex)) {
+	    return outVertex;
+	} else {
+	    return null;
+	}
+    }
+
+    @Override
+    public void remove() {
+	if (isLoop()) {
+	    outVertex.removeEdgeFromAdjList(this);
+	} else {
+	    outVertex.removeEdgeFromAdjList(this);
+	    inVertex.removeEdgeFromAdjList(this);
+	}
+
+	super.remove();
+    }
+
+    void removeProperties() {
+	super.remove();
+    }
+
+    @Override
+    public Object getId() {
+	return new String(Base64.encode(rcKey));
+    }
+
+    public boolean exists() {
+	boolean edgePropTableEntryExists;
+	boolean outVertexEntryExists;
+	boolean inVertexEntryExists;
+
+	PerfMon pm = PerfMon.getInstance();
+	try {
+	    JRamCloud edgeTable = graph.getRcClient();
+	    pm.read_start("RamCloudEdge exists()");
+	    edgeTable.read(graph.edgePropTableId, rcKey);
+	    pm.read_end("RamCloudEdge exists()");
+	    edgePropTableEntryExists = true;
+	} catch (Exception e) {
+	    pm.read_end("RamCloudEdge exists()");
+	    // Edge property table entry does not exist
+	    edgePropTableEntryExists = false;
+	}
+
+	outVertexEntryExists = outVertex.getEdgeSet().contains(this);
+
+	if (!outVertex.equals(inVertex)) {
+	    inVertexEntryExists = inVertex.getEdgeSet().contains(this);
+	} else {
+	    inVertexEntryExists = outVertexEntryExists;
+	}
+
+	if (edgePropTableEntryExists && outVertexEntryExists && inVertexEntryExists) {
+	    return true;
+	} else if (!edgePropTableEntryExists && !outVertexEntryExists && !inVertexEntryExists) {
+	    return false;
+	} else {
+	    log.warn("{}: Detected RamCloudGraph inconsistency: edgePropTableEntryExists={}, outVertexEntryExists={}, inVertexEntryExists={}.", this, edgePropTableEntryExists, outVertexEntryExists, inVertexEntryExists);
+	    return true;
+	}
+    }
+
+    public void create() throws Exception {
+	// TODO: Existence check costs extra (presently 3 reads), could use option to turn on/off
+	if (!exists()) {
+		PerfMon pm = PerfMon.getInstance();
+		// create edge property table
+		JRamCloud edgeTable = graph.getRcClient();
+	        pm.write_start("RamCloudEdge create()");
+		edgeTable.write(graph.edgePropTableId, rcKey, ByteBuffer.allocate(0).array());
+	        pm.write_end("RamCloudEdge create()");
+
+		boolean addSucc = outVertex.addEdgeToAdjList(this);
+		if ( !addSucc ) {
+		    edgeTable.remove(graph.edgePropTableId, rcKey);
+		    throw ExceptionFactory.edgeWithIdAlreadyExist(rcKey);
+		}
+		if (!isLoop()) {
+		    addSucc = inVertex.addEdgeToAdjList(this);
+		    if ( !addSucc ) {
+			edgeTable.remove(graph.edgePropTableId, rcKey);
+			outVertex.removeEdgeFromAdjList(this);
+			throw ExceptionFactory.edgeWithIdAlreadyExist(rcKey);
+		    }
+		}
+	} else {
+	    throw ExceptionFactory.edgeWithIdAlreadyExist(rcKey);
+	}
+    }
+
+    public static boolean isValidEdgeId(byte[] id) {
+	if (id == null) {
+	    return false;
+	}
+	if (id.length == 0) {
+	    return false;
+	}
+
+	ByteBuffer edgeId = ByteBuffer.wrap(id);
+	try {
+	    edgeId.getLong();
+	} catch (BufferUnderflowException e) {
+	    return false;
+	}
+
+	try {
+	    edgeId.getLong();
+	} catch (BufferUnderflowException e) {
+	    return false;
+	}
+
+	if (edgeId.remaining() == 0) {
+	    return false;
+	}
+
+	return true;
+    }
+
+    @Override
+    public int hashCode() {
+	return Arrays.hashCode(rcKey);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+	if (this == obj) {
+	    return true;
+	}
+	if (obj == null) {
+	    return false;
+	}
+	if (getClass() != obj.getClass()) {
+	    return false;
+	}
+	RamCloudEdge other = (RamCloudEdge) obj;
+	return Arrays.equals(rcKey, other.rcKey);
+    }
+
+    @Override
+    public String toString() {
+	return "RamCloudEdge [outVertex=" + outVertex + ", inVertex=" + inVertex
+		+ ", label=" + label + "]";
+    }
+}
diff --git a/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudElement.java b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudElement.java
new file mode 100644
index 0000000..f1183c5
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudElement.java
@@ -0,0 +1,315 @@
+/* Copyright (c) 2013 Stanford University
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package com.tinkerpop.blueprints.impls.ramcloud;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.io.ByteBufferInput;
+import com.esotericsoftware.kryo.io.Output;
+import com.tinkerpop.blueprints.Edge;
+import com.tinkerpop.blueprints.Element;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.util.ExceptionFactory;
+import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
+
+import edu.stanford.ramcloud.JRamCloud;
+
+public class RamCloudElement implements Element, Serializable {
+
+    private final static Logger log = LoggerFactory.getLogger(RamCloudGraph.class);
+    private byte[] rcPropTableKey;
+    private long rcPropTableId;
+    private RamCloudGraph graph;
+
+    private static final ThreadLocal<Kryo> kryo = new ThreadLocal<Kryo>() {
+        @Override
+        protected Kryo initialValue() {
+                 Kryo kryo = new Kryo();
+                 kryo.setRegistrationRequired(true);
+                 kryo.register(String.class);
+                 kryo.register(Long.class);
+                 kryo.register(Integer.class);
+                 kryo.register(Short.class);
+                 kryo.register(Byte.class);
+                 kryo.register(TreeMap.class);
+                 kryo.register(ArrayList.class);
+                 kryo.setReferences(false);
+                 return kryo;
+        }
+    };
+
+    public RamCloudElement() {
+    }
+
+    public RamCloudElement(byte[] rcPropTableKey, long rcPropTableId, RamCloudGraph graph) {
+	this.rcPropTableKey = rcPropTableKey;
+	this.rcPropTableId = rcPropTableId;
+	this.graph = graph;
+    }
+
+    protected Map<String, Object> getPropertyMap() {
+	JRamCloud.Object propTableEntry;
+
+	PerfMon pm = PerfMon.getInstance();
+	try {
+	    JRamCloud vertTable = graph.getRcClient();
+	    pm.read_start("RamCloudElement getPropertyMap()");
+	    propTableEntry = vertTable.read(rcPropTableId, rcPropTableKey);
+	    pm.read_end("RamCloudElement getPropertyMap()");
+	    if (propTableEntry.value.length > 1024 * 1024 * 0.9) {
+		log.warn("Element[id={}] property map size is near 1MB limit!", new String(rcPropTableKey));
+	    }
+	} catch (Exception e) {
+	    pm.read_end("RamCloudElement getPropertyMap()");
+	    log.warn("Element does not have a property table entry!");
+	    return null;
+	}
+
+	return convertRcBytesToPropertyMap(propTableEntry.value);
+    }
+
+    public static Map<String, Object> convertRcBytesToPropertyMapEx(byte[] byteArray) {
+	if (byteArray == null) {
+	    log.warn("Got a null byteArray argument");
+	    return null;
+	} else if (byteArray.length != 0) {
+	    PerfMon pm = PerfMon.getInstance();
+	    pm.deser_start("RamCloudElement convertRcBytesToPropertyMapEx()");
+	    ByteBufferInput input = new ByteBufferInput(byteArray);
+	    TreeMap map = kryo.get().readObject(input, TreeMap.class);
+	    pm.deser_end("RamCloudElement convertRcBytesToPropertyMapEx()");
+	    return map;
+	} else {
+	    return new TreeMap<String, Object>();
+	}
+    }
+
+    public Map<String, Object> convertRcBytesToPropertyMap(byte[] byteArray) {
+	if (byteArray == null) {
+	    log.warn("Got a null byteArray argument");
+	    return null;
+	} else if (byteArray.length != 0) {
+	    PerfMon pm = PerfMon.getInstance();
+	    long startTime = 0;
+	    if(RamCloudGraph.measureSerializeTimeProp == 1) {
+		startTime = System.nanoTime();
+	    }
+	    pm.deser_start("RamCloudElement convertRcBytesToPropertyMap()");
+	    ByteBufferInput input = new ByteBufferInput(byteArray);
+	    TreeMap map = kryo.get().readObject(input, TreeMap.class);
+	    pm.deser_end("RamCloudElement convertRcBytesToPropertyMap()");
+	    if(RamCloudGraph.measureSerializeTimeProp == 1) {
+            	long endTime = System.nanoTime();
+            	log.error("Performance element kryo deserialization key {} {} size {}", this, endTime - startTime, byteArray.length);
+	    }
+	    return map;
+	} else {
+	    return new TreeMap<String, Object>();
+	}
+    }
+
+    private void setPropertyMap(Map<String, Object> map) {
+	byte[] rcValue;
+	PerfMon pm = PerfMon.getInstance();
+
+	long startKryoTime = 0;
+	if(RamCloudGraph.measureSerializeTimeProp == 1) {
+	    startKryoTime = System.nanoTime();
+	}
+	pm.ser_start("RamCloudElement setPropertyMap()");
+	byte[] rcTemp = new byte[1024*1024];
+	Output output = new Output(rcTemp);
+	kryo.get().writeObject(output, map);
+	long midKryoTime = 0;
+	if(RamCloudGraph.measureSerializeTimeProp == 1) {
+	    midKryoTime = System.nanoTime();
+	}
+	rcValue = output.toBytes();
+	pm.ser_end("RamCloudElement setPropertyMap()");
+	if(RamCloudGraph.measureSerializeTimeProp == 1) {
+        	long endKryoTime = System.nanoTime();
+        	log.error("Performance element kryo serialization key {} mid {}, total {}, size {}", this, midKryoTime - startKryoTime, endKryoTime - startKryoTime, rcValue.length);
+	}
+
+	long startTime = 0;
+	JRamCloud vertTable = graph.getRcClient();
+	if (graph.measureRcTimeProp == 1) {
+	    startTime = System.nanoTime();
+	}
+	pm.write_start("RamCloudElement setPropertyMap()");
+	vertTable.write(rcPropTableId, rcPropTableKey, rcValue);
+	pm.write_end("RamCloudElement setPropertyMap()");
+	if (graph.measureRcTimeProp == 1) {
+	    long endTime = System.nanoTime();
+	    log.error("Performance setPropertyMap write time key {} {}", this, endTime - startTime);
+	}
+    }
+
+    @Override
+    public <T> T getProperty(String key) {
+	Map<String, Object> map = getPropertyMap();
+	return (T) map.get(key);
+    }
+
+    @Override
+    public Set<String> getPropertyKeys() {
+	Map<String, Object> map = getPropertyMap();
+	return map.keySet();
+    }
+
+    public Map<String, Object> getProperties() {
+	return getPropertyMap();
+    }
+    public void setProperties(Map<String, Object> properties) {
+        Map<String, Object> map = getPropertyMap();
+        Map<String, Object> oldValueMap = new HashMap<String, Object>(map.size());
+        for (Map.Entry<String, Object> property : properties.entrySet()) {
+            String key = property.getKey();
+            if (key == null) {
+                throw ExceptionFactory.propertyKeyCanNotBeNull();
+            }
+
+            if (key.equals("")) {
+                throw ExceptionFactory.propertyKeyCanNotBeEmpty();
+            }
+
+            if (key.equals("id")) {
+                throw ExceptionFactory.propertyKeyIdIsReserved();
+            }
+
+            if (this instanceof RamCloudEdge && key.equals("label")) {
+                throw ExceptionFactory.propertyKeyLabelIsReservedForEdges();
+            }
+            Object value = property.getValue();
+            if (value == null) {
+                throw ExceptionFactory.propertyValueCanNotBeNull();
+            }
+
+            oldValueMap.put(key, map.put(key, value));
+
+        }
+        setPropertyMap(map);
+
+        // TODO use multi-write
+        for (Map.Entry<String, Object> oldProperty : oldValueMap.entrySet()) {
+            String key = oldProperty.getKey();
+            Object oldValue = oldProperty.getValue();
+            Object value = map.get(key);
+            if (this instanceof RamCloudVertex) {
+                RamCloudKeyIndex keyIndex = new RamCloudKeyIndex(graph.kidxVertTableId, key, value, graph, Vertex.class);
+                keyIndex.autoUpdate(key, value, oldValue, this);
+            } else {
+                RamCloudKeyIndex keyIndex = new RamCloudKeyIndex(graph.kidxVertTableId, key, value, graph, Edge.class);
+                keyIndex.autoUpdate(key, value, oldValue, this);
+            }
+        }
+    }
+
+    @Override
+    public void setProperty(String key, Object value) {
+	Object oldValue;
+	if (value == null) {
+	    throw ExceptionFactory.propertyValueCanNotBeNull();
+	}
+
+	if (key == null) {
+	    throw ExceptionFactory.propertyKeyCanNotBeNull();
+	}
+
+	if (key.equals("")) {
+	    throw ExceptionFactory.propertyKeyCanNotBeEmpty();
+	}
+
+	if (key.equals("id")) {
+	    throw ExceptionFactory.propertyKeyIdIsReserved();
+	}
+
+	if (this instanceof RamCloudEdge && key.equals("label")) {
+	    throw ExceptionFactory.propertyKeyLabelIsReservedForEdges();
+	}
+
+	long startTime = 0;
+	if (graph.measureBPTimeProp == 1) {
+	    startTime = System.nanoTime();
+	}
+
+	Map<String, Object> map = getPropertyMap();
+	oldValue = map.put(key, value);
+	setPropertyMap(map);
+
+	boolean ret = false;
+	if (this instanceof RamCloudVertex) {
+	    RamCloudKeyIndex keyIndex = new RamCloudKeyIndex(graph.kidxVertTableId, key, value, graph, Vertex.class);
+	    ret = keyIndex.autoUpdate(key, value, oldValue, this);
+	} else {
+	    RamCloudKeyIndex keyIndex = new RamCloudKeyIndex(graph.kidxVertTableId, key, value, graph, Edge.class);
+	    keyIndex.autoUpdate(key, value, oldValue, this);
+	}
+
+	if (graph.measureBPTimeProp == 1) {
+	    long endTime = System.nanoTime();
+	    if (ret) {
+		log.error("Performance vertex setProperty(key {}) which is index total time {}", key, endTime - startTime);
+	    } else {
+		log.error("Performance vertex setProperty(key {}) does not index time {}", key, endTime - startTime);
+	    }
+	}
+
+    }
+
+    @Override
+    public <T> T removeProperty(String key) {
+	Map<String, Object> map = getPropertyMap();
+	T retVal = (T) map.remove(key);
+	setPropertyMap(map);
+	if (this instanceof RamCloudVertex) {
+	    RamCloudKeyIndex keyIndex = new RamCloudKeyIndex(graph.kidxVertTableId, key, retVal, graph, Vertex.class);
+	    keyIndex.autoRemove(key, retVal.toString(), this);
+	} else {
+	    RamCloudKeyIndex keyIndex = new RamCloudKeyIndex(graph.kidxVertTableId, key, retVal, graph, Edge.class);
+	    keyIndex.autoRemove(key, retVal.toString(), this);
+	}
+
+	return retVal;
+    }
+
+    @Override
+    public void remove() {
+	graph.getRcClient().remove(rcPropTableId, rcPropTableKey);
+    }
+
+    @Override
+    public Object getId() {
+	// TODO Auto-generated method stub
+	return null;
+    }
+
+    @Override
+    public String toString() {
+	return "RamCloudElement [rcPropTableKey=" + Arrays.toString(rcPropTableKey)
+		+ ", rcPropTableId=" + rcPropTableId + "]";
+    }
+}
diff --git a/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudGraph.java b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudGraph.java
new file mode 100644
index 0000000..4843b01
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudGraph.java
@@ -0,0 +1,725 @@
+/* Copyright (c) 2013 Stanford University
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package com.tinkerpop.blueprints.impls.ramcloud;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.jersey.core.util.Base64;
+import com.tinkerpop.blueprints.Direction;
+import com.tinkerpop.blueprints.Edge;
+import com.tinkerpop.blueprints.Element;
+import com.tinkerpop.blueprints.Features;
+import com.tinkerpop.blueprints.GraphQuery;
+import com.tinkerpop.blueprints.Index;
+import com.tinkerpop.blueprints.IndexableGraph;
+import com.tinkerpop.blueprints.KeyIndexableGraph;
+import com.tinkerpop.blueprints.Parameter;
+import com.tinkerpop.blueprints.TransactionalGraph;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.util.DefaultGraphQuery;
+import com.tinkerpop.blueprints.util.ExceptionFactory;
+import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
+
+import edu.stanford.ramcloud.JRamCloud;
+import edu.stanford.ramcloud.JRamCloud.MultiWriteObject;
+
+public class RamCloudGraph implements IndexableGraph, KeyIndexableGraph, TransactionalGraph, Serializable {
+    private final static Logger log = LoggerFactory.getLogger(RamCloudGraph.class);
+
+    private static final ThreadLocal<JRamCloud> RamCloudThreadLocal = new ThreadLocal<JRamCloud>();
+
+    protected long vertTableId; //(vertex_id) --> ( (n,d,ll,l), (n,d,ll,l), ... )
+    protected long vertPropTableId; //(vertex_id) -> ( (kl,k,vl,v), (kl,k,vl,v), ... )
+    protected long edgePropTableId; //(edge_id) -> ( (kl,k,vl,v), (kl,k,vl,v), ... )
+    protected long idxVertTableId;
+    protected long idxEdgeTableId;
+    protected long kidxVertTableId;
+    protected long kidxEdgeTableId;
+    protected long instanceTableId;
+    private String VERT_TABLE_NAME = "verts";
+    private String EDGE_PROP_TABLE_NAME = "edge_props";
+    private String VERT_PROP_TABLE_NAME = "vert_props";
+    private String IDX_VERT_TABLE_NAME = "idx_vert";
+    private String IDX_EDGE_TABLE_NAME = "idx_edge";
+    private String KIDX_VERT_TABLE_NAME = "kidx_vert";
+    private String KIDX_EDGE_TABLE_NAME = "kidx_edge";
+    private final String INSTANCE_TABLE_NAME = "instance";
+    private long instanceId;
+    private AtomicLong nextVertexId;
+    private final long INSTANCE_ID_RANGE = 100000;
+    private String coordinatorLocation;
+    private static final Features FEATURES = new Features();
+    public final long measureBPTimeProp = Long.valueOf(System.getProperty("benchmark.measureBP", "0"));
+    public final long measureRcTimeProp = Long.valueOf(System.getProperty("benchmark.measureRc", "0"));
+    public static final long measureSerializeTimeProp = Long.valueOf(System.getProperty("benchmark.measureSerializeTimeProp", "0"));
+
+
+    public final Set<String> indexedKeys = new HashSet<String>();
+
+    static {
+	FEATURES.supportsSerializableObjectProperty = true;
+	FEATURES.supportsBooleanProperty = true;
+	FEATURES.supportsDoubleProperty = true;
+	FEATURES.supportsFloatProperty = true;
+	FEATURES.supportsIntegerProperty = true;
+	FEATURES.supportsPrimitiveArrayProperty = true;
+	FEATURES.supportsUniformListProperty = true;
+	FEATURES.supportsMixedListProperty = true;
+	FEATURES.supportsLongProperty = true;
+	FEATURES.supportsMapProperty = true;
+	FEATURES.supportsStringProperty = true;
+
+	FEATURES.supportsDuplicateEdges = false;
+	FEATURES.supportsSelfLoops = false;
+	FEATURES.isPersistent = false;
+	FEATURES.isWrapper = false;
+	FEATURES.supportsVertexIteration = true;
+	FEATURES.supportsEdgeIteration = true;
+	FEATURES.supportsVertexIndex = true;
+	FEATURES.supportsEdgeIndex = false;
+	FEATURES.ignoresSuppliedIds = true;
+	FEATURES.supportsTransactions = false;
+	FEATURES.supportsIndices = false;
+	FEATURES.supportsKeyIndices = true;
+	FEATURES.supportsVertexKeyIndex = true;
+	FEATURES.supportsEdgeKeyIndex = false;
+	FEATURES.supportsEdgeRetrieval = true;
+	FEATURES.supportsVertexProperties = true;
+	FEATURES.supportsEdgeProperties = true;
+	FEATURES.supportsThreadedTransactions = false;
+    }
+
+    static {
+	System.loadLibrary("edu_stanford_ramcloud_JRamCloud");
+    }
+
+    private RamCloudGraph() {
+    }
+
+
+    public RamCloudGraph(String coordinatorLocation) {
+	this.coordinatorLocation = coordinatorLocation;
+
+	JRamCloud rcClient = getRcClient();
+
+	vertTableId = rcClient.createTable(VERT_TABLE_NAME);
+	vertPropTableId = rcClient.createTable(VERT_PROP_TABLE_NAME);
+	edgePropTableId = rcClient.createTable(EDGE_PROP_TABLE_NAME);
+	idxVertTableId = rcClient.createTable(IDX_VERT_TABLE_NAME);
+	idxEdgeTableId = rcClient.createTable(IDX_EDGE_TABLE_NAME);
+	kidxVertTableId = rcClient.createTable(KIDX_VERT_TABLE_NAME);
+	kidxEdgeTableId = rcClient.createTable(KIDX_EDGE_TABLE_NAME);
+	instanceTableId = rcClient.createTable(INSTANCE_TABLE_NAME);
+
+	log.info( "Connected to coordinator at {}", coordinatorLocation);
+	log.debug("VERT_TABLE:{}, VERT_PROP_TABLE:{}, EDGE_PROP_TABLE:{}, IDX_VERT_TABLE:{}, IDX_EDGE_TABLE:{}, KIDX_VERT_TABLE:{}, KIDX_EDGE_TABLE:{}", vertTableId, vertPropTableId, edgePropTableId, idxVertTableId, idxEdgeTableId, kidxVertTableId, kidxEdgeTableId);
+	nextVertexId = new AtomicLong(-1);
+        initInstance();
+    }
+
+    public JRamCloud getRcClient() {
+	JRamCloud rcClient = RamCloudThreadLocal.get();
+	if (rcClient == null) {
+	    rcClient = new JRamCloud(coordinatorLocation);
+	    RamCloudThreadLocal.set(rcClient);
+	}
+	return rcClient;
+    }
+
+    @Override
+    public Features getFeatures() {
+	return FEATURES;
+    }
+
+    private Long parseVertexId(Object id) {
+	Long longId;
+	if (id == null) {
+	    longId = nextVertexId.incrementAndGet();
+	} else if (id instanceof Integer) {
+	    longId = ((Integer) id).longValue();
+	} else if (id instanceof Long) {
+	    longId = (Long) id;
+	} else if (id instanceof String) {
+	    try {
+		longId = Long.parseLong((String) id, 10);
+	    } catch (NumberFormatException e) {
+		log.warn("ID argument {} of type {} is not a parseable long number: {}", id, id.getClass(), e);
+		return null;
+	    }
+	} else if (id instanceof byte[]) {
+	    try {
+		longId = ByteBuffer.wrap((byte[]) id).getLong();
+	    } catch (BufferUnderflowException e) {
+		log.warn("ID argument {} of type {} is not a parseable long number: {}", id, id.getClass(), e);
+		return null;
+	    }
+	} else {
+	    log.warn("ID argument {} of type {} is not supported. Returning null.", id, id.getClass());
+	    return null;
+	}
+	return longId;
+    }
+
+    @Override
+    public Vertex addVertex(Object id) {
+	long startTime = 0;
+	long Tstamp1 = 0;
+	long Tstamp2 = 0;
+
+	if (measureBPTimeProp == 1) {
+	    startTime = System.nanoTime();
+	}
+	Long longId = parseVertexId(id);
+	if (longId == null)
+	    return null;
+	if (measureBPTimeProp == 1) {
+	    Tstamp1 = System.nanoTime();
+	}
+	RamCloudVertex newVertex = new RamCloudVertex(longId, this);
+	if (measureBPTimeProp == 1) {
+	    Tstamp2 = System.nanoTime();
+	    log.error("Performance addVertex [id={}] : Calling create at {}", longId, Tstamp2);
+	}
+
+	try {
+	    newVertex.create();
+	    if (measureBPTimeProp == 1) {
+		long endTime = System.nanoTime();
+		log.error("Performance addVertex [id={}] : genid {} newVerex {} create {} total time {}", longId, Tstamp1 - startTime, Tstamp2 - Tstamp1, endTime - Tstamp2, endTime - startTime);
+	    }
+	    log.info("Added vertex: [id={}]", longId);
+	    return newVertex;
+	} catch (IllegalArgumentException e) {
+	    log.error("Tried to create vertex failed {" + newVertex + "}", e);
+	    return null;
+	}
+    }
+
+    public List<RamCloudVertex> addVertices(Iterable<Object> ids) {
+	log.info("addVertices start");
+	List<RamCloudVertex> vertices = new LinkedList<RamCloudVertex>();
+
+	for (Object id: ids) {
+	    Long longId = parseVertexId(id);
+	    if (longId == null)
+		return null;
+	    RamCloudVertex v = new RamCloudVertex(longId, this);
+	    if (v.exists()) {
+		log.error("ramcloud vertex id: {} already exists", v.getId());
+		throw ExceptionFactory.vertexWithIdAlreadyExists(v.getId());
+	    }
+	    vertices.add(v);
+	}
+	MultiWriteObject multiWriteObjects[] = new MultiWriteObject[vertices.size() * 2];
+	for (int i=0; i < vertices.size(); i++) {
+	    RamCloudVertex v = vertices.get(i);
+	    multiWriteObjects[i*2] = new MultiWriteObject(vertTableId, v.rcKey, ByteBuffer.allocate(0).array(), null);
+	    multiWriteObjects[i*2+1] = new MultiWriteObject(vertPropTableId, v.rcKey, ByteBuffer.allocate(0).array(), null);
+	}
+	try {
+		PerfMon pm = PerfMon.getInstance();
+		pm.multiwrite_start("RamCloudVertex create()");
+	    getRcClient().multiWrite(multiWriteObjects);
+		pm.multiwrite_end("RamCloudVertex create()");
+	    log.info("ramcloud vertices are created");
+	} catch (Exception e) {
+	    log.error("Tried to create vertices failed {}", e);
+	    return null;
+	}
+	log.info("addVertices end (success)");
+	return vertices;
+    }
+
+    private final void initInstance() {
+        //long incrementValue = 1;
+        JRamCloud.Object instanceEntry = null;
+        JRamCloud rcClient = getRcClient();
+        try {
+            instanceEntry = rcClient.read(instanceTableId, "nextInstanceId".getBytes());
+        } catch (Exception e) {
+            if (e instanceof JRamCloud.ObjectDoesntExistException) {
+                instanceId = 0;
+                rcClient.write(instanceTableId, "nextInstanceId".getBytes(), ByteBuffer.allocate(0).array());
+            }
+        }
+        if (instanceEntry != null) {
+	    long curInstanceId = 1;
+	    for (int i = 0 ; i < 100 ; i++) {
+		Map<String, Long> propMap = null;
+		if (instanceEntry.value == null) {
+		    log.warn("Got a null byteArray argument");
+		    return;
+		} else if (instanceEntry.value.length != 0) {
+		    try {
+			ByteArrayInputStream bais = new ByteArrayInputStream(instanceEntry.value);
+			ObjectInputStream ois = new ObjectInputStream(bais);
+			propMap = (Map<String, Long>) ois.readObject();
+		    } catch (IOException e) {
+			log.error("Got an exception while deserializing element's property map: ", e);
+			return;
+		    } catch (ClassNotFoundException e) {
+			log.error("Got an exception while deserializing element's property map: ", e);
+			return;
+		    }
+		} else {
+		    propMap = new HashMap<String, Long>();
+		}
+
+		if (propMap.containsKey(INSTANCE_TABLE_NAME)) {
+		    curInstanceId = propMap.get(INSTANCE_TABLE_NAME) + 1;
+		}
+
+		propMap.put(INSTANCE_TABLE_NAME, curInstanceId);
+
+		byte[] rcValue = null;
+		try {
+		    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		    ObjectOutputStream oot = new ObjectOutputStream(baos);
+		    oot.writeObject(propMap);
+		    rcValue = baos.toByteArray();
+		} catch (IOException e) {
+		    log.error("Got an exception while serializing element's property map", e);
+		    return;
+		}
+		JRamCloud.RejectRules rules = rcClient.new RejectRules();
+		rules.setNeVersion(instanceEntry.version);
+		try {
+		    rcClient.writeRule(instanceTableId, "nextInstanceId".getBytes(), rcValue, rules);
+		    instanceId = curInstanceId;
+		    break;
+		} catch (Exception ex) {
+		    log.debug("Cond. Write increment Vertex property: ", ex);
+		    instanceEntry = rcClient.read(instanceTableId, "nextInstanceId".getBytes());
+		    continue;
+		}
+	    }
+	}
+
+	nextVertexId.compareAndSet(-1, instanceId * INSTANCE_ID_RANGE);
+    }
+
+    @Override
+    public Vertex getVertex(Object id) throws IllegalArgumentException {
+	Long longId;
+
+	if (id == null) {
+	    throw ExceptionFactory.vertexIdCanNotBeNull();
+	} else if (id instanceof Integer) {
+	    longId = ((Integer) id).longValue();
+	} else if (id instanceof Long) {
+	    longId = (Long) id;
+	} else if (id instanceof String) {
+	    try {
+		longId = Long.parseLong((String) id, 10);
+	    } catch (NumberFormatException e) {
+		log.warn("ID argument {} of type {} is not a parseable long number: {}", id, id.getClass(), e);
+		return null;
+	    }
+	} else if (id instanceof byte[]) {
+	    try {
+		longId = ByteBuffer.wrap((byte[]) id).getLong();
+	    } catch (BufferUnderflowException e) {
+		log.warn("ID argument {} of type {} is not a parseable long number: {}", id, id.getClass(), e);
+		return null;
+	    }
+	} else {
+	    log.warn("ID argument {} of type {} is not supported. Returning null.", id, id.getClass());
+	    return null;
+	}
+
+	RamCloudVertex vertex = new RamCloudVertex(longId, this);
+
+	if (vertex.exists()) {
+	    return vertex;
+	} else {
+	    return null;
+	}
+    }
+
+    @Override
+    public void removeVertex(Vertex vertex) {
+	((RamCloudVertex) vertex).remove();
+    }
+
+    @Override
+    public Iterable<Vertex> getVertices() {
+	JRamCloud.TableEnumerator tableEnum = getRcClient().new TableEnumerator(vertPropTableId);
+	List<Vertex> vertices = new LinkedList<Vertex>();
+
+	while (tableEnum.hasNext()) {
+		vertices.add(new RamCloudVertex(tableEnum.next().key, this));
+	}
+
+	return vertices;
+    }
+
+    @Override
+    public Iterable<Vertex> getVertices(String key, Object value) {
+	long startTime = 0;
+	long Tstamp1 = 0;
+	long Tstamp2 = 0;
+	long Tstamp3 = 0;
+	if (measureBPTimeProp == 1) {
+	    startTime = System.nanoTime();
+	    log.error("Performance getVertices(key {}) start at {}", key, startTime);
+	}
+
+	List<Vertex> vertices = new ArrayList<Vertex>();
+	List<Object> vertexList = null;
+
+	JRamCloud vertTable = getRcClient();
+	if (measureBPTimeProp == 1) {
+	    Tstamp1 = System.nanoTime();
+	    log.error("Performance getVertices(key {}) Calling indexedKeys.contains(key) at {}", key, Tstamp1);
+	}
+
+
+	if (indexedKeys.contains(key)) {
+	    PerfMon pm = PerfMon.getInstance();
+	    if (measureBPTimeProp == 1) {
+	      Tstamp2 = System.nanoTime();
+	      log.error("Performance getVertices(key {}) Calling new RamCloudKeyIndex at {}", key, Tstamp2);
+	    }
+	    RamCloudKeyIndex KeyIndex = new RamCloudKeyIndex(kidxVertTableId, key, value, this, Vertex.class);
+	    if (measureBPTimeProp == 1) {
+	      Tstamp3 = System.nanoTime();
+	      log.error("Performance getVertices(key {}) Calling KeyIndex.GetElmIdListForPropValue at {}", key, Tstamp3);
+	    }
+	    vertexList = KeyIndex.getElmIdListForPropValue(value.toString());
+	    if (vertexList == null) {
+		if (measureBPTimeProp == 1) {
+		    long endTime = System.nanoTime();
+		    log.error("Performance getVertices(key {}) does not exists : getRcClient {} indexedKeys.contains(key) {} new_RamCloudKeyIndex {} KeyIndex.get..Value {} total {} diff {}", key, Tstamp1-startTime, Tstamp2-Tstamp1,Tstamp3-Tstamp2, endTime-Tstamp3, endTime - startTime, (endTime-startTime)- (Tstamp1-startTime)- (Tstamp2-Tstamp1)- (Tstamp3-Tstamp2)-(endTime-Tstamp3));
+		}
+		return vertices;
+	    }
+
+	    final int mreadMax = 400;
+	    final int size = Math.min(mreadMax, vertexList.size());
+	    JRamCloud.multiReadObject vertPropTableMread[] = new JRamCloud.multiReadObject[size];
+
+	    int vertexNum = 0;
+	    for (Object vert : vertexList) {
+		byte[] rckey =
+			ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN).putLong((Long) vert).array();
+		vertPropTableMread[vertexNum] = new JRamCloud.multiReadObject(vertPropTableId, rckey);
+		if (vertexNum >= (mreadMax - 1)) {
+		    pm.multiread_start("RamCloudGraph getVertices()");
+		    JRamCloud.Object outvertPropTable[] =
+			    vertTable.multiRead(vertPropTableMread);
+		    pm.multiread_end("RamCloudGraph getVertices()");
+		    for (int i = 0; i < outvertPropTable.length; i++) {
+			if (outvertPropTable[i] != null) {
+			    vertices.add(new RamCloudVertex(outvertPropTable[i].key, this));
+			}
+		    }
+		    vertexNum = 0;
+		    continue;
+		}
+		vertexNum++;
+	    }
+
+	    if (vertexNum != 0) {
+		JRamCloud.multiReadObject mread_leftover[] = Arrays.copyOf(vertPropTableMread, vertexNum);
+
+		long startTime2 = 0;
+		if (measureRcTimeProp == 1) {
+		    startTime2 = System.nanoTime();
+		}
+		pm.multiread_start("RamCloudGraph getVertices()");
+		JRamCloud.Object outvertPropTable[] = vertTable.multiRead(mread_leftover);
+		pm.multiread_end("RamCloudGraph getVertices()");
+		if (measureRcTimeProp == 1) {
+		    long endTime2 = System.nanoTime();
+		    log.error("Performance index multiread(key {}, number {}) time {}", key, vertexNum, endTime2 - startTime2);
+		}
+		for (int i = 0; i < outvertPropTable.length; i++) {
+		    if (outvertPropTable[i] != null) {
+			vertices.add(new RamCloudVertex(outvertPropTable[i].key, this));
+		    }
+		}
+	    }
+	} else {
+
+	    JRamCloud.TableEnumerator tableEnum = getRcClient().new TableEnumerator(vertPropTableId);
+	    JRamCloud.Object tableEntry;
+
+	    while (tableEnum.hasNext()) {
+		tableEntry = tableEnum.next();
+		if (tableEntry != null) {
+		    //XXX remove temp
+		    // RamCloudVertex temp = new RamCloudVertex(tableEntry.key, this);
+		    Map<String, Object> propMap = RamCloudElement.convertRcBytesToPropertyMapEx(tableEntry.value);
+		    if (propMap.containsKey(key) && propMap.get(key).equals(value)) {
+			vertices.add(new RamCloudVertex(tableEntry.key, this));
+		    }
+		}
+	    }
+	}
+
+	if (measureBPTimeProp == 1) {
+		long endTime = System.nanoTime();
+		log.error("Performance getVertices exists total time {}.", endTime - startTime);
+	}
+
+	return vertices;
+    }
+
+    @Override
+    public Edge addEdge(Object id, Vertex outVertex, Vertex inVertex, String label) throws IllegalArgumentException {
+	log.info("Adding edge: [id={}, outVertex={}, inVertex={}, label={}]", id, outVertex, inVertex, label);
+
+	if (label == null) {
+	    throw ExceptionFactory.edgeLabelCanNotBeNull();
+	}
+
+	RamCloudEdge newEdge = new RamCloudEdge((RamCloudVertex) outVertex, (RamCloudVertex) inVertex, label, this);
+
+	for (int i = 0; i < 5 ;i++) {
+	    try {
+		newEdge.create();
+		return newEdge;
+	    } catch (Exception e) {
+		log.warn("Tried to create edge failed: {" + newEdge + "}: ", e);
+
+		if (e instanceof NoSuchElementException) {
+		    log.error("addEdge RETRYING {}", i);
+		    continue;
+		}
+	    }
+	}
+	return null;
+    }
+
+    public List<Edge> addEdges(Iterable<Edge> edgeEntities) throws IllegalArgumentException {
+	//TODO WIP: need multi-write
+	log.info("addEdges start");
+	ArrayList<Edge> edges = new ArrayList<Edge>();
+	for (Edge edge: edgeEntities) {
+	    edges.add(addEdge(null, edge.getVertex(Direction.OUT), edge.getVertex(Direction.IN), edge.getLabel()));
+	}
+	log.info("addVertices end");
+	return edges;
+    }
+
+    public void setProperties(Map<RamCloudVertex, Map<String, Object>> properties) {
+	// TODO WIP: need multi-write
+	log.info("setProperties start");
+	for (Map.Entry<RamCloudVertex, Map<String, Object>> e: properties.entrySet()) {
+	    e.getKey().setProperties(e.getValue());
+	}
+	log.info("setProperties end");
+    }
+
+    @Override
+    public Edge getEdge(Object id) throws IllegalArgumentException {
+	byte[] bytearrayId;
+
+	if (id == null) {
+	    throw ExceptionFactory.edgeIdCanNotBeNull();
+	} else if (id instanceof byte[]) {
+	    bytearrayId = (byte[]) id;
+	} else if (id instanceof String) {
+	    bytearrayId = Base64.decode(((String) id));
+	} else {
+	    log.warn("ID argument {} of type {} is not supported. Returning null.", id, id.getClass());
+	    return null;
+	}
+
+	if (!RamCloudEdge.isValidEdgeId(bytearrayId)) {
+	    log.warn("ID argument {} of type {} is malformed. Returning null.", id, id.getClass());
+	    return null;
+	}
+
+	RamCloudEdge edge = new RamCloudEdge(bytearrayId, this);
+
+	if (edge.exists()) {
+	    return edge;
+	} else {
+	    return null;
+	}
+    }
+
+    @Override
+    public void removeEdge(Edge edge) {
+	edge.remove();
+    }
+
+    @Override
+    public Iterable<Edge> getEdges() {
+	JRamCloud.TableEnumerator tableEnum = getRcClient().new TableEnumerator(edgePropTableId);
+	List<Edge> edges = new ArrayList<Edge>();
+
+	while (tableEnum.hasNext()) {
+	    edges.add(new RamCloudEdge(tableEnum.next().key, this));
+	}
+
+	return edges;
+    }
+
+    @Override
+    public Iterable<Edge> getEdges(String key, Object value) {
+	JRamCloud.TableEnumerator tableEnum = getRcClient().new TableEnumerator(edgePropTableId);
+	List<Edge> edges = new ArrayList<Edge>();
+	JRamCloud.Object tableEntry;
+
+	while (tableEnum.hasNext()) {
+	    tableEntry = tableEnum.next();
+		// FIXME temp
+		//RamCloudEdge temp = new RamCloudEdge(tableEntry.key, this);
+	    Map<String, Object> propMap = RamCloudElement.convertRcBytesToPropertyMapEx(tableEntry.value);
+	    if (propMap.containsKey(key) && propMap.get(key).equals(value)) {
+		edges.add(new RamCloudEdge(tableEntry.key, this));
+	    }
+	}
+
+	return edges;
+    }
+
+    @Override
+    public GraphQuery query() {
+	return new DefaultGraphQuery(this);
+    }
+
+    @Override
+    public void shutdown() {
+	JRamCloud rcClient = getRcClient();
+	rcClient.dropTable(VERT_TABLE_NAME);
+	rcClient.dropTable(VERT_PROP_TABLE_NAME);
+	rcClient.dropTable(EDGE_PROP_TABLE_NAME);
+	rcClient.dropTable(IDX_VERT_TABLE_NAME);
+	rcClient.dropTable(IDX_EDGE_TABLE_NAME);
+	rcClient.dropTable(KIDX_VERT_TABLE_NAME);
+	rcClient.dropTable(KIDX_EDGE_TABLE_NAME);
+	rcClient.disconnect();
+    }
+
+    @Override
+    public void stopTransaction(Conclusion conclusion) {
+	// TODO Auto-generated method stub
+    }
+
+    @Override
+    public void commit() {
+	// TODO Auto-generated method stub
+    }
+
+    @Override
+    public void rollback() {
+	// TODO Auto-generated method stub
+    }
+
+    @Override
+    public <T extends Element> void dropKeyIndex(String key, Class<T> elementClass) {
+	throw new UnsupportedOperationException("Not supported yet.");
+	//FIXME how to dropKeyIndex
+	//new RamCloudKeyIndex(kidxVertTableId, key, this, elementClass);
+	//getIndexedKeys(key, elementClass).removeIndex();
+    }
+
+    @Override
+    public <T extends Element> void createKeyIndex(String key,
+	    Class<T> elementClass, Parameter... indexParameters) {
+	if (key == null) {
+	    return;
+	}
+	if (this.indexedKeys.contains(key)) {
+	    return;
+	}
+	this.indexedKeys.add(key);
+    }
+
+    @Override
+    public <T extends Element> Set< String> getIndexedKeys(Class< T> elementClass) {
+	if (null != this.indexedKeys) {
+	    return new HashSet<String>(this.indexedKeys);
+	} else {
+	    return Collections.emptySet();
+	}
+    }
+
+    @Override
+    public <T extends Element> Index<T> createIndex(String indexName,
+	    Class<T> indexClass, Parameter... indexParameters) {
+	throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public <T extends Element> Index<T> getIndex(String indexName, Class<T> indexClass) {
+	throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public Iterable<Index<? extends Element>> getIndices() {
+	throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void dropIndex(String indexName) {
+	throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public String toString() {
+	return getClass().getSimpleName().toLowerCase() + "[vertices:" + ((List<Vertex>)getVertices()).size() + " edges:" + ((List<Edge>)getEdges()).size() + "]";
+    }
+
+    public static void main(String[] args) {
+	RamCloudGraph graph = new RamCloudGraph();
+
+	Vertex a = graph.addVertex(null);
+	Vertex b = graph.addVertex(null);
+	Vertex c = graph.addVertex(null);
+	Vertex d = graph.addVertex(null);
+	Vertex e = graph.addVertex(null);
+	Vertex f = graph.addVertex(null);
+	Vertex g = graph.addVertex(null);
+
+	graph.addEdge(null, a, a, "friend");
+	graph.addEdge(null, a, b, "friend1");
+	graph.addEdge(null, a, b, "friend2");
+	graph.addEdge(null, a, b, "friend3");
+	graph.addEdge(null, a, c, "friend");
+	graph.addEdge(null, a, d, "friend");
+	graph.addEdge(null, a, e, "friend");
+	graph.addEdge(null, a, f, "friend");
+	graph.addEdge(null, a, g, "friend");
+
+	graph.shutdown();
+    }
+}
diff --git a/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudGraphProtos.java b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudGraphProtos.java
new file mode 100644
index 0000000..9a126eb
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudGraphProtos.java
@@ -0,0 +1,3861 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: ramcloudgraph.proto
+
+package com.tinkerpop.blueprints.impls.ramcloud;
+
+public final class RamCloudGraphProtos {
+  private RamCloudGraphProtos() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface EdgeListProtoBufOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // repeated .RamCloudGraph.EdgeProtoBuf edge = 1;
+    /**
+     * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+     */
+    java.util.List<com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf> 
+        getEdgeList();
+    /**
+     * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+     */
+    com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf getEdge(int index);
+    /**
+     * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+     */
+    int getEdgeCount();
+    /**
+     * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+     */
+    java.util.List<? extends com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBufOrBuilder> 
+        getEdgeOrBuilderList();
+    /**
+     * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+     */
+    com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBufOrBuilder getEdgeOrBuilder(
+        int index);
+  }
+  /**
+   * Protobuf type {@code RamCloudGraph.EdgeListProtoBuf}
+   */
+  public static final class EdgeListProtoBuf extends
+      com.google.protobuf.GeneratedMessage
+      implements EdgeListProtoBufOrBuilder {
+    // Use EdgeListProtoBuf.newBuilder() to construct.
+    private EdgeListProtoBuf(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private EdgeListProtoBuf(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final EdgeListProtoBuf defaultInstance;
+    public static EdgeListProtoBuf getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public EdgeListProtoBuf getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private EdgeListProtoBuf(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                edge_ = new java.util.ArrayList<com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              edge_.add(input.readMessage(com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.PARSER, extensionRegistry));
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+          edge_ = java.util.Collections.unmodifiableList(edge_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_EdgeListProtoBuf_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_EdgeListProtoBuf_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf.class, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<EdgeListProtoBuf> PARSER =
+        new com.google.protobuf.AbstractParser<EdgeListProtoBuf>() {
+      public EdgeListProtoBuf parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new EdgeListProtoBuf(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<EdgeListProtoBuf> getParserForType() {
+      return PARSER;
+    }
+
+    // repeated .RamCloudGraph.EdgeProtoBuf edge = 1;
+    public static final int EDGE_FIELD_NUMBER = 1;
+    private java.util.List<com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf> edge_;
+    /**
+     * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+     */
+    public java.util.List<com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf> getEdgeList() {
+      return edge_;
+    }
+    /**
+     * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+     */
+    public java.util.List<? extends com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBufOrBuilder> 
+        getEdgeOrBuilderList() {
+      return edge_;
+    }
+    /**
+     * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+     */
+    public int getEdgeCount() {
+      return edge_.size();
+    }
+    /**
+     * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+     */
+    public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf getEdge(int index) {
+      return edge_.get(index);
+    }
+    /**
+     * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+     */
+    public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBufOrBuilder getEdgeOrBuilder(
+        int index) {
+      return edge_.get(index);
+    }
+
+    private void initFields() {
+      edge_ = java.util.Collections.emptyList();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      for (int i = 0; i < getEdgeCount(); i++) {
+        if (!getEdge(i).isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      for (int i = 0; i < edge_.size(); i++) {
+        output.writeMessage(1, edge_.get(i));
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < edge_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, edge_.get(i));
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code RamCloudGraph.EdgeListProtoBuf}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBufOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_EdgeListProtoBuf_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_EdgeListProtoBuf_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf.class, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf.Builder.class);
+      }
+
+      // Construct using com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getEdgeFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (edgeBuilder_ == null) {
+          edge_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          edgeBuilder_.clear();
+        }
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_EdgeListProtoBuf_descriptor;
+      }
+
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf getDefaultInstanceForType() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf.getDefaultInstance();
+      }
+
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf build() {
+        com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf buildPartial() {
+        com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf result = new com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf(this);
+        int from_bitField0_ = bitField0_;
+        if (edgeBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+            edge_ = java.util.Collections.unmodifiableList(edge_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.edge_ = edge_;
+        } else {
+          result.edge_ = edgeBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf) {
+          return mergeFrom((com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf other) {
+        if (other == com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf.getDefaultInstance()) return this;
+        if (edgeBuilder_ == null) {
+          if (!other.edge_.isEmpty()) {
+            if (edge_.isEmpty()) {
+              edge_ = other.edge_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureEdgeIsMutable();
+              edge_.addAll(other.edge_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.edge_.isEmpty()) {
+            if (edgeBuilder_.isEmpty()) {
+              edgeBuilder_.dispose();
+              edgeBuilder_ = null;
+              edge_ = other.edge_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              edgeBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getEdgeFieldBuilder() : null;
+            } else {
+              edgeBuilder_.addAllMessages(other.edge_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        for (int i = 0; i < getEdgeCount(); i++) {
+          if (!getEdge(i).isInitialized()) {
+            
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // repeated .RamCloudGraph.EdgeProtoBuf edge = 1;
+      private java.util.List<com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf> edge_ =
+        java.util.Collections.emptyList();
+      private void ensureEdgeIsMutable() {
+        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+          edge_ = new java.util.ArrayList<com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf>(edge_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.Builder, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBufOrBuilder> edgeBuilder_;
+
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public java.util.List<com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf> getEdgeList() {
+        if (edgeBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(edge_);
+        } else {
+          return edgeBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public int getEdgeCount() {
+        if (edgeBuilder_ == null) {
+          return edge_.size();
+        } else {
+          return edgeBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf getEdge(int index) {
+        if (edgeBuilder_ == null) {
+          return edge_.get(index);
+        } else {
+          return edgeBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public Builder setEdge(
+          int index, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf value) {
+        if (edgeBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureEdgeIsMutable();
+          edge_.set(index, value);
+          onChanged();
+        } else {
+          edgeBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public Builder setEdge(
+          int index, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.Builder builderForValue) {
+        if (edgeBuilder_ == null) {
+          ensureEdgeIsMutable();
+          edge_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          edgeBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public Builder addEdge(com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf value) {
+        if (edgeBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureEdgeIsMutable();
+          edge_.add(value);
+          onChanged();
+        } else {
+          edgeBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public Builder addEdge(
+          int index, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf value) {
+        if (edgeBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureEdgeIsMutable();
+          edge_.add(index, value);
+          onChanged();
+        } else {
+          edgeBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public Builder addEdge(
+          com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.Builder builderForValue) {
+        if (edgeBuilder_ == null) {
+          ensureEdgeIsMutable();
+          edge_.add(builderForValue.build());
+          onChanged();
+        } else {
+          edgeBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public Builder addEdge(
+          int index, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.Builder builderForValue) {
+        if (edgeBuilder_ == null) {
+          ensureEdgeIsMutable();
+          edge_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          edgeBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public Builder addAllEdge(
+          java.lang.Iterable<? extends com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf> values) {
+        if (edgeBuilder_ == null) {
+          ensureEdgeIsMutable();
+          super.addAll(values, edge_);
+          onChanged();
+        } else {
+          edgeBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public Builder clearEdge() {
+        if (edgeBuilder_ == null) {
+          edge_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          edgeBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public Builder removeEdge(int index) {
+        if (edgeBuilder_ == null) {
+          ensureEdgeIsMutable();
+          edge_.remove(index);
+          onChanged();
+        } else {
+          edgeBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.Builder getEdgeBuilder(
+          int index) {
+        return getEdgeFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBufOrBuilder getEdgeOrBuilder(
+          int index) {
+        if (edgeBuilder_ == null) {
+          return edge_.get(index);  } else {
+          return edgeBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public java.util.List<? extends com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBufOrBuilder> 
+           getEdgeOrBuilderList() {
+        if (edgeBuilder_ != null) {
+          return edgeBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(edge_);
+        }
+      }
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.Builder addEdgeBuilder() {
+        return getEdgeFieldBuilder().addBuilder(
+            com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.Builder addEdgeBuilder(
+          int index) {
+        return getEdgeFieldBuilder().addBuilder(
+            index, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .RamCloudGraph.EdgeProtoBuf edge = 1;</code>
+       */
+      public java.util.List<com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.Builder> 
+           getEdgeBuilderList() {
+        return getEdgeFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.Builder, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBufOrBuilder> 
+          getEdgeFieldBuilder() {
+        if (edgeBuilder_ == null) {
+          edgeBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.Builder, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBufOrBuilder>(
+                  edge_,
+                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  getParentForChildren(),
+                  isClean());
+          edge_ = null;
+        }
+        return edgeBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:RamCloudGraph.EdgeListProtoBuf)
+    }
+
+    static {
+      defaultInstance = new EdgeListProtoBuf(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:RamCloudGraph.EdgeListProtoBuf)
+  }
+
+  public interface EdgeProtoBufOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required uint64 neighborId = 1;
+    /**
+     * <code>required uint64 neighborId = 1;</code>
+     */
+    boolean hasNeighborId();
+    /**
+     * <code>required uint64 neighborId = 1;</code>
+     */
+    long getNeighborId();
+
+    // required bool outgoing = 2;
+    /**
+     * <code>required bool outgoing = 2;</code>
+     */
+    boolean hasOutgoing();
+    /**
+     * <code>required bool outgoing = 2;</code>
+     */
+    boolean getOutgoing();
+
+    // required string label = 3;
+    /**
+     * <code>required string label = 3;</code>
+     */
+    boolean hasLabel();
+    /**
+     * <code>required string label = 3;</code>
+     */
+    java.lang.String getLabel();
+    /**
+     * <code>required string label = 3;</code>
+     */
+    com.google.protobuf.ByteString
+        getLabelBytes();
+  }
+  /**
+   * Protobuf type {@code RamCloudGraph.EdgeProtoBuf}
+   */
+  public static final class EdgeProtoBuf extends
+      com.google.protobuf.GeneratedMessage
+      implements EdgeProtoBufOrBuilder {
+    // Use EdgeProtoBuf.newBuilder() to construct.
+    private EdgeProtoBuf(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private EdgeProtoBuf(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final EdgeProtoBuf defaultInstance;
+    public static EdgeProtoBuf getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public EdgeProtoBuf getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private EdgeProtoBuf(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 8: {
+              bitField0_ |= 0x00000001;
+              neighborId_ = input.readUInt64();
+              break;
+            }
+            case 16: {
+              bitField0_ |= 0x00000002;
+              outgoing_ = input.readBool();
+              break;
+            }
+            case 26: {
+              bitField0_ |= 0x00000004;
+              label_ = input.readBytes();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_EdgeProtoBuf_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_EdgeProtoBuf_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.class, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<EdgeProtoBuf> PARSER =
+        new com.google.protobuf.AbstractParser<EdgeProtoBuf>() {
+      public EdgeProtoBuf parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new EdgeProtoBuf(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<EdgeProtoBuf> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required uint64 neighborId = 1;
+    public static final int NEIGHBORID_FIELD_NUMBER = 1;
+    private long neighborId_;
+    /**
+     * <code>required uint64 neighborId = 1;</code>
+     */
+    public boolean hasNeighborId() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required uint64 neighborId = 1;</code>
+     */
+    public long getNeighborId() {
+      return neighborId_;
+    }
+
+    // required bool outgoing = 2;
+    public static final int OUTGOING_FIELD_NUMBER = 2;
+    private boolean outgoing_;
+    /**
+     * <code>required bool outgoing = 2;</code>
+     */
+    public boolean hasOutgoing() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required bool outgoing = 2;</code>
+     */
+    public boolean getOutgoing() {
+      return outgoing_;
+    }
+
+    // required string label = 3;
+    public static final int LABEL_FIELD_NUMBER = 3;
+    private java.lang.Object label_;
+    /**
+     * <code>required string label = 3;</code>
+     */
+    public boolean hasLabel() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>required string label = 3;</code>
+     */
+    public java.lang.String getLabel() {
+      java.lang.Object ref = label_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          label_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string label = 3;</code>
+     */
+    public com.google.protobuf.ByteString
+        getLabelBytes() {
+      java.lang.Object ref = label_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        label_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    private void initFields() {
+      neighborId_ = 0L;
+      outgoing_ = false;
+      label_ = "";
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasNeighborId()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasOutgoing()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasLabel()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeUInt64(1, neighborId_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBool(2, outgoing_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeBytes(3, getLabelBytes());
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeUInt64Size(1, neighborId_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(2, outgoing_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(3, getLabelBytes());
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code RamCloudGraph.EdgeProtoBuf}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBufOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_EdgeProtoBuf_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_EdgeProtoBuf_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.class, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.Builder.class);
+      }
+
+      // Construct using com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        neighborId_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        outgoing_ = false;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        label_ = "";
+        bitField0_ = (bitField0_ & ~0x00000004);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_EdgeProtoBuf_descriptor;
+      }
+
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf getDefaultInstanceForType() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.getDefaultInstance();
+      }
+
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf build() {
+        com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf buildPartial() {
+        com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf result = new com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.neighborId_ = neighborId_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.outgoing_ = outgoing_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.label_ = label_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf) {
+          return mergeFrom((com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf other) {
+        if (other == com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf.getDefaultInstance()) return this;
+        if (other.hasNeighborId()) {
+          setNeighborId(other.getNeighborId());
+        }
+        if (other.hasOutgoing()) {
+          setOutgoing(other.getOutgoing());
+        }
+        if (other.hasLabel()) {
+          bitField0_ |= 0x00000004;
+          label_ = other.label_;
+          onChanged();
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasNeighborId()) {
+          
+          return false;
+        }
+        if (!hasOutgoing()) {
+          
+          return false;
+        }
+        if (!hasLabel()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required uint64 neighborId = 1;
+      private long neighborId_ ;
+      /**
+       * <code>required uint64 neighborId = 1;</code>
+       */
+      public boolean hasNeighborId() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required uint64 neighborId = 1;</code>
+       */
+      public long getNeighborId() {
+        return neighborId_;
+      }
+      /**
+       * <code>required uint64 neighborId = 1;</code>
+       */
+      public Builder setNeighborId(long value) {
+        bitField0_ |= 0x00000001;
+        neighborId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required uint64 neighborId = 1;</code>
+       */
+      public Builder clearNeighborId() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        neighborId_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // required bool outgoing = 2;
+      private boolean outgoing_ ;
+      /**
+       * <code>required bool outgoing = 2;</code>
+       */
+      public boolean hasOutgoing() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required bool outgoing = 2;</code>
+       */
+      public boolean getOutgoing() {
+        return outgoing_;
+      }
+      /**
+       * <code>required bool outgoing = 2;</code>
+       */
+      public Builder setOutgoing(boolean value) {
+        bitField0_ |= 0x00000002;
+        outgoing_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required bool outgoing = 2;</code>
+       */
+      public Builder clearOutgoing() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        outgoing_ = false;
+        onChanged();
+        return this;
+      }
+
+      // required string label = 3;
+      private java.lang.Object label_ = "";
+      /**
+       * <code>required string label = 3;</code>
+       */
+      public boolean hasLabel() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>required string label = 3;</code>
+       */
+      public java.lang.String getLabel() {
+        java.lang.Object ref = label_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          label_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string label = 3;</code>
+       */
+      public com.google.protobuf.ByteString
+          getLabelBytes() {
+        java.lang.Object ref = label_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          label_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string label = 3;</code>
+       */
+      public Builder setLabel(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000004;
+        label_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string label = 3;</code>
+       */
+      public Builder clearLabel() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        label_ = getDefaultInstance().getLabel();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string label = 3;</code>
+       */
+      public Builder setLabelBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000004;
+        label_ = value;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:RamCloudGraph.EdgeProtoBuf)
+    }
+
+    static {
+      defaultInstance = new EdgeProtoBuf(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:RamCloudGraph.EdgeProtoBuf)
+  }
+
+  public interface PropertyListProtoBufOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // repeated .RamCloudGraph.PropertyProtoBuf property = 1;
+    /**
+     * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+     */
+    java.util.List<com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf> 
+        getPropertyList();
+    /**
+     * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+     */
+    com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf getProperty(int index);
+    /**
+     * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+     */
+    int getPropertyCount();
+    /**
+     * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+     */
+    java.util.List<? extends com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBufOrBuilder> 
+        getPropertyOrBuilderList();
+    /**
+     * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+     */
+    com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBufOrBuilder getPropertyOrBuilder(
+        int index);
+  }
+  /**
+   * Protobuf type {@code RamCloudGraph.PropertyListProtoBuf}
+   */
+  public static final class PropertyListProtoBuf extends
+      com.google.protobuf.GeneratedMessage
+      implements PropertyListProtoBufOrBuilder {
+    // Use PropertyListProtoBuf.newBuilder() to construct.
+    private PropertyListProtoBuf(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private PropertyListProtoBuf(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final PropertyListProtoBuf defaultInstance;
+    public static PropertyListProtoBuf getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public PropertyListProtoBuf getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private PropertyListProtoBuf(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                property_ = new java.util.ArrayList<com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              property_.add(input.readMessage(com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.PARSER, extensionRegistry));
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+          property_ = java.util.Collections.unmodifiableList(property_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_PropertyListProtoBuf_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_PropertyListProtoBuf_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf.class, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<PropertyListProtoBuf> PARSER =
+        new com.google.protobuf.AbstractParser<PropertyListProtoBuf>() {
+      public PropertyListProtoBuf parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new PropertyListProtoBuf(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<PropertyListProtoBuf> getParserForType() {
+      return PARSER;
+    }
+
+    // repeated .RamCloudGraph.PropertyProtoBuf property = 1;
+    public static final int PROPERTY_FIELD_NUMBER = 1;
+    private java.util.List<com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf> property_;
+    /**
+     * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+     */
+    public java.util.List<com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf> getPropertyList() {
+      return property_;
+    }
+    /**
+     * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+     */
+    public java.util.List<? extends com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBufOrBuilder> 
+        getPropertyOrBuilderList() {
+      return property_;
+    }
+    /**
+     * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+     */
+    public int getPropertyCount() {
+      return property_.size();
+    }
+    /**
+     * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+     */
+    public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf getProperty(int index) {
+      return property_.get(index);
+    }
+    /**
+     * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+     */
+    public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBufOrBuilder getPropertyOrBuilder(
+        int index) {
+      return property_.get(index);
+    }
+
+    private void initFields() {
+      property_ = java.util.Collections.emptyList();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      for (int i = 0; i < getPropertyCount(); i++) {
+        if (!getProperty(i).isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      for (int i = 0; i < property_.size(); i++) {
+        output.writeMessage(1, property_.get(i));
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < property_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, property_.get(i));
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code RamCloudGraph.PropertyListProtoBuf}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBufOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_PropertyListProtoBuf_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_PropertyListProtoBuf_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf.class, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf.Builder.class);
+      }
+
+      // Construct using com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getPropertyFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (propertyBuilder_ == null) {
+          property_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          propertyBuilder_.clear();
+        }
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_PropertyListProtoBuf_descriptor;
+      }
+
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf getDefaultInstanceForType() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf.getDefaultInstance();
+      }
+
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf build() {
+        com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf buildPartial() {
+        com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf result = new com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf(this);
+        int from_bitField0_ = bitField0_;
+        if (propertyBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001)) {
+            property_ = java.util.Collections.unmodifiableList(property_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.property_ = property_;
+        } else {
+          result.property_ = propertyBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf) {
+          return mergeFrom((com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf other) {
+        if (other == com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf.getDefaultInstance()) return this;
+        if (propertyBuilder_ == null) {
+          if (!other.property_.isEmpty()) {
+            if (property_.isEmpty()) {
+              property_ = other.property_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensurePropertyIsMutable();
+              property_.addAll(other.property_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.property_.isEmpty()) {
+            if (propertyBuilder_.isEmpty()) {
+              propertyBuilder_.dispose();
+              propertyBuilder_ = null;
+              property_ = other.property_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              propertyBuilder_ = 
+                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                   getPropertyFieldBuilder() : null;
+            } else {
+              propertyBuilder_.addAllMessages(other.property_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        for (int i = 0; i < getPropertyCount(); i++) {
+          if (!getProperty(i).isInitialized()) {
+            
+            return false;
+          }
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyListProtoBuf) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // repeated .RamCloudGraph.PropertyProtoBuf property = 1;
+      private java.util.List<com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf> property_ =
+        java.util.Collections.emptyList();
+      private void ensurePropertyIsMutable() {
+        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+          property_ = new java.util.ArrayList<com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf>(property_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilder<
+          com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Builder, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBufOrBuilder> propertyBuilder_;
+
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public java.util.List<com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf> getPropertyList() {
+        if (propertyBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(property_);
+        } else {
+          return propertyBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public int getPropertyCount() {
+        if (propertyBuilder_ == null) {
+          return property_.size();
+        } else {
+          return propertyBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf getProperty(int index) {
+        if (propertyBuilder_ == null) {
+          return property_.get(index);
+        } else {
+          return propertyBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public Builder setProperty(
+          int index, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf value) {
+        if (propertyBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensurePropertyIsMutable();
+          property_.set(index, value);
+          onChanged();
+        } else {
+          propertyBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public Builder setProperty(
+          int index, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Builder builderForValue) {
+        if (propertyBuilder_ == null) {
+          ensurePropertyIsMutable();
+          property_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          propertyBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public Builder addProperty(com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf value) {
+        if (propertyBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensurePropertyIsMutable();
+          property_.add(value);
+          onChanged();
+        } else {
+          propertyBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public Builder addProperty(
+          int index, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf value) {
+        if (propertyBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensurePropertyIsMutable();
+          property_.add(index, value);
+          onChanged();
+        } else {
+          propertyBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public Builder addProperty(
+          com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Builder builderForValue) {
+        if (propertyBuilder_ == null) {
+          ensurePropertyIsMutable();
+          property_.add(builderForValue.build());
+          onChanged();
+        } else {
+          propertyBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public Builder addProperty(
+          int index, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Builder builderForValue) {
+        if (propertyBuilder_ == null) {
+          ensurePropertyIsMutable();
+          property_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          propertyBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public Builder addAllProperty(
+          java.lang.Iterable<? extends com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf> values) {
+        if (propertyBuilder_ == null) {
+          ensurePropertyIsMutable();
+          super.addAll(values, property_);
+          onChanged();
+        } else {
+          propertyBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public Builder clearProperty() {
+        if (propertyBuilder_ == null) {
+          property_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          propertyBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public Builder removeProperty(int index) {
+        if (propertyBuilder_ == null) {
+          ensurePropertyIsMutable();
+          property_.remove(index);
+          onChanged();
+        } else {
+          propertyBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Builder getPropertyBuilder(
+          int index) {
+        return getPropertyFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBufOrBuilder getPropertyOrBuilder(
+          int index) {
+        if (propertyBuilder_ == null) {
+          return property_.get(index);  } else {
+          return propertyBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public java.util.List<? extends com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBufOrBuilder> 
+           getPropertyOrBuilderList() {
+        if (propertyBuilder_ != null) {
+          return propertyBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(property_);
+        }
+      }
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Builder addPropertyBuilder() {
+        return getPropertyFieldBuilder().addBuilder(
+            com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Builder addPropertyBuilder(
+          int index) {
+        return getPropertyFieldBuilder().addBuilder(
+            index, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .RamCloudGraph.PropertyProtoBuf property = 1;</code>
+       */
+      public java.util.List<com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Builder> 
+           getPropertyBuilderList() {
+        return getPropertyFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilder<
+          com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Builder, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBufOrBuilder> 
+          getPropertyFieldBuilder() {
+        if (propertyBuilder_ == null) {
+          propertyBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+              com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Builder, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBufOrBuilder>(
+                  property_,
+                  ((bitField0_ & 0x00000001) == 0x00000001),
+                  getParentForChildren(),
+                  isClean());
+          property_ = null;
+        }
+        return propertyBuilder_;
+      }
+
+      // @@protoc_insertion_point(builder_scope:RamCloudGraph.PropertyListProtoBuf)
+    }
+
+    static {
+      defaultInstance = new PropertyListProtoBuf(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:RamCloudGraph.PropertyListProtoBuf)
+  }
+
+  public interface PropertyProtoBufOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required string key = 1;
+    /**
+     * <code>required string key = 1;</code>
+     */
+    boolean hasKey();
+    /**
+     * <code>required string key = 1;</code>
+     */
+    java.lang.String getKey();
+    /**
+     * <code>required string key = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getKeyBytes();
+
+    // required .RamCloudGraph.PropertyProtoBuf.Type value_type = 2;
+    /**
+     * <code>required .RamCloudGraph.PropertyProtoBuf.Type value_type = 2;</code>
+     */
+    boolean hasValueType();
+    /**
+     * <code>required .RamCloudGraph.PropertyProtoBuf.Type value_type = 2;</code>
+     */
+    com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Type getValueType();
+
+    // optional string string_value = 3;
+    /**
+     * <code>optional string string_value = 3;</code>
+     */
+    boolean hasStringValue();
+    /**
+     * <code>optional string string_value = 3;</code>
+     */
+    java.lang.String getStringValue();
+    /**
+     * <code>optional string string_value = 3;</code>
+     */
+    com.google.protobuf.ByteString
+        getStringValueBytes();
+
+    // optional int32 int32_value = 4;
+    /**
+     * <code>optional int32 int32_value = 4;</code>
+     */
+    boolean hasInt32Value();
+    /**
+     * <code>optional int32 int32_value = 4;</code>
+     */
+    int getInt32Value();
+
+    // optional int64 int64_value = 5;
+    /**
+     * <code>optional int64 int64_value = 5;</code>
+     */
+    boolean hasInt64Value();
+    /**
+     * <code>optional int64 int64_value = 5;</code>
+     */
+    long getInt64Value();
+
+    // optional double double_value = 6;
+    /**
+     * <code>optional double double_value = 6;</code>
+     */
+    boolean hasDoubleValue();
+    /**
+     * <code>optional double double_value = 6;</code>
+     */
+    double getDoubleValue();
+
+    // optional float float_value = 7;
+    /**
+     * <code>optional float float_value = 7;</code>
+     */
+    boolean hasFloatValue();
+    /**
+     * <code>optional float float_value = 7;</code>
+     */
+    float getFloatValue();
+
+    // optional bool bool_value = 8;
+    /**
+     * <code>optional bool bool_value = 8;</code>
+     */
+    boolean hasBoolValue();
+    /**
+     * <code>optional bool bool_value = 8;</code>
+     */
+    boolean getBoolValue();
+  }
+  /**
+   * Protobuf type {@code RamCloudGraph.PropertyProtoBuf}
+   */
+  public static final class PropertyProtoBuf extends
+      com.google.protobuf.GeneratedMessage
+      implements PropertyProtoBufOrBuilder {
+    // Use PropertyProtoBuf.newBuilder() to construct.
+    private PropertyProtoBuf(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private PropertyProtoBuf(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final PropertyProtoBuf defaultInstance;
+    public static PropertyProtoBuf getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public PropertyProtoBuf getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private PropertyProtoBuf(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              bitField0_ |= 0x00000001;
+              key_ = input.readBytes();
+              break;
+            }
+            case 16: {
+              int rawValue = input.readEnum();
+              com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Type value = com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Type.valueOf(rawValue);
+              if (value == null) {
+                unknownFields.mergeVarintField(2, rawValue);
+              } else {
+                bitField0_ |= 0x00000002;
+                valueType_ = value;
+              }
+              break;
+            }
+            case 26: {
+              bitField0_ |= 0x00000004;
+              stringValue_ = input.readBytes();
+              break;
+            }
+            case 32: {
+              bitField0_ |= 0x00000008;
+              int32Value_ = input.readInt32();
+              break;
+            }
+            case 40: {
+              bitField0_ |= 0x00000010;
+              int64Value_ = input.readInt64();
+              break;
+            }
+            case 49: {
+              bitField0_ |= 0x00000020;
+              doubleValue_ = input.readDouble();
+              break;
+            }
+            case 61: {
+              bitField0_ |= 0x00000040;
+              floatValue_ = input.readFloat();
+              break;
+            }
+            case 64: {
+              bitField0_ |= 0x00000080;
+              boolValue_ = input.readBool();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_PropertyProtoBuf_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_PropertyProtoBuf_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.class, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<PropertyProtoBuf> PARSER =
+        new com.google.protobuf.AbstractParser<PropertyProtoBuf>() {
+      public PropertyProtoBuf parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new PropertyProtoBuf(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<PropertyProtoBuf> getParserForType() {
+      return PARSER;
+    }
+
+    /**
+     * Protobuf enum {@code RamCloudGraph.PropertyProtoBuf.Type}
+     */
+    public enum Type
+        implements com.google.protobuf.ProtocolMessageEnum {
+      /**
+       * <code>STRING = 1;</code>
+       */
+      STRING(0, 1),
+      /**
+       * <code>INT32 = 2;</code>
+       */
+      INT32(1, 2),
+      /**
+       * <code>INT64 = 3;</code>
+       */
+      INT64(2, 3),
+      /**
+       * <code>DOUBLE = 4;</code>
+       */
+      DOUBLE(3, 4),
+      /**
+       * <code>FLOAT = 5;</code>
+       */
+      FLOAT(4, 5),
+      /**
+       * <code>BOOL = 6;</code>
+       */
+      BOOL(5, 6),
+      ;
+
+      /**
+       * <code>STRING = 1;</code>
+       */
+      public static final int STRING_VALUE = 1;
+      /**
+       * <code>INT32 = 2;</code>
+       */
+      public static final int INT32_VALUE = 2;
+      /**
+       * <code>INT64 = 3;</code>
+       */
+      public static final int INT64_VALUE = 3;
+      /**
+       * <code>DOUBLE = 4;</code>
+       */
+      public static final int DOUBLE_VALUE = 4;
+      /**
+       * <code>FLOAT = 5;</code>
+       */
+      public static final int FLOAT_VALUE = 5;
+      /**
+       * <code>BOOL = 6;</code>
+       */
+      public static final int BOOL_VALUE = 6;
+
+
+      public final int getNumber() { return value; }
+
+      public static Type valueOf(int value) {
+        switch (value) {
+          case 1: return STRING;
+          case 2: return INT32;
+          case 3: return INT64;
+          case 4: return DOUBLE;
+          case 5: return FLOAT;
+          case 6: return BOOL;
+          default: return null;
+        }
+      }
+
+      public static com.google.protobuf.Internal.EnumLiteMap<Type>
+          internalGetValueMap() {
+        return internalValueMap;
+      }
+      private static com.google.protobuf.Internal.EnumLiteMap<Type>
+          internalValueMap =
+            new com.google.protobuf.Internal.EnumLiteMap<Type>() {
+              public Type findValueByNumber(int number) {
+                return Type.valueOf(number);
+              }
+            };
+
+      public final com.google.protobuf.Descriptors.EnumValueDescriptor
+          getValueDescriptor() {
+        return getDescriptor().getValues().get(index);
+      }
+      public final com.google.protobuf.Descriptors.EnumDescriptor
+          getDescriptorForType() {
+        return getDescriptor();
+      }
+      public static final com.google.protobuf.Descriptors.EnumDescriptor
+          getDescriptor() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.getDescriptor().getEnumTypes().get(0);
+      }
+
+      private static final Type[] VALUES = values();
+
+      public static Type valueOf(
+          com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+        if (desc.getType() != getDescriptor()) {
+          throw new java.lang.IllegalArgumentException(
+            "EnumValueDescriptor is not for this type.");
+        }
+        return VALUES[desc.getIndex()];
+      }
+
+      private final int index;
+      private final int value;
+
+      private Type(int index, int value) {
+        this.index = index;
+        this.value = value;
+      }
+
+      // @@protoc_insertion_point(enum_scope:RamCloudGraph.PropertyProtoBuf.Type)
+    }
+
+    private int bitField0_;
+    // required string key = 1;
+    public static final int KEY_FIELD_NUMBER = 1;
+    private java.lang.Object key_;
+    /**
+     * <code>required string key = 1;</code>
+     */
+    public boolean hasKey() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required string key = 1;</code>
+     */
+    public java.lang.String getKey() {
+      java.lang.Object ref = key_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          key_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>required string key = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getKeyBytes() {
+      java.lang.Object ref = key_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        key_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // required .RamCloudGraph.PropertyProtoBuf.Type value_type = 2;
+    public static final int VALUE_TYPE_FIELD_NUMBER = 2;
+    private com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Type valueType_;
+    /**
+     * <code>required .RamCloudGraph.PropertyProtoBuf.Type value_type = 2;</code>
+     */
+    public boolean hasValueType() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required .RamCloudGraph.PropertyProtoBuf.Type value_type = 2;</code>
+     */
+    public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Type getValueType() {
+      return valueType_;
+    }
+
+    // optional string string_value = 3;
+    public static final int STRING_VALUE_FIELD_NUMBER = 3;
+    private java.lang.Object stringValue_;
+    /**
+     * <code>optional string string_value = 3;</code>
+     */
+    public boolean hasStringValue() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>optional string string_value = 3;</code>
+     */
+    public java.lang.String getStringValue() {
+      java.lang.Object ref = stringValue_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          stringValue_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string string_value = 3;</code>
+     */
+    public com.google.protobuf.ByteString
+        getStringValueBytes() {
+      java.lang.Object ref = stringValue_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        stringValue_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // optional int32 int32_value = 4;
+    public static final int INT32_VALUE_FIELD_NUMBER = 4;
+    private int int32Value_;
+    /**
+     * <code>optional int32 int32_value = 4;</code>
+     */
+    public boolean hasInt32Value() {
+      return ((bitField0_ & 0x00000008) == 0x00000008);
+    }
+    /**
+     * <code>optional int32 int32_value = 4;</code>
+     */
+    public int getInt32Value() {
+      return int32Value_;
+    }
+
+    // optional int64 int64_value = 5;
+    public static final int INT64_VALUE_FIELD_NUMBER = 5;
+    private long int64Value_;
+    /**
+     * <code>optional int64 int64_value = 5;</code>
+     */
+    public boolean hasInt64Value() {
+      return ((bitField0_ & 0x00000010) == 0x00000010);
+    }
+    /**
+     * <code>optional int64 int64_value = 5;</code>
+     */
+    public long getInt64Value() {
+      return int64Value_;
+    }
+
+    // optional double double_value = 6;
+    public static final int DOUBLE_VALUE_FIELD_NUMBER = 6;
+    private double doubleValue_;
+    /**
+     * <code>optional double double_value = 6;</code>
+     */
+    public boolean hasDoubleValue() {
+      return ((bitField0_ & 0x00000020) == 0x00000020);
+    }
+    /**
+     * <code>optional double double_value = 6;</code>
+     */
+    public double getDoubleValue() {
+      return doubleValue_;
+    }
+
+    // optional float float_value = 7;
+    public static final int FLOAT_VALUE_FIELD_NUMBER = 7;
+    private float floatValue_;
+    /**
+     * <code>optional float float_value = 7;</code>
+     */
+    public boolean hasFloatValue() {
+      return ((bitField0_ & 0x00000040) == 0x00000040);
+    }
+    /**
+     * <code>optional float float_value = 7;</code>
+     */
+    public float getFloatValue() {
+      return floatValue_;
+    }
+
+    // optional bool bool_value = 8;
+    public static final int BOOL_VALUE_FIELD_NUMBER = 8;
+    private boolean boolValue_;
+    /**
+     * <code>optional bool bool_value = 8;</code>
+     */
+    public boolean hasBoolValue() {
+      return ((bitField0_ & 0x00000080) == 0x00000080);
+    }
+    /**
+     * <code>optional bool bool_value = 8;</code>
+     */
+    public boolean getBoolValue() {
+      return boolValue_;
+    }
+
+    private void initFields() {
+      key_ = "";
+      valueType_ = com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Type.STRING;
+      stringValue_ = "";
+      int32Value_ = 0;
+      int64Value_ = 0L;
+      doubleValue_ = 0D;
+      floatValue_ = 0F;
+      boolValue_ = false;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasKey()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasValueType()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeBytes(1, getKeyBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeEnum(2, valueType_.getNumber());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeBytes(3, getStringValueBytes());
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        output.writeInt32(4, int32Value_);
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        output.writeInt64(5, int64Value_);
+      }
+      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+        output.writeDouble(6, doubleValue_);
+      }
+      if (((bitField0_ & 0x00000040) == 0x00000040)) {
+        output.writeFloat(7, floatValue_);
+      }
+      if (((bitField0_ & 0x00000080) == 0x00000080)) {
+        output.writeBool(8, boolValue_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getKeyBytes());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeEnumSize(2, valueType_.getNumber());
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(3, getStringValueBytes());
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(4, int32Value_);
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(5, int64Value_);
+      }
+      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeDoubleSize(6, doubleValue_);
+      }
+      if (((bitField0_ & 0x00000040) == 0x00000040)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(7, floatValue_);
+      }
+      if (((bitField0_ & 0x00000080) == 0x00000080)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(8, boolValue_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code RamCloudGraph.PropertyProtoBuf}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBufOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_PropertyProtoBuf_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_PropertyProtoBuf_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.class, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Builder.class);
+      }
+
+      // Construct using com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        key_ = "";
+        bitField0_ = (bitField0_ & ~0x00000001);
+        valueType_ = com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Type.STRING;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        stringValue_ = "";
+        bitField0_ = (bitField0_ & ~0x00000004);
+        int32Value_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000008);
+        int64Value_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000010);
+        doubleValue_ = 0D;
+        bitField0_ = (bitField0_ & ~0x00000020);
+        floatValue_ = 0F;
+        bitField0_ = (bitField0_ & ~0x00000040);
+        boolValue_ = false;
+        bitField0_ = (bitField0_ & ~0x00000080);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_PropertyProtoBuf_descriptor;
+      }
+
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf getDefaultInstanceForType() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.getDefaultInstance();
+      }
+
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf build() {
+        com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf buildPartial() {
+        com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf result = new com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.key_ = key_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.valueType_ = valueType_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.stringValue_ = stringValue_;
+        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+          to_bitField0_ |= 0x00000008;
+        }
+        result.int32Value_ = int32Value_;
+        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+          to_bitField0_ |= 0x00000010;
+        }
+        result.int64Value_ = int64Value_;
+        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
+          to_bitField0_ |= 0x00000020;
+        }
+        result.doubleValue_ = doubleValue_;
+        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
+          to_bitField0_ |= 0x00000040;
+        }
+        result.floatValue_ = floatValue_;
+        if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
+          to_bitField0_ |= 0x00000080;
+        }
+        result.boolValue_ = boolValue_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf) {
+          return mergeFrom((com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf other) {
+        if (other == com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.getDefaultInstance()) return this;
+        if (other.hasKey()) {
+          bitField0_ |= 0x00000001;
+          key_ = other.key_;
+          onChanged();
+        }
+        if (other.hasValueType()) {
+          setValueType(other.getValueType());
+        }
+        if (other.hasStringValue()) {
+          bitField0_ |= 0x00000004;
+          stringValue_ = other.stringValue_;
+          onChanged();
+        }
+        if (other.hasInt32Value()) {
+          setInt32Value(other.getInt32Value());
+        }
+        if (other.hasInt64Value()) {
+          setInt64Value(other.getInt64Value());
+        }
+        if (other.hasDoubleValue()) {
+          setDoubleValue(other.getDoubleValue());
+        }
+        if (other.hasFloatValue()) {
+          setFloatValue(other.getFloatValue());
+        }
+        if (other.hasBoolValue()) {
+          setBoolValue(other.getBoolValue());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasKey()) {
+          
+          return false;
+        }
+        if (!hasValueType()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required string key = 1;
+      private java.lang.Object key_ = "";
+      /**
+       * <code>required string key = 1;</code>
+       */
+      public boolean hasKey() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required string key = 1;</code>
+       */
+      public java.lang.String getKey() {
+        java.lang.Object ref = key_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          key_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>required string key = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getKeyBytes() {
+        java.lang.Object ref = key_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          key_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>required string key = 1;</code>
+       */
+      public Builder setKey(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        key_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string key = 1;</code>
+       */
+      public Builder clearKey() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        key_ = getDefaultInstance().getKey();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required string key = 1;</code>
+       */
+      public Builder setKeyBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        key_ = value;
+        onChanged();
+        return this;
+      }
+
+      // required .RamCloudGraph.PropertyProtoBuf.Type value_type = 2;
+      private com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Type valueType_ = com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Type.STRING;
+      /**
+       * <code>required .RamCloudGraph.PropertyProtoBuf.Type value_type = 2;</code>
+       */
+      public boolean hasValueType() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required .RamCloudGraph.PropertyProtoBuf.Type value_type = 2;</code>
+       */
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Type getValueType() {
+        return valueType_;
+      }
+      /**
+       * <code>required .RamCloudGraph.PropertyProtoBuf.Type value_type = 2;</code>
+       */
+      public Builder setValueType(com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Type value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        bitField0_ |= 0x00000002;
+        valueType_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required .RamCloudGraph.PropertyProtoBuf.Type value_type = 2;</code>
+       */
+      public Builder clearValueType() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        valueType_ = com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.PropertyProtoBuf.Type.STRING;
+        onChanged();
+        return this;
+      }
+
+      // optional string string_value = 3;
+      private java.lang.Object stringValue_ = "";
+      /**
+       * <code>optional string string_value = 3;</code>
+       */
+      public boolean hasStringValue() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>optional string string_value = 3;</code>
+       */
+      public java.lang.String getStringValue() {
+        java.lang.Object ref = stringValue_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          stringValue_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string string_value = 3;</code>
+       */
+      public com.google.protobuf.ByteString
+          getStringValueBytes() {
+        java.lang.Object ref = stringValue_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          stringValue_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string string_value = 3;</code>
+       */
+      public Builder setStringValue(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000004;
+        stringValue_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string string_value = 3;</code>
+       */
+      public Builder clearStringValue() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        stringValue_ = getDefaultInstance().getStringValue();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string string_value = 3;</code>
+       */
+      public Builder setStringValueBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000004;
+        stringValue_ = value;
+        onChanged();
+        return this;
+      }
+
+      // optional int32 int32_value = 4;
+      private int int32Value_ ;
+      /**
+       * <code>optional int32 int32_value = 4;</code>
+       */
+      public boolean hasInt32Value() {
+        return ((bitField0_ & 0x00000008) == 0x00000008);
+      }
+      /**
+       * <code>optional int32 int32_value = 4;</code>
+       */
+      public int getInt32Value() {
+        return int32Value_;
+      }
+      /**
+       * <code>optional int32 int32_value = 4;</code>
+       */
+      public Builder setInt32Value(int value) {
+        bitField0_ |= 0x00000008;
+        int32Value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int32 int32_value = 4;</code>
+       */
+      public Builder clearInt32Value() {
+        bitField0_ = (bitField0_ & ~0x00000008);
+        int32Value_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // optional int64 int64_value = 5;
+      private long int64Value_ ;
+      /**
+       * <code>optional int64 int64_value = 5;</code>
+       */
+      public boolean hasInt64Value() {
+        return ((bitField0_ & 0x00000010) == 0x00000010);
+      }
+      /**
+       * <code>optional int64 int64_value = 5;</code>
+       */
+      public long getInt64Value() {
+        return int64Value_;
+      }
+      /**
+       * <code>optional int64 int64_value = 5;</code>
+       */
+      public Builder setInt64Value(long value) {
+        bitField0_ |= 0x00000010;
+        int64Value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int64 int64_value = 5;</code>
+       */
+      public Builder clearInt64Value() {
+        bitField0_ = (bitField0_ & ~0x00000010);
+        int64Value_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // optional double double_value = 6;
+      private double doubleValue_ ;
+      /**
+       * <code>optional double double_value = 6;</code>
+       */
+      public boolean hasDoubleValue() {
+        return ((bitField0_ & 0x00000020) == 0x00000020);
+      }
+      /**
+       * <code>optional double double_value = 6;</code>
+       */
+      public double getDoubleValue() {
+        return doubleValue_;
+      }
+      /**
+       * <code>optional double double_value = 6;</code>
+       */
+      public Builder setDoubleValue(double value) {
+        bitField0_ |= 0x00000020;
+        doubleValue_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional double double_value = 6;</code>
+       */
+      public Builder clearDoubleValue() {
+        bitField0_ = (bitField0_ & ~0x00000020);
+        doubleValue_ = 0D;
+        onChanged();
+        return this;
+      }
+
+      // optional float float_value = 7;
+      private float floatValue_ ;
+      /**
+       * <code>optional float float_value = 7;</code>
+       */
+      public boolean hasFloatValue() {
+        return ((bitField0_ & 0x00000040) == 0x00000040);
+      }
+      /**
+       * <code>optional float float_value = 7;</code>
+       */
+      public float getFloatValue() {
+        return floatValue_;
+      }
+      /**
+       * <code>optional float float_value = 7;</code>
+       */
+      public Builder setFloatValue(float value) {
+        bitField0_ |= 0x00000040;
+        floatValue_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional float float_value = 7;</code>
+       */
+      public Builder clearFloatValue() {
+        bitField0_ = (bitField0_ & ~0x00000040);
+        floatValue_ = 0F;
+        onChanged();
+        return this;
+      }
+
+      // optional bool bool_value = 8;
+      private boolean boolValue_ ;
+      /**
+       * <code>optional bool bool_value = 8;</code>
+       */
+      public boolean hasBoolValue() {
+        return ((bitField0_ & 0x00000080) == 0x00000080);
+      }
+      /**
+       * <code>optional bool bool_value = 8;</code>
+       */
+      public boolean getBoolValue() {
+        return boolValue_;
+      }
+      /**
+       * <code>optional bool bool_value = 8;</code>
+       */
+      public Builder setBoolValue(boolean value) {
+        bitField0_ |= 0x00000080;
+        boolValue_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bool bool_value = 8;</code>
+       */
+      public Builder clearBoolValue() {
+        bitField0_ = (bitField0_ & ~0x00000080);
+        boolValue_ = false;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:RamCloudGraph.PropertyProtoBuf)
+    }
+
+    static {
+      defaultInstance = new PropertyProtoBuf(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:RamCloudGraph.PropertyProtoBuf)
+  }
+
+  public interface IndexBlobOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // repeated int64 vertexId = 1;
+    /**
+     * <code>repeated int64 vertexId = 1;</code>
+     */
+    java.util.List<java.lang.Long> getVertexIdList();
+    /**
+     * <code>repeated int64 vertexId = 1;</code>
+     */
+    int getVertexIdCount();
+    /**
+     * <code>repeated int64 vertexId = 1;</code>
+     */
+    long getVertexId(int index);
+  }
+  /**
+   * Protobuf type {@code RamCloudGraph.IndexBlob}
+   */
+  public static final class IndexBlob extends
+      com.google.protobuf.GeneratedMessage
+      implements IndexBlobOrBuilder {
+    // Use IndexBlob.newBuilder() to construct.
+    private IndexBlob(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private IndexBlob(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final IndexBlob defaultInstance;
+    public static IndexBlob getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public IndexBlob getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private IndexBlob(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 8: {
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                vertexId_ = new java.util.ArrayList<java.lang.Long>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              vertexId_.add(input.readInt64());
+              break;
+            }
+            case 10: {
+              int length = input.readRawVarint32();
+              int limit = input.pushLimit(length);
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001) && input.getBytesUntilLimit() > 0) {
+                vertexId_ = new java.util.ArrayList<java.lang.Long>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              while (input.getBytesUntilLimit() > 0) {
+                vertexId_.add(input.readInt64());
+              }
+              input.popLimit(limit);
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+          vertexId_ = java.util.Collections.unmodifiableList(vertexId_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_IndexBlob_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_IndexBlob_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob.class, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<IndexBlob> PARSER =
+        new com.google.protobuf.AbstractParser<IndexBlob>() {
+      public IndexBlob parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new IndexBlob(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<IndexBlob> getParserForType() {
+      return PARSER;
+    }
+
+    // repeated int64 vertexId = 1;
+    public static final int VERTEXID_FIELD_NUMBER = 1;
+    private java.util.List<java.lang.Long> vertexId_;
+    /**
+     * <code>repeated int64 vertexId = 1;</code>
+     */
+    public java.util.List<java.lang.Long>
+        getVertexIdList() {
+      return vertexId_;
+    }
+    /**
+     * <code>repeated int64 vertexId = 1;</code>
+     */
+    public int getVertexIdCount() {
+      return vertexId_.size();
+    }
+    /**
+     * <code>repeated int64 vertexId = 1;</code>
+     */
+    public long getVertexId(int index) {
+      return vertexId_.get(index);
+    }
+
+    private void initFields() {
+      vertexId_ = java.util.Collections.emptyList();
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      for (int i = 0; i < vertexId_.size(); i++) {
+        output.writeInt64(1, vertexId_.get(i));
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      {
+        int dataSize = 0;
+        for (int i = 0; i < vertexId_.size(); i++) {
+          dataSize += com.google.protobuf.CodedOutputStream
+            .computeInt64SizeNoTag(vertexId_.get(i));
+        }
+        size += dataSize;
+        size += 1 * getVertexIdList().size();
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code RamCloudGraph.IndexBlob}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlobOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_IndexBlob_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_IndexBlob_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob.class, com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob.Builder.class);
+      }
+
+      // Construct using com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        vertexId_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.internal_static_RamCloudGraph_IndexBlob_descriptor;
+      }
+
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob getDefaultInstanceForType() {
+        return com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob.getDefaultInstance();
+      }
+
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob build() {
+        com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob buildPartial() {
+        com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob result = new com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob(this);
+        int from_bitField0_ = bitField0_;
+        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          vertexId_ = java.util.Collections.unmodifiableList(vertexId_);
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.vertexId_ = vertexId_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob) {
+          return mergeFrom((com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob other) {
+        if (other == com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob.getDefaultInstance()) return this;
+        if (!other.vertexId_.isEmpty()) {
+          if (vertexId_.isEmpty()) {
+            vertexId_ = other.vertexId_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+            ensureVertexIdIsMutable();
+            vertexId_.addAll(other.vertexId_);
+          }
+          onChanged();
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // repeated int64 vertexId = 1;
+      private java.util.List<java.lang.Long> vertexId_ = java.util.Collections.emptyList();
+      private void ensureVertexIdIsMutable() {
+        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+          vertexId_ = new java.util.ArrayList<java.lang.Long>(vertexId_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+      /**
+       * <code>repeated int64 vertexId = 1;</code>
+       */
+      public java.util.List<java.lang.Long>
+          getVertexIdList() {
+        return java.util.Collections.unmodifiableList(vertexId_);
+      }
+      /**
+       * <code>repeated int64 vertexId = 1;</code>
+       */
+      public int getVertexIdCount() {
+        return vertexId_.size();
+      }
+      /**
+       * <code>repeated int64 vertexId = 1;</code>
+       */
+      public long getVertexId(int index) {
+        return vertexId_.get(index);
+      }
+      /**
+       * <code>repeated int64 vertexId = 1;</code>
+       */
+      public Builder setVertexId(
+          int index, long value) {
+        ensureVertexIdIsMutable();
+        vertexId_.set(index, value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated int64 vertexId = 1;</code>
+       */
+      public Builder addVertexId(long value) {
+        ensureVertexIdIsMutable();
+        vertexId_.add(value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated int64 vertexId = 1;</code>
+       */
+      public Builder addAllVertexId(
+          java.lang.Iterable<? extends java.lang.Long> values) {
+        ensureVertexIdIsMutable();
+        super.addAll(values, vertexId_);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated int64 vertexId = 1;</code>
+       */
+      public Builder clearVertexId() {
+        vertexId_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:RamCloudGraph.IndexBlob)
+    }
+
+    static {
+      defaultInstance = new IndexBlob(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:RamCloudGraph.IndexBlob)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_RamCloudGraph_EdgeListProtoBuf_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_RamCloudGraph_EdgeListProtoBuf_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_RamCloudGraph_EdgeProtoBuf_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_RamCloudGraph_EdgeProtoBuf_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_RamCloudGraph_PropertyListProtoBuf_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_RamCloudGraph_PropertyListProtoBuf_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_RamCloudGraph_PropertyProtoBuf_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_RamCloudGraph_PropertyProtoBuf_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_RamCloudGraph_IndexBlob_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_RamCloudGraph_IndexBlob_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\023ramcloudgraph.proto\022\rRamCloudGraph\"=\n\020" +
+      "EdgeListProtoBuf\022)\n\004edge\030\001 \003(\0132\033.RamClou" +
+      "dGraph.EdgeProtoBuf\"C\n\014EdgeProtoBuf\022\022\n\nn" +
+      "eighborId\030\001 \002(\004\022\020\n\010outgoing\030\002 \002(\010\022\r\n\005lab" +
+      "el\030\003 \002(\t\"I\n\024PropertyListProtoBuf\0221\n\010prop" +
+      "erty\030\001 \003(\0132\037.RamCloudGraph.PropertyProto" +
+      "Buf\"\243\002\n\020PropertyProtoBuf\022\013\n\003key\030\001 \002(\t\0228\n" +
+      "\nvalue_type\030\002 \002(\0162$.RamCloudGraph.Proper" +
+      "tyProtoBuf.Type\022\024\n\014string_value\030\003 \001(\t\022\023\n" +
+      "\013int32_value\030\004 \001(\005\022\023\n\013int64_value\030\005 \001(\003\022",
+      "\024\n\014double_value\030\006 \001(\001\022\023\n\013float_value\030\007 \001" +
+      "(\002\022\022\n\nbool_value\030\010 \001(\010\"I\n\004Type\022\n\n\006STRING" +
+      "\020\001\022\t\n\005INT32\020\002\022\t\n\005INT64\020\003\022\n\n\006DOUBLE\020\004\022\t\n\005" +
+      "FLOAT\020\005\022\010\n\004BOOL\020\006\"\035\n\tIndexBlob\022\020\n\010vertex" +
+      "Id\030\001 \003(\003B>\n\'com.tinkerpop.blueprints.imp" +
+      "ls.ramcloudB\023RamCloudGraphProtos"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_RamCloudGraph_EdgeListProtoBuf_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_RamCloudGraph_EdgeListProtoBuf_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_RamCloudGraph_EdgeListProtoBuf_descriptor,
+              new java.lang.String[] { "Edge", });
+          internal_static_RamCloudGraph_EdgeProtoBuf_descriptor =
+            getDescriptor().getMessageTypes().get(1);
+          internal_static_RamCloudGraph_EdgeProtoBuf_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_RamCloudGraph_EdgeProtoBuf_descriptor,
+              new java.lang.String[] { "NeighborId", "Outgoing", "Label", });
+          internal_static_RamCloudGraph_PropertyListProtoBuf_descriptor =
+            getDescriptor().getMessageTypes().get(2);
+          internal_static_RamCloudGraph_PropertyListProtoBuf_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_RamCloudGraph_PropertyListProtoBuf_descriptor,
+              new java.lang.String[] { "Property", });
+          internal_static_RamCloudGraph_PropertyProtoBuf_descriptor =
+            getDescriptor().getMessageTypes().get(3);
+          internal_static_RamCloudGraph_PropertyProtoBuf_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_RamCloudGraph_PropertyProtoBuf_descriptor,
+              new java.lang.String[] { "Key", "ValueType", "StringValue", "Int32Value", "Int64Value", "DoubleValue", "FloatValue", "BoolValue", });
+          internal_static_RamCloudGraph_IndexBlob_descriptor =
+            getDescriptor().getMessageTypes().get(4);
+          internal_static_RamCloudGraph_IndexBlob_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_RamCloudGraph_IndexBlob_descriptor,
+              new java.lang.String[] { "VertexId", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudIndex.java b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudIndex.java
new file mode 100644
index 0000000..0ba951d
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudIndex.java
@@ -0,0 +1,550 @@
+/* Copyright (c) 2013 Stanford University
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package com.tinkerpop.blueprints.impls.ramcloud;
+
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.tinkerpop.blueprints.CloseableIterable;
+import com.tinkerpop.blueprints.Element;
+import com.tinkerpop.blueprints.Index;
+import com.tinkerpop.blueprints.util.ExceptionFactory;
+import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
+import com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob;
+import com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.IndexBlob.Builder;
+
+import edu.stanford.ramcloud.JRamCloud;
+
+// FIXME Index instance should be representing an Index table, not a IndexTable K-V pair
+public class RamCloudIndex<T extends Element> implements Index<T>, Serializable {
+
+    private final static Logger log = LoggerFactory.getLogger(RamCloudGraph.class);
+    protected RamCloudGraph graph;
+    private long tableId;
+    private String indexName;
+    protected byte[] rcKey;
+    private Class<T> indexClass;
+    // FIXME this should not be defined here
+    private long indexVersion;
+
+//    private static final ThreadLocal<Kryo> kryo = new ThreadLocal<Kryo>() {
+//        @Override
+//        protected Kryo initialValue() {
+//                 Kryo kryo = new Kryo();
+//                 kryo.setRegistrationRequired(true);
+//                 kryo.register(Long.class);
+//                 kryo.register(String.class);
+//                 kryo.register(TreeMap.class);
+//                 kryo.register(ArrayList.class);
+//                 kryo.setReferences(false);
+//                 return kryo;
+//        }
+//    };
+
+
+    public RamCloudIndex(long tableId, String indexName, Object propValue, RamCloudGraph graph, Class<T> indexClass) {
+	this.tableId = tableId;
+	this.graph = graph;
+	this.rcKey = indexToRcKey(indexName, propValue);
+	this.indexName = indexName;
+	this.indexClass = indexClass;
+    }
+
+    public RamCloudIndex(long tableId, byte[] rcKey, RamCloudGraph graph, Class<T> indexClass) {
+	this.tableId = tableId;
+	this.graph = graph;
+	this.rcKey = rcKey;
+	this.indexName = rcKeyToIndexName(rcKey);
+	this.indexClass = indexClass;
+    }
+
+    public boolean exists() {
+	PerfMon pm = PerfMon.getInstance();
+
+	try {
+	    JRamCloud.Object vertTableEntry;
+	    JRamCloud vertTable = graph.getRcClient();
+
+	    //vertTableEntry = graph.getRcClient().read(tableId, rcKey);
+	    pm.indexread_start("RamCloudIndex exists()");
+	    vertTableEntry = vertTable.read(tableId, rcKey);
+	    pm.indexread_end("RamCloudIndex exists()");
+	    indexVersion = vertTableEntry.version;
+	    return true;
+	} catch (Exception e) {
+	    pm.indexread_end("RamCloudIndex exists()");
+	    log.debug("IndexTable entry for {} does not exists(): {}@{} [{}]", indexName, new String(rcKey), tableId, this);
+	    return false;
+	}
+    }
+
+    public void create() {
+	if (!exists()) {
+	    PerfMon pm = PerfMon.getInstance();
+	    try {
+		JRamCloud rcClient = graph.getRcClient();
+		JRamCloud.RejectRules rules = rcClient.new RejectRules();
+		rules.setExists();
+
+		//graph.getRcClient().writeRule(tableId, rcKey, ByteBuffer.allocate(0).array(), rules);
+		pm.indexwrite_start("RamCloudIndex create()");
+		rcClient.writeRule(tableId, rcKey, ByteBuffer.allocate(0).array(), rules);
+		pm.indexwrite_end("RamCloudIndex create()");
+	    } catch (Exception e) {
+		pm.indexwrite_end("RamCloudIndex create()");
+		log.info(toString() + ": Write create index list: ", e);
+	    }
+	}
+    }
+
+    public static byte[] indexToRcKey(String key, Object propValue) {
+	try {
+	    String s = key + "=" + propValue;
+	    return ByteBuffer.allocate(s.getBytes().length).put(s.getBytes("UTF-8")).array();
+	} catch (UnsupportedEncodingException ex) {
+	    log.error("indexToRcKey({}, {}) failed with exception {}", key, propValue, ex);
+	}
+	return null;
+    }
+
+    public static String rcKeyToIndexName(byte[] rcKey) {
+	try {
+	    String s = new String(rcKey, "UTF-8");
+	    return s.substring(0, s.indexOf('='));
+	} catch (UnsupportedEncodingException ex) {
+	    log.error("rcKeyToIndexName({}) failed with exception {}", rcKey, ex);
+	}
+	return null;
+    }
+    public static String rcKeyToPropName(byte[] rcKey) {
+	try {
+	    String s = new String(rcKey, "UTF-8");
+	    return s.substring(s.indexOf('=')+1);
+	} catch (UnsupportedEncodingException ex) {
+	    log.error("rcKeyToPropName({}) failed with exception {}", rcKey, ex);
+	}
+	return null;
+    }
+
+    @Override
+    public String getIndexName() {
+	return this.indexName;
+    }
+
+    @Override
+    public Class<T> getIndexClass() {
+	return this.indexClass;
+    }
+
+    @Override
+    public void put(String key, Object value, T element) {
+	getSetProperty(key, value, element.getId());
+    }
+
+    public void getSetProperty(String key, Object propValue, Object elmId) {
+	if (elmId == null) {
+	    // FIXME Throw appropriate Exception
+	    log.error("Element Id cannot be null");
+	    return;
+	    //throw ExceptionFactory.vertexIdCanNotBeNull();
+	    //throw ExceptionFactory.edgeIdCanNotBeNull();
+	}
+
+	long startTime = 0;
+	if (graph.measureBPTimeProp == 1) {
+	    startTime = System.nanoTime();
+	}
+
+	create();
+
+	// FIXME give more meaningful loop variable
+	for (int i = 0; i < 100; i++) {
+	    Map<Object, List<Object>> map = readIndexPropertyMapFromDB();
+	    List<Object> values = map.get(propValue);
+	    if (values == null) {
+		values = new ArrayList<Object>();
+		map.put(propValue, values);
+	    }
+	    if (!values.contains(elmId)) {
+		values.add(elmId);
+	    }
+
+            //Masa commented out the following measurement b/c Serialization delay is measured in onvertIndexPropertyMapToRcBytes(map)
+	    //long serStartTime = System.nanoTime();
+	    byte[] rcValue = convertIndexPropertyMapToRcBytes(map);
+	    //if(RamCloudGraph.measureSerializeTimeProp == 1) {
+	    //	long serEndTime = System.nanoTime();
+	    //	log.error("Performance index kryo serialization [id={}] {} size {}", elmId, serEndTime - serStartTime, rcValue.length);
+            //}
+
+	    if (rcValue.length != 0) {
+		if (writeWithRules(rcValue)) {
+		    break;
+		} else {
+		    log.debug("getSetProperty(String {}, Object {}) cond. write failure RETRYING {}", propValue, elmId, i+1);
+		    if (i == 100) {
+			log.error("getSetProperty(String {}, Object {}) cond. write failure Gaveup RETRYING", propValue, elmId);
+		    }
+		}
+	    }
+	}
+
+	if (graph.measureBPTimeProp == 1) {
+	    long endTime = System.nanoTime();
+	    log.error("Performance index setProperty total time {}", endTime - startTime);
+	}
+    }
+
+    @Override
+    public CloseableIterable<T> get(String string, Object value) {
+	// FIXME Do we need this implemented
+	throw new RuntimeException("Not implemented yet");
+	//return getElmIdListForPropValue(value);
+    }
+
+    @Override
+    public CloseableIterable<T> query(String string, Object o) {
+	throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public long count(String key, Object value) {
+	Map<Object, List<Object>> map = readIndexPropertyMapFromDB();
+	List<Object> values = map.get(value);
+	if (null == values) {
+	    return 0;
+	} else {
+	    return values.size();
+	}
+    }
+
+    @Override
+    public void remove(String propName, Object propValue, T element) {
+
+	if (propName == null) {
+	    throw ExceptionFactory.propertyKeyCanNotBeNull();
+	}
+
+	if (propName.equals("")) {
+	    throw ExceptionFactory.propertyKeyCanNotBeEmpty();
+	}
+
+	if (propName.equals("id")) {
+	    throw ExceptionFactory.propertyKeyIdIsReserved();
+	}
+
+	if (!propName.equals(indexName)) {
+	    log.error("Index name mismatch indexName:{}, remove({},{},...). SOMETHING IS WRONG", indexName, propName, propValue);
+	}
+
+	// FIXME better loop variable name
+	final int MAX_RETRYS = 100;
+	for (int i = 0; i < MAX_RETRYS; ++i) {
+	    Map<Object, List<Object>> map = readIndexPropertyMapFromDB();
+
+	    if (map.containsKey(propValue)) {
+		List<Object> idList = map.get(propValue);
+		if (null != idList) {
+		    idList.remove(element.getId());
+		    if (idList.isEmpty()) {
+			log.debug("remove({},{},...) called, and list became empty.", propName, propValue);
+			map.remove(propValue);
+		    }
+		}
+	    } else {
+		// propValue not found
+		log.warn("remove({},{},...) called on '{}' index table, but was not found on index. SOMETHING MAY BE WRONG", propName, propValue, this.indexName);
+		// no change to DB so exit now
+		return;
+	    }
+	    //long startTime = System.nanoTime();
+	    //if(RamCloudGraph.measureSerializeTimeProp == 1) {
+	    //   pm.ser_start("SC");
+	    //}
+	    byte[] rcValue = convertIndexPropertyMapToRcBytes(map);
+	    //if(RamCloudGraph.measureSerializeTimeProp == 1) {
+	    //    pm.ser_end("SC");
+	    	//long endTime = System.nanoTime();
+		//pm.ser_add(endTime - startTime);
+	    	//log.error("Performance index kryo serialization for removal key {} {} size {}", element, endTime - startTime, rcValue.length);
+	    //}
+
+	    if (rcValue.length == 0) {
+		return;
+	    }
+
+	    if (writeWithRules(rcValue)) {
+		break;
+	    } else {
+		log.debug("remove({}, {}, T element) write failure RETRYING {}", propName, propValue, (i + 1));
+		if (i + 1 == MAX_RETRYS) {
+		    log.error("remove({}, {}, T element) write failed completely. gave up RETRYING", propName, propValue);
+		}
+	    }
+	}
+
+    }
+
+    public void removeElement(T element) {
+	removeElement(this.tableId, element, this.graph);
+    }
+
+    // FIXME this methods should not be defined here
+    public <T extends Element> void removeElement(long tableId, T element, RamCloudGraph graph) {
+	JRamCloud.TableEnumerator tableEnum = graph.getRcClient().new TableEnumerator(tableId);
+
+	while (tableEnum.hasNext()) {
+	    JRamCloud.Object tableEntry = tableEnum.next();
+	    Map<Object, List<Object>> indexValMap = convertRcBytesToIndexPropertyMap(tableEntry.value);
+
+	    boolean madeChange = false;
+	    Iterator<Map.Entry<Object, List<Object>>> indexValMapIt = indexValMap.entrySet().iterator();
+	    while (indexValMapIt.hasNext()) {
+		Map.Entry<Object, List<Object>> entry = indexValMapIt.next();
+		List<Object> idList = entry.getValue();
+		madeChange |= idList.remove(element.getId());
+		if (idList.isEmpty()) {
+		    madeChange = true;
+		    indexValMapIt.remove();
+		}
+	    }
+	    if (madeChange == false) {
+		continue;
+	    }
+
+	    byte[] rcValue = convertIndexPropertyMapToRcBytes(indexValMap);
+	    if (rcValue.length == 0) {
+		// nothing to write
+		continue;
+	    }
+	    if (writeWithRules(tableId, tableEntry.key, rcValue, tableEntry.version, graph)) {
+		// cond. write success
+		continue;
+	    } else {
+		// cond. write failure
+		log.debug("removeElement({}, {}, ...) cond. key/value write failure RETRYING", tableId, element );
+		// FIXME Dirty hack
+		final int RETRY_MAX = 100;
+		for (int retry = RETRY_MAX; retry >= 0; --retry) {
+		    RamCloudKeyIndex idx = new RamCloudKeyIndex(tableId, tableEntry.key, graph, element.getClass());
+		    Map<Object, List<Object>> rereadMap = idx.readIndexPropertyMapFromDB();
+
+		    boolean madeChangeOnRetry = false;
+		    Iterator<Map.Entry<Object, List<Object>>> rereadIndexValMapIt = rereadMap.entrySet().iterator();
+		    while (rereadIndexValMapIt.hasNext()) {
+			Map.Entry<Object, List<Object>> entry = rereadIndexValMapIt.next();
+			List<Object> idList = entry.getValue();
+			madeChangeOnRetry |= idList.remove(element.getId());
+			if (idList.isEmpty()) {
+			    madeChangeOnRetry = true;
+			    rereadIndexValMapIt.remove();
+			}
+		    }
+		    if (madeChangeOnRetry == false) {
+			log.debug("removeElement({}, {}, ...) no more write required. SOMETHING MAY BE WRONG", tableId, element);
+			break;
+		    }
+
+		    if (idx.writeWithRules(convertIndexPropertyMapToRcBytes(rereadMap))) {
+			log.debug("removeElement({}, {}, ...) cond. key/value {} write failure RETRYING {}", tableId, element, rereadMap, RETRY_MAX - retry);
+			// cond. re-write success
+			break;
+		    }
+		    if (retry == 0) {
+			log.error("removeElement({}, {}, ...) cond. write failed completely. Gave up RETRYING", tableId, element);
+			// XXX may be we should throw some kind of exception here?
+		    }
+		}
+	    }
+	}
+    }
+
+    public Map<Object, List<Object>> readIndexPropertyMapFromDB() {
+	//log.debug("getIndexPropertyMap() ");
+	JRamCloud.Object propTableEntry;
+	long startTime = 0;
+	PerfMon pm = PerfMon.getInstance();
+
+	try {
+	    JRamCloud vertTable = graph.getRcClient();
+	    if (graph.measureRcTimeProp == 1) {
+		startTime = System.nanoTime();
+	    }
+	    //propTableEntry = graph.getRcClient().read(tableId, rcKey);
+	    pm.indexread_start("RamCloudIndex readIndexPropertyMapFromDB()");
+	    propTableEntry = vertTable.read(tableId, rcKey);
+	    pm.indexread_end("RamCloudIndex readIndexPropertyMapFromDB()");
+	    if (graph.measureRcTimeProp == 1) {
+		long endTime = System.nanoTime();
+		log.error("Performance readIndexPropertyMapFromDB(indexName {}) read time {}", indexName, endTime - startTime);
+	    }
+	    indexVersion = propTableEntry.version;
+	} catch (Exception e) {
+	    pm.indexread_end("RamCloudIndex readIndexPropertyMapFromDB()");
+	    indexVersion = 0;
+	    if (graph.measureRcTimeProp == 1) {
+		long endTime = System.nanoTime();
+		log.error("Performance readIndexPropertyMapFromDB(indexName {}) exception read time {}", indexName, endTime - startTime);
+	    }
+	    log.warn("readIndexPropertyMapFromDB() Element does not have a index property table entry! tableId :" + tableId + " indexName : " + indexName + " ", e);
+	    return null;
+	}
+
+	return convertRcBytesToIndexPropertyMap(propTableEntry.value);
+    }
+
+    public Map<Object, List<Object>> convertRcBytesToIndexPropertyMap(byte[] byteArray) {
+	if (byteArray == null) {
+	    log.error("Got a null byteArray argument");
+	    return null;
+	} else if (byteArray.length != 0) {
+	    PerfMon pm = PerfMon.getInstance();
+            long startTime = 0;
+            if(RamCloudGraph.measureSerializeTimeProp == 1) {
+        	startTime = System.nanoTime();
+            }
+	    pm.indexdeser_start("RamCloudIndex convertRcBytesToIndexPropertyMap()");
+	    IndexBlob blob;
+	    TreeMap<Object, List<Object>> map = new TreeMap<Object, List<Object>>();
+	    try {
+		blob = IndexBlob.parseFrom(byteArray);
+		List const_list = blob.getVertexIdList();
+		ArrayList list = new ArrayList<>(const_list);
+//		ByteBufferInput input = new ByteBufferInput(byteArray);
+//		ArrayList list = kryo.get().readObject(input, ArrayList.class);
+		map.put(rcKeyToPropName(rcKey), list);
+	    } catch (InvalidProtocolBufferException e) {
+		log.error("{" + toString() + "}: Read malformed edge list: ", e);
+	    } finally {
+		pm.indexdeser_end("RamCloudIndex convertRcBytesToIndexPropertyMap()");
+	    }
+            if(RamCloudGraph.measureSerializeTimeProp == 1) {
+            	long endTime = System.nanoTime();
+                log.error("Performance index kryo deserialization [id=N/A] {} size {}", endTime - startTime, byteArray.length);
+            }
+	    return map;
+	} else {
+	    return new TreeMap<Object, List<Object>>();
+	}
+    }
+
+    public static byte[] convertIndexPropertyMapToRcBytes(Map<Object, List<Object>> map) {
+	PerfMon pm = PerfMon.getInstance();
+	long startTime = 0;
+	if(RamCloudGraph.measureSerializeTimeProp == 1) {
+	    startTime = System.nanoTime();
+	}
+	byte[] bytes;
+
+	pm.indexser_start("RamCloudIndex convertIndexPropertyMapToRcBytes()");
+	Builder builder = IndexBlob.newBuilder();
+	if ( map.values().size() != 0 ) {
+		List<Long> vtxIds = (List)map.values().iterator().next();
+		builder.addAllVertexId(vtxIds);
+	}
+	IndexBlob blob = builder.build();
+	bytes = blob.toByteArray();
+//	ByteBufferOutput output = new ByteBufferOutput(1024*1024);
+//	if ( map.values().size() == 0 ) {
+//	    kryo.get().writeObject(output, new ArrayList<Object>());
+//	} else {
+//	    kryo.get().writeObject(output, vtxIds);
+//	}
+//	bytes = output.toBytes();
+        pm.indexser_end("RamCloudIndex convertIndexPropertyMapToRcBytes()");
+	if(RamCloudGraph.measureSerializeTimeProp == 1) {
+        	long endTime = System.nanoTime();
+		log.error("Performance index ProtoBuff serialization {}, size={}", endTime - startTime, bytes);
+	}
+	return bytes;
+    }
+
+    protected boolean writeWithRules(byte[] rcValue) {
+	return writeWithRules(this.tableId, this.rcKey, rcValue, this.indexVersion, this.graph);
+    }
+
+    private static boolean writeWithRules(long tableId, byte[] rcKey, byte[] rcValue, long expectedVersion, RamCloudGraph graph) {
+	JRamCloud.RejectRules rules = graph.getRcClient().new RejectRules();
+
+	if (expectedVersion == 0) {
+	    rules.setExists();
+	} else {
+	    rules.setNeVersion(expectedVersion);
+	}
+
+	PerfMon pm = PerfMon.getInstance();
+	try {
+	    JRamCloud vertTable = graph.getRcClient();
+	    pm.indexwrite_start("RamCloudIndex writeWithRules()");
+	    vertTable.writeRule(tableId, rcKey, rcValue, rules);
+	    pm.indexwrite_end("RamCloudIndex writeWithRules()");
+	} catch (Exception e) {
+            pm.indexwrite_end("RamCloudIndex writeWithRules()");
+            pm.indexwrite_condfail("RamCloudIndex writeWithRules()");
+	    log.debug("Cond. Write index property: {} failed {} expected version: {}", rcKeyToIndexName(rcKey), e, expectedVersion);
+	    return false;
+	}
+	return true;
+    }
+
+    public List<Object> getElmIdListForPropValue(Object propValue) {
+	Map<Object, List<Object>> map = readIndexPropertyMapFromDB();
+	if (map == null) {
+	    log.debug("IndexPropertyMap was null. {} : {}", indexName, propValue);
+	    return null;
+	}
+	return map.get(propValue);
+    }
+
+    public Set<Object> getIndexPropertyKeys() {
+	Map<Object, List<Object>> map = readIndexPropertyMapFromDB();
+	return map.keySet();
+    }
+
+    public <T> T removeIndexProperty(String key) {
+	for (int i = 0; i < 100; ++i) {
+	    Map<Object, List<Object>> map = readIndexPropertyMapFromDB();
+	    T retVal = (T) map.remove(key);
+	    byte[] rcValue = convertIndexPropertyMapToRcBytes(map);
+	    if (rcValue.length != 0) {
+		if (writeWithRules(rcValue)) {
+		    return retVal;
+		} else {
+		    log.debug("removeIndexProperty({}) cond. key/value write failure RETRYING {}", tableId, (i + 1));
+		}
+	    }
+	}
+	log.error("removeIndexProperty({}) cond. key/value write failure gave up RETRYING", tableId);
+	// XXX ?Is this correct
+	return null;
+    }
+
+    public void removeIndex() {
+	log.info("Removing Index: {} was version {} [{}]", indexName, indexVersion, this);
+	graph.getRcClient().remove(tableId, rcKey);
+    }
+}
diff --git a/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudKeyIndex.java b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudKeyIndex.java
new file mode 100644
index 0000000..0127a62
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudKeyIndex.java
@@ -0,0 +1,63 @@
+/* Copyright (c) 2013 Stanford University
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package com.tinkerpop.blueprints.impls.ramcloud;
+
+import java.io.Serializable;
+import java.util.Set;
+
+import com.tinkerpop.blueprints.Element;
+
+public class RamCloudKeyIndex<T extends RamCloudElement> extends RamCloudIndex<T> implements Serializable {
+    public RamCloudKeyIndex(long tableId, String indexName, Object propValue, RamCloudGraph graph, Class<T> indexClass) {
+	super(tableId, indexName, propValue, graph, indexClass);
+    }
+
+    public RamCloudKeyIndex(long tableId, byte[] rcKey, RamCloudGraph graph, Class<T> indexClass) {
+	super(tableId, rcKey, graph, indexClass);
+    }
+
+    public boolean autoUpdate(final String key, final Object newValue, final Object oldValue, final T element) {
+	if (graph.indexedKeys.contains(key)) {
+	    if (oldValue != null) {
+		this.remove(key, oldValue, element);
+	    }
+	    this.put(key, newValue, element);
+	    return true;
+	} else {
+	    return false;
+	}
+    }
+
+    public void autoRemove(final String key, final Object oldValue, final T element) {
+	if (graph.indexedKeys.contains(key)) {
+	    this.remove(key, oldValue, element);
+	}
+    }
+
+    public long reIndexElements(final RamCloudGraph graph, final Iterable<? extends Element> elements, final Set<String> keys) {
+	long counter = 0;
+	for (final Element element : elements) {
+	    for (final String key : keys) {
+		final Object value = element.removeProperty(key);
+		if (null != value) {
+		    counter++;
+		    element.setProperty(key, value);
+		}
+	    }
+	}
+	return counter;
+    }
+}
diff --git a/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudVertex.java b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudVertex.java
new file mode 100644
index 0000000..421db77
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudVertex.java
@@ -0,0 +1,513 @@
+/* Copyright (c) 2013 Stanford University
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package com.tinkerpop.blueprints.impls.ramcloud;
+
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.tinkerpop.blueprints.Direction;
+import com.tinkerpop.blueprints.Edge;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.VertexQuery;
+import com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeListProtoBuf;
+import com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraphProtos.EdgeProtoBuf;
+import com.tinkerpop.blueprints.util.DefaultVertexQuery;
+import com.tinkerpop.blueprints.util.ExceptionFactory;
+import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
+
+import edu.stanford.ramcloud.JRamCloud;
+import edu.stanford.ramcloud.JRamCloud.MultiWriteObject;
+import edu.stanford.ramcloud.JRamCloud.RejectRules;
+import edu.stanford.ramcloud.JRamCloud.WrongVersionException;
+
+public class RamCloudVertex extends RamCloudElement implements Vertex, Serializable {
+
+	private final static Logger log = LoggerFactory.getLogger(RamCloudGraph.class);
+	private static final long serialVersionUID = 7526472295622776147L;
+	protected long id;
+	protected byte[] rcKey;
+	private RamCloudGraph graph;
+
+	private Versioned<EdgeListProtoBuf> cachedAdjEdgeList;
+
+	public RamCloudVertex(long id, RamCloudGraph graph) {
+		super(idToRcKey(id), graph.vertPropTableId, graph);
+
+		this.id = id;
+		this.rcKey = idToRcKey(id);
+		this.graph = graph;
+		this.cachedAdjEdgeList = null;
+	}
+
+	public RamCloudVertex(byte[] rcKey, RamCloudGraph graph) {
+		super(rcKey, graph.vertPropTableId, graph);
+
+		this.id = rcKeyToId(rcKey);
+		this.rcKey = rcKey;
+		this.graph = graph;
+		this.cachedAdjEdgeList = null;
+	}
+
+
+	/*
+	 * Vertex interface implementation
+	 */
+	@Override
+	public Edge addEdge(String label, Vertex inVertex) {
+		return graph.addEdge(null, this, inVertex, label);
+	}
+
+	@Override
+	public Iterable<Edge> getEdges(Direction direction, String... labels) {
+		return new ArrayList<Edge>(getEdgeList(direction, labels));
+	}
+
+	@Override
+	public Iterable<Vertex> getVertices(Direction direction, String... labels) {
+		List<RamCloudEdge> edges = getEdgeList(direction, labels);
+		List<Vertex> neighbors = new LinkedList<Vertex>();
+		for (RamCloudEdge edge : edges) {
+			neighbors.add(edge.getNeighbor(this));
+		}
+		return neighbors;
+	}
+
+	@Override
+	public VertexQuery query() {
+		return new DefaultVertexQuery(this);
+	}
+
+	/*
+	 * RamCloudElement overridden methods
+	 */
+	@Override
+	public Object getId() {
+		return id;
+	}
+
+	@Override
+	public void remove() {
+		Set<RamCloudEdge> edges = getEdgeSet();
+
+		// neighbor vertex -> List of Edges to remove
+		Map<RamCloudVertex, List<RamCloudEdge>> vertexToEdgesMap = new HashMap<RamCloudVertex, List<RamCloudEdge>>( edges.size() );
+
+		// Batch edges together by neighbor vertex
+		for (RamCloudEdge edge : edges) {
+			RamCloudVertex neighbor = (RamCloudVertex) edge.getNeighbor(this);
+			List<RamCloudEdge> edgeList = vertexToEdgesMap.get(neighbor);
+
+			if (edgeList == null) {
+				edgeList = new LinkedList<RamCloudEdge>();
+			}
+
+			edgeList.add(edge);
+			vertexToEdgesMap.put(neighbor, edgeList);
+		}
+
+		// Remove batches of edges at a time by neighbor vertex
+		for (Entry<RamCloudVertex, List<RamCloudEdge>> entry : vertexToEdgesMap.entrySet()) {
+			// Skip over loopback edges to ourself
+			if (!entry.getKey().equals(this)) {
+				entry.getKey().removeEdgesFromAdjList(entry.getValue());
+			}
+
+			// Remove this batch of edges from the edge property table
+			for (RamCloudEdge edge : entry.getValue()) {
+				edge.removeProperties();
+			}
+		}
+
+		Map<String,Object> props = this.getPropertyMap();
+		for( Map.Entry<String,Object> entry : props.entrySet() ) {
+			if ( !graph.indexedKeys.contains(entry.getKey() ) ) continue;
+			RamCloudKeyIndex keyIndex = new RamCloudKeyIndex(graph.kidxVertTableId, entry.getKey(), entry.getValue(), graph, Vertex.class);
+			keyIndex.remove(entry.getKey(), entry.getValue(), this);
+		}
+
+		// Remove ourselves entirely from the vertex table
+		graph.getRcClient().remove(graph.vertTableId, rcKey);
+
+		super.remove();
+	}
+
+	/*
+	 * Object overridden methods
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (obj == null) {
+			return false;
+		}
+		if (getClass() != obj.getClass()) {
+			return false;
+		}
+		RamCloudVertex other = (RamCloudVertex) obj;
+		return (id == other.id);
+	}
+
+	@Override
+	public int hashCode() {
+		return Long.valueOf(id).hashCode();
+	}
+
+	@Override
+	public String toString() {
+		return "RamCloudVertex [id=" + id + "]";
+	}
+
+	/*
+	 * RamCloudVertex specific methods
+	 */
+	private static byte[] idToRcKey(long id) {
+		return ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN).putLong(id).array();
+	}
+
+	private static long rcKeyToId(byte[] rcKey) {
+		return ByteBuffer.wrap(rcKey).order(ByteOrder.LITTLE_ENDIAN).getLong();
+	}
+
+	boolean addEdgeToAdjList(RamCloudEdge edge) {
+		List<RamCloudEdge> edgesToAdd = new ArrayList<RamCloudEdge>(1);
+		edgesToAdd.add(edge);
+		return addEdgesToAdjList(edgesToAdd);
+	}
+	boolean removeEdgeFromAdjList(RamCloudEdge edge) {
+		List<RamCloudEdge> edgesToRemove = new ArrayList<RamCloudEdge>(1);
+		edgesToRemove.add(edge);
+		return removeEdgesFromAdjList(edgesToRemove);
+	}
+
+	private boolean addEdgesToAdjList(List<RamCloudEdge> edgesToAdd) {
+		return updateEdgeAdjList(edgesToAdd, true);
+	}
+	private boolean removeEdgesFromAdjList(List<RamCloudEdge> edgesToAdd) {
+		return updateEdgeAdjList(edgesToAdd, false);
+	}
+
+	/** Conditionally update Adj. Edge List
+	 * @return true if EdgeAdjList was logically modified.(Cache update does not imply true return)
+	 */
+	private boolean updateEdgeAdjList(List<RamCloudEdge> edgesToModify, boolean add) {
+		PerfMon pm = PerfMon.getInstance();
+		JRamCloud rcClient = graph.getRcClient();
+		final int MAX_RETRIES = 100;
+		for (int retry = 1 ; retry <= MAX_RETRIES ; ++retry ) {
+			Set<RamCloudEdge> edges;
+			long expected_version = 0L;
+			if ( this.cachedAdjEdgeList == null ) {
+				edges = new HashSet<RamCloudEdge>();
+			} else {
+				expected_version = this.cachedAdjEdgeList.getVersion();
+				if ( expected_version == 0L && add == false ) {
+					updateCachedAdjEdgeList();
+					expected_version = this.cachedAdjEdgeList.getVersion();
+				}
+				edges = buildEdgeSetFromProtobuf(this.cachedAdjEdgeList.getValue(), Direction.BOTH);
+			}
+			if ( expected_version == 0L && add == false ) {
+				updateCachedAdjEdgeList();
+				expected_version = this.cachedAdjEdgeList.getVersion();
+				edges = buildEdgeSetFromProtobuf(this.cachedAdjEdgeList.getValue(), Direction.BOTH);
+			}
+			//log.debug( (add?"Adding":"Removing") + " edges to: {"+ edges+ "}");
+
+			try {
+				if ( add ) {
+					if (edges.addAll(edgesToModify) == false) {
+						log.warn("{}: There aren't any changes to edges ({})", this, edgesToModify);
+						return false;
+					}
+				} else {
+					if (edges.removeAll(edgesToModify) == false) {
+						log.warn("{}: There aren't any changes to edges ({})", this, edgesToModify);
+						return false;
+					}
+				}
+
+				EdgeListProtoBuf edgeList = buildProtoBufFromEdgeSet(edges);
+				JRamCloud.RejectRules rules = rcClient.new RejectRules();
+				if ( expected_version == 0L ) {
+					rules.setExists();
+				} else {
+					rules.setNeVersion(expected_version);
+				}
+				pm.write_start("RAMCloudVertex updateEdgeAdjList()");
+				long updated_version = rcClient.writeRule(graph.vertTableId, rcKey, edgeList.toByteArray(), rules);
+				pm.write_end("RAMCloudVertex updateEdgeAdjList()");
+				this.cachedAdjEdgeList.setValue(edgeList, updated_version);
+				return true;
+			} catch (UnsupportedOperationException e) {
+				pm.write_end("RAMCloudVertex updateEdgeAdjList()");
+				pm.write_condfail("RAMCloudVertex updateEdgeAdjList()");
+				log.error("{" + toString() + "}: Failed to modify a set of edges ({" + edgesToModify + "}): ", e);
+				return false;
+			} catch (ClassCastException e) {
+				pm.write_end("RAMCloudVertex updateEdgeAdjList()");
+				pm.write_condfail("RAMCloudVertex updateEdgeAdjList()");
+				log.error("{" + toString() + "}: Failed to modify a set of edges ({" + edgesToModify + "}): ", e);
+				return false;
+			} catch (NullPointerException e) {
+				pm.write_end("RAMCloudVertex updateEdgeAdjList()");
+				pm.write_condfail("RAMCloudVertex updateEdgeAdjList()");
+				log.error("{" + toString() + "}: Failed to modify a set of edges ({" + edgesToModify + "}): ", e);
+				return false;
+			} catch (Exception e) {
+				pm.write_end("RAMCloudVertex updateEdgeAdjList()");
+				pm.write_condfail("RAMCloudVertex updateEdgeAdjList()");
+				// FIXME Workaround for native method exception declaration bug
+				if ( e instanceof WrongVersionException ) {
+					log.debug("Conditional Updating EdgeList failed for {} RETRYING {}", this, retry);
+					//log.debug("Conditional Updating EdgeList failed for {} modifing {} RETRYING [{}]", this, edgesToModify, retry);
+					updateCachedAdjEdgeList();
+				} else {
+					log.debug("Cond. Write to modify adj edge list failed, exception thrown", e);
+					updateCachedAdjEdgeList();
+				}
+			}
+		}
+		log.error("Conditional Updating EdgeList failed for {} gave up RETRYING", this);
+		return false;
+	}
+
+	/** Get all adj.edge list
+	 * Method is exposed to package namespace to do Vertex removal efficiently;
+	 */
+	Set<RamCloudEdge> getEdgeSet() {
+		return getVersionedEdgeSet(Direction.BOTH).getValue();
+	}
+
+	private Versioned<EdgeListProtoBuf> updateCachedAdjEdgeList() {
+		JRamCloud.Object vertTableEntry;
+		EdgeListProtoBuf edgeList;
+
+		PerfMon pm = PerfMon.getInstance();
+		try {
+			JRamCloud vertTable = graph.getRcClient();
+			pm.read_start("RamCloudVertex updateCachedAdjEdgeList()");
+			vertTableEntry = vertTable.read(graph.vertTableId, rcKey);
+			pm.read_end("RamCloudVertex updateCachedAdjEdgeList()");
+		} catch (Exception e) {
+			pm.read_end("RamCloudVertex updateCachedAdjEdgeList()");
+			log.error("{" + toString() + "}: Error reading vertex table entry: ", e);
+			return null;
+		}
+
+		try {
+			pm.protodeser_start("RamCloudVertex updateCachedAdjEdgeList()");
+			edgeList = EdgeListProtoBuf.parseFrom(vertTableEntry.value);
+			Versioned<EdgeListProtoBuf> updatedEdgeList = new Versioned<EdgeListProtoBuf>(edgeList, vertTableEntry.version);
+			this.cachedAdjEdgeList = updatedEdgeList;
+			pm.protodeser_end("RamCloudVertex updateCachedAdjEdgeList()");
+			return updatedEdgeList;
+		} catch (InvalidProtocolBufferException e) {
+			pm.protodeser_end("RamCloudVertex updateCachedAdjEdgeList()");
+			log.error("{" + toString() + "}: Read malformed edge list: ", e);
+			return null;
+		}
+	}
+
+	private Versioned<Set<RamCloudEdge>> getVersionedEdgeSet(Direction direction, String... labels) {
+		Versioned<EdgeListProtoBuf> cachedEdgeList = updateCachedAdjEdgeList();
+		return new Versioned<Set<RamCloudEdge>>(buildEdgeSetFromProtobuf(cachedEdgeList.getValue(), direction, labels), cachedEdgeList.getVersion() );
+	}
+
+	private Set<RamCloudEdge> buildEdgeSetFromProtobuf(EdgeListProtoBuf edgeList,
+			Direction direction, String... labels) {
+		PerfMon pm = PerfMon.getInstance();
+		long startTime = 0;
+		if(RamCloudGraph.measureSerializeTimeProp == 1) {
+		    startTime = System.nanoTime();
+		}
+		pm.protodeser_start("RamCloudVertex buildEdgeSetFromProtobuf()");
+		Set<RamCloudEdge> edgeSet = new HashSet<RamCloudEdge>( edgeList.getEdgeCount() );
+		for (EdgeProtoBuf edge : edgeList.getEdgeList()) {
+			if ((direction.equals(Direction.BOTH) || (edge.getOutgoing() ^ direction.equals(Direction.IN)))
+					&& (labels.length == 0 || Arrays.asList(labels).contains(edge.getLabel()))) {
+				RamCloudVertex  neighbor = new RamCloudVertex(edge.getNeighborId(), graph);
+				if (edge.getOutgoing()) {
+					edgeSet.add(new RamCloudEdge(this, neighbor, edge.getLabel(), graph));
+				} else {
+					edgeSet.add(new RamCloudEdge(neighbor, this, edge.getLabel(), graph));
+				}
+			}
+		}
+		pm.protodeser_end("RamCloudVertex buildEdgeSetFromProtobuf()");
+		if(RamCloudGraph.measureSerializeTimeProp == 1) {
+                 	long endTime = System.nanoTime();
+                	log.error("Performance buildEdgeSetFromProtobuf key {}, {}, size={}", this, endTime - startTime, edgeList.getSerializedSize());
+		}
+		return edgeSet;
+	}
+
+
+
+	private EdgeListProtoBuf buildProtoBufFromEdgeSet(Set<RamCloudEdge> edgeSet) {
+		PerfMon pm = PerfMon.getInstance();
+		long startTime = 0;
+		if(RamCloudGraph.measureSerializeTimeProp == 1) {
+		    startTime = System.nanoTime();
+		}
+
+		pm.protoser_start("RamCloudVertex buildProtoBufFromEdgeSet()");
+
+		EdgeListProtoBuf.Builder edgeListBuilder = EdgeListProtoBuf.newBuilder();
+		EdgeProtoBuf.Builder edgeBuilder = EdgeProtoBuf.newBuilder();
+
+		for (Edge edge : edgeSet) {
+			if (edge.getVertex(Direction.OUT).equals(this) || edge.getVertex(Direction.IN).equals(this)) {
+				if (edge.getVertex(Direction.OUT).equals(edge.getVertex(Direction.IN))) {
+					edgeBuilder.setNeighborId(id);
+					edgeBuilder.setOutgoing(true);
+					edgeBuilder.setLabel(edge.getLabel());
+					edgeListBuilder.addEdge(edgeBuilder.build());
+
+					edgeBuilder.setOutgoing(false);
+					edgeListBuilder.addEdge(edgeBuilder.build());
+				} else {
+					if (edge.getVertex(Direction.OUT).equals(this)) {
+						edgeBuilder.setNeighborId((Long) edge.getVertex(Direction.IN).getId());
+						edgeBuilder.setOutgoing(true);
+						edgeBuilder.setLabel(edge.getLabel());
+						edgeListBuilder.addEdge(edgeBuilder.build());
+					} else {
+						edgeBuilder.setNeighborId((Long) edge.getVertex(Direction.OUT).getId());
+						edgeBuilder.setOutgoing(false);
+						edgeBuilder.setLabel(edge.getLabel());
+						edgeListBuilder.addEdge(edgeBuilder.build());
+					}
+				}
+			} else {
+				log.warn("{}: Tried to add an edge unowned by this vertex ({})", this, edge);
+			}
+		}
+
+		EdgeListProtoBuf buf = edgeListBuilder.build();
+		pm.protoser_end("RamCloudVertex buildProtoBufFromEdgeSet");
+		if(RamCloudGraph.measureSerializeTimeProp == 1) {
+                	long endTime = System.nanoTime();
+                	log.error("Performance buildProtoBufFromEdgeSet key {}, {}, size={}", this, endTime - startTime, buf.getSerializedSize());
+		}
+		return buf;
+	}
+
+	@Deprecated
+	private List<RamCloudEdge> getEdgeList() {
+		return getEdgeList(Direction.BOTH);
+	}
+
+	private List<RamCloudEdge> getEdgeList(Direction direction, String... labels) {
+
+		Versioned<EdgeListProtoBuf> cachedEdgeList = updateCachedAdjEdgeList();
+		PerfMon pm = PerfMon.getInstance();
+		pm.protodeser_start("RamCloudVertex getEdgeList()");
+
+		List<RamCloudEdge> edgeList = new ArrayList<RamCloudEdge>(cachedEdgeList.getValue().getEdgeCount());
+
+		for (EdgeProtoBuf edge : cachedEdgeList.getValue().getEdgeList()) {
+			if ((direction.equals(Direction.BOTH) || (edge.getOutgoing() ^ direction.equals(Direction.IN)))
+					&& (labels.length == 0 || Arrays.asList(labels).contains(edge.getLabel()))) {
+				RamCloudVertex neighbor = new RamCloudVertex(edge.getNeighborId(), graph);
+				if (edge.getOutgoing()) {
+					edgeList.add(new RamCloudEdge(this, neighbor, edge.getLabel(), graph));
+				} else {
+					edgeList.add(new RamCloudEdge(neighbor, this, edge.getLabel(), graph));
+				}
+			}
+		}
+		pm.protodeser_end("RamCloudVertex getEdgeList()");
+
+		return edgeList;
+	}
+
+	protected boolean exists() {
+		boolean vertTableEntryExists = false;
+		boolean vertPropTableEntryExists = false;
+
+		PerfMon pm = PerfMon.getInstance();
+	        JRamCloud vertTable = graph.getRcClient();
+		try {
+		        pm.read_start("RamCloudVertex exists()");
+			vertTable.read(graph.vertTableId, rcKey);
+			pm.read_end("RamCloudVertex exists()");
+			vertTableEntryExists = true;
+		} catch (Exception e) {
+			// Vertex table entry does not exist
+		        pm.read_end("RamCloudVertex exists()");
+		}
+
+		try {
+			pm.read_start("RamCloudVertex exists()");
+			vertTable.read(graph.vertPropTableId, rcKey);
+		        pm.read_end("RamCloudVertex exists()");
+			vertPropTableEntryExists = true;
+		} catch (Exception e) {
+			// Vertex property table entry does not exist
+		        pm.read_end("RamCloudVertex exists()");
+		}
+
+		if (vertTableEntryExists && vertPropTableEntryExists) {
+			return true;
+		} else if (!vertTableEntryExists && !vertPropTableEntryExists) {
+			return false;
+		} else {
+			log.warn("{}: Detected RamCloudGraph inconsistency: vertTableEntryExists={}, vertPropTableEntryExists={}.", this, vertTableEntryExists, vertPropTableEntryExists);
+			return true;
+		}
+	}
+
+	protected void create() throws IllegalArgumentException {
+		// TODO: Existence check costs extra (presently 2 reads), could use option to turn on/off
+		if (!exists()) {
+			PerfMon pm = PerfMon.getInstance();
+			JRamCloud vertTable = graph.getRcClient();
+			MultiWriteObject[] mwo = new MultiWriteObject[2];
+			mwo[0] = new MultiWriteObject(graph.vertTableId, rcKey, ByteBuffer.allocate(0).array(), null);
+			mwo[1] = new MultiWriteObject(graph.vertPropTableId, rcKey, ByteBuffer.allocate(0).array(), null);
+			pm.multiwrite_start("RamCloudVertex create()");
+			vertTable.multiWrite(mwo);
+			pm.multiwrite_end("RamCloudVertex create()");
+		} else {
+			throw ExceptionFactory.vertexWithIdAlreadyExists(id);
+		}
+	}
+
+	public void debugPrintEdgeList() {
+		List<RamCloudEdge> edgeList = getEdgeList();
+
+		log.debug("{}: Debug Printing Edge List...", this);
+		for (RamCloudEdge edge : edgeList) {
+			System.out.println(edge.toString());
+		}
+	}
+}
diff --git a/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/Versioned.java b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/Versioned.java
new file mode 100644
index 0000000..e944c62
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/Versioned.java
@@ -0,0 +1,41 @@
+/* Copyright (c) 2013 Stanford University
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package com.tinkerpop.blueprints.impls.ramcloud;
+
+public class Versioned<T> {
+	private T value;
+	private long version;
+
+	public Versioned(T value) {
+		this(value, 0L);
+	}
+
+	public Versioned(T value, long version) {
+		this.value = value;
+		this.version = version;
+	}
+
+	public T getValue() {
+		return value;
+	}
+	public long getVersion() {
+		return version;
+	}
+	public void setValue(T value, long version) {
+		this.value = value;
+		this.version = version;
+	}
+}
diff --git a/src/main/java/com/tinkerpop/rexster/config/RamCloudGraphConfiguration.java b/src/main/java/com/tinkerpop/rexster/config/RamCloudGraphConfiguration.java
new file mode 100644
index 0000000..fad056e
--- /dev/null
+++ b/src/main/java/com/tinkerpop/rexster/config/RamCloudGraphConfiguration.java
@@ -0,0 +1,30 @@
+/* Copyright (c) 2013 Stanford University
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package com.tinkerpop.rexster.config;
+
+import com.tinkerpop.blueprints.Graph;
+import com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraph;
+import com.tinkerpop.rexster.config.GraphConfiguration;
+import org.apache.commons.configuration.Configuration;
+
+
+public class RamCloudGraphConfiguration implements GraphConfiguration {
+
+    public Graph configureGraphInstance(final Configuration properties) throws GraphConfigurationException {
+        return new RamCloudGraph("fast+udp:host=127.0.0.1,port=12246");
+    }
+
+}
diff --git a/src/main/java/edu/stanford/ramcloud/JRamCloud.java b/src/main/java/edu/stanford/ramcloud/JRamCloud.java
new file mode 100755
index 0000000..fef2b12
--- /dev/null
+++ b/src/main/java/edu/stanford/ramcloud/JRamCloud.java
@@ -0,0 +1,430 @@
+/* Copyright (c) 2013 Stanford University
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package edu.stanford.ramcloud;
+
+/*
+ * This class provides Java bindings for RAMCloud. Right now it is a rather
+ * simple subset of what RamCloud.h defines.
+ *
+ * Running ``javah'' on this file will generate a C header file with the
+ * appropriate JNI function definitions. The glue interfacing to the C++
+ * RAMCloud library can be found in JRamCloud.cc.
+ *
+ * For JNI information, the IBM tutorials and Android developer docs are much
+ * better than Sun's at giving an overall intro:
+ *      http://www.ibm.com/developerworks/java/tutorials/j-jni/section4.html
+ *      http://developer.android.com/training/articles/perf-jni.html
+ */
+public class JRamCloud {
+    static {
+        System.loadLibrary("edu_stanford_ramcloud_JRamCloud");
+    }
+
+    /// Pointer to the underlying C++ RAMCloud object associated with this
+    /// object.
+    private long ramcloudObjectPointer = 0;
+
+    /**
+     * See src/RejectRules.h.
+     */
+    public class RejectRules {
+	private long givenVersion;
+        private boolean doesntExist;
+        private boolean exists;
+        private boolean versionLeGiven;
+        private boolean versionNeGiven;
+
+        public RejectRules() {
+            this.givenVersion = -1;
+            this.exists = this.doesntExist = this.versionLeGiven = this.versionNeGiven = false;
+        }
+
+        public void setLeVersion(long version) {
+            setVersion(version);
+            this.versionLeGiven = true;
+        }
+
+        public void setExists() {
+            this.exists = true;
+        }
+
+        public void setDoesntExists() {
+            this.doesntExist = true;
+        }
+
+        public void setNeVersion(long version) {
+            setVersion(version);
+            this.versionNeGiven = true;
+        }
+
+        private void setVersion(long version) {
+            this.givenVersion = version;
+        }	
+    }
+    
+    public static class multiReadObject {
+        long tableId;
+        byte[] key;
+        
+        public multiReadObject(long _tableId, byte[] _key){
+            tableId = _tableId;
+            key = _key;
+        }
+    }
+    
+    public static class MultiWriteObject {
+        long tableId;
+        byte[] key;
+        byte[] value;
+        RejectRules rules;
+
+        public MultiWriteObject(long tableId, byte[] key, byte[] value, RejectRules rules) {
+            this.tableId = tableId;
+            this.key = key;
+            this.value = value;
+            this.rules = rules;
+        }
+    }
+
+    public class MultiWriteRspObject {
+        private int status;
+        private long version;
+
+        public MultiWriteRspObject(int status, long version) {
+            this.status = status;
+            this.version = version;
+        }
+        public int getStatus() {
+            return status;
+        }
+
+        public long getVersion() {
+            return version;
+        }
+    }
+
+    /**
+     * This class is returned by Read operations. It encapsulates the entire
+     * object, including the key, value, and version.
+     *
+     * It mostly exists because Java doesn't support primitive out parameters
+     * or multiple return values, and we don't know the object's size ahead of
+     * time, so passing in a fixed-length array would be problematic.
+     */
+    public class Object {
+        Object(byte[] _key, byte[] _value, long _version)
+        {
+            key = _key;
+            value = _value;
+            version = _version;
+        }
+
+        public String
+        getKey()
+        {
+            return new String(key);
+        }
+
+        public String
+        getValue()
+        {
+            return new String(value);
+        }
+
+        final public byte[] key;
+        final public byte[] value;
+        final public long version;
+    }
+
+    public class TableEnumerator {
+        private long tableEnumeratorObjectPointer = 0;
+        private long ramCloudObjectPointer = 0;
+        
+        public TableEnumerator(long tableId)
+        {
+            ramCloudObjectPointer = ramcloudObjectPointer;
+            tableEnumeratorObjectPointer = init(tableId);
+        }
+        
+        private native long init(long tableId);
+        public native boolean hasNext();
+        public native Object next();
+    }
+
+    /**
+     * Connect to the RAMCloud cluster specified by the given coordinator's
+     * service locator string. This causes the JNI code to instantiate the
+     * underlying RamCloud C++ object.
+     */
+    public
+    JRamCloud(String coordinatorLocator)
+    {
+        ramcloudObjectPointer = connect(coordinatorLocator);
+    }
+
+    /**
+     * Disconnect from the RAMCloud cluster. This causes the JNI code to
+     * destroy the underlying RamCloud C++ object.
+     */
+    public void
+    disconnect()
+    {
+        if (ramcloudObjectPointer != 0) {
+            disconnect(ramcloudObjectPointer);
+            ramcloudObjectPointer = 0;
+        }
+    }
+
+    /**
+     * This method is called by the garbage collector before destroying the
+     * object. The user really should have called disconnect, but in case
+     * they did not, be sure to clean up after them.
+     */
+    public void
+    finalize()
+    {
+        System.err.println("warning: JRamCloud::disconnect() was not called " +
+                           "prior to the finalizer. You should disconnect " +
+                           "your JRamCloud object when you're done with it.");
+        disconnect();
+    }
+
+    /**
+     * Convenience read() wrapper that take a String key argument.
+     */
+    public Object
+    read(long tableId, String key)
+    {
+        return read(tableId, key.getBytes());
+    }
+
+    /**
+     * Convenience read() wrapper that take a String key argument.
+     */
+    public Object
+    read(long tableId, String key, RejectRules rules)
+    {
+        return read(tableId, key.getBytes(), rules);
+    }
+    
+    /**
+     * Convenience remove() wrapper that take a String key argument.
+     */
+    public long
+    remove(long tableId, String key)
+    {
+        return remove(tableId, key.getBytes());
+    }
+
+    /**
+     * Convenience remove() wrapper that take a String key argument.
+     */
+    public long
+    remove(long tableId, String key, RejectRules rules)
+    {
+        return remove(tableId, key.getBytes(), rules);
+    }
+
+    /**
+     * Convenience write() wrapper that take String key and value arguments.
+     */
+    public long
+    write(long tableId, String key, String value)
+    {
+        return write(tableId, key.getBytes(), value.getBytes());
+    }
+
+    /**
+     * Convenience write() wrapper that take String key and value arguments.
+     */
+    public long
+    write(long tableId, String key, String value, RejectRules rules)
+    {
+        return write(tableId, key.getBytes(), value.getBytes(), rules);
+    }
+
+    /**
+     * Convenience write() wrapper that takes a String key and a byte[] value
+     * argument.
+     */
+    public long
+    write(long tableId, String key, byte[] value)
+    {
+        return write(tableId, key.getBytes(), value);
+    }
+
+    /**
+     * Convenience write() wrapper that takes a String key and a byte[] value
+     * argument.
+     */
+    public long
+    write(long tableId, String key, byte[] value, RejectRules rules)
+    {
+        return write(tableId, key.getBytes(), value, rules);
+    }
+    
+    private static native long connect(String coordinatorLocator);
+    private static native void disconnect(long ramcloudObjectPointer);
+
+    public native long createTable(String name);
+    public native long createTable(String name, int serverSpan);
+    public native void dropTable(String name);
+    public native long getTableId(String name);
+    public native Object read(long tableId, byte[] key);
+    public native Object read(long tableId, byte[] key, RejectRules rules);
+    public native Object[] multiRead(multiReadObject[] mread);
+    public native long remove(long tableId, byte[] key);
+    public native long remove(long tableId, byte[] key, RejectRules rules);
+    public native long write(long tableId, byte[] key, byte[] value);
+    public native long write(long tableId, byte[] key, byte[] value, RejectRules rules);
+    public native long writeRule(long tableId, byte[] key, byte[] value, RejectRules rules);
+    public native MultiWriteRspObject[] multiWrite(MultiWriteObject[] mwrite);
+
+    /*
+     * The following exceptions may be thrown by the JNI functions:
+     */
+
+    public class TableDoesntExistException extends Exception {
+        public TableDoesntExistException(String message)
+        {
+            super(message);
+        }
+    }
+
+    public class ObjectDoesntExistException extends Exception {
+        public ObjectDoesntExistException(String message)
+        {
+            super(message);
+        }
+    }
+
+    public class ObjectExistsException extends Exception {
+        public ObjectExistsException(String message)
+        {
+            super(message);
+        }
+    }
+
+    public class WrongVersionException extends Exception {
+        public WrongVersionException(String message)
+        {
+            super(message);
+        }
+    }
+    
+    public class InvalidObjectException extends Exception {
+        public InvalidObjectException(String message) {
+            super(message);
+        }
+    }
+    
+    public class RejectRulesException extends Exception {
+        public RejectRulesException(String message) {
+            super(message);
+        }
+    }
+
+    /**
+     * A simple end-to-end test of the java bindings.
+     */
+    public static void
+    main(String argv[])
+    {
+        JRamCloud ramcloud = new JRamCloud(argv[0]);
+        long tableId = ramcloud.createTable("hi");
+        System.out.println("created table, id = " + tableId);
+        long tableId2 = ramcloud.getTableId("hi");
+        System.out.println("getTableId says tableId = " + tableId2);
+
+        System.out.println("wrote obj version = " +
+            ramcloud.write(tableId, "thisIsTheKey", "thisIsTheValue"));
+
+        JRamCloud.Object o = ramcloud.read(tableId, "thisIsTheKey");
+        System.out.println("read object: key = [" + o.getKey() + "], value = ["
+            + o.getValue() + "], version = " + o.version);
+
+        ramcloud.remove(tableId, "thisIsTheKey");
+
+        try {
+            ramcloud.read(tableId, "thisIsTheKey");
+            System.out.println("Error: shouldn't have read successfully!");
+        } catch (Exception e) {
+            // OK
+        }
+
+        ramcloud.write(tableId, "thisIsTheKey", "thisIsTheValue");
+        
+        long before = System.nanoTime();
+        for (int i = 0; i < 1000; i++) {
+            JRamCloud.Object unused = ramcloud.read(tableId, "thisIsTheKey");
+        }
+        long after = System.nanoTime();
+        System.out.println("Avg read latency: " +
+            ((double)(after - before) / 1000 / 1000) + " usec");
+        
+        // multiRead test
+        long tableId4 = ramcloud.createTable("table4");
+        System.out.println("table4 id " + tableId4);
+        ramcloud.write(tableId4, "object1-1", "value:1-1");
+        ramcloud.write(tableId4, "object1-2", "value:1-2");
+        ramcloud.write(tableId4, "object1-3", "value:1-3");
+        long tableId5 = ramcloud.createTable("table5");
+        System.out.println("table5 id " + tableId5);
+        ramcloud.write(tableId5, "object2-1", "value:2-1");
+        long tableId6 = ramcloud.createTable("table6");
+        ramcloud.write(tableId6, "object3-1", "value:3-1");
+        ramcloud.write(tableId6, "object3-2", "value:3-2");
+
+        multiReadObject mread[] = new multiReadObject[2];
+        //for (int k = 0; k < 2000; k++) {
+        mread[0] = new multiReadObject(tableId4, "object1-1".getBytes());
+        mread[1] = new multiReadObject(tableId5, "object2-1".getBytes());
+        JRamCloud.Object out[] = ramcloud.multiRead(mread);
+        for (int i = 0 ; i < 2 ; i++){
+            System.out.println("multi read object: key = [" + out[i].getKey() + "], value = ["
+                    + out[i].getValue() + "]");
+        //}
+        }
+        MultiWriteObject mwrite[] = new MultiWriteObject[2];
+        for (int i = 0; i < 1000; i++) {
+            String key1 = "key1" + new Integer(i).toString();
+            String key2 = "key2" + new Integer(i).toString();
+      
+            mwrite[0] = new MultiWriteObject(tableId4, key1.getBytes(), "v0-value".getBytes(), null);
+            mwrite[1] = new MultiWriteObject(tableId5, key2.getBytes(), "v1".getBytes(), null);
+            MultiWriteRspObject[] rsp = ramcloud.multiWrite(mwrite);
+            if (rsp != null) {
+                for (int j = 0; j < rsp.length; j++) {
+                    System.out.println("multi write rsp(" + j + ") status:version " + rsp[j].getStatus() + ":" + rsp[j].getVersion());
+                }
+            }
+        }
+        for (int i = 0; i < 1000; i++) {
+            String key1 = "key1" + new Integer(i).toString();
+            String key2 = "key2" + new Integer(i).toString();
+            mread[0] = new multiReadObject(tableId4, key1.getBytes());
+            mread[1] = new multiReadObject(tableId5, key2.getBytes());
+            out = ramcloud.multiRead(mread);
+            for (int j = 0; j < 2; j++) {
+                System.out.println("multi read object: key = [" + out[j].getKey() + "], value = [" + out[j].getValue() + "]");
+            }
+        }
+        ramcloud.dropTable("table4");
+        ramcloud.dropTable("table5");
+        ramcloud.dropTable("table6");
+        ramcloud.disconnect();
+    }
+}
diff --git a/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java b/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
index 45995bf..13a0157 100644
--- a/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
+++ b/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
@@ -19,8 +19,10 @@
 import net.onrc.onos.datagrid.web.DatagridWebRoutable;
 import net.onrc.onos.ofcontroller.flowmanager.IFlowEventHandlerService;
 import net.onrc.onos.ofcontroller.flowmanager.PerformanceMonitor.Measurement;
-import net.onrc.onos.ofcontroller.proxyarp.ArpMessage;
-import net.onrc.onos.ofcontroller.proxyarp.IArpEventHandler;
+import net.onrc.onos.ofcontroller.proxyarp.ArpReplyNotification;
+import net.onrc.onos.ofcontroller.proxyarp.IArpReplyEventHandler;
+import net.onrc.onos.ofcontroller.proxyarp.IPacketOutEventHandler;
+import net.onrc.onos.ofcontroller.proxyarp.PacketOutNotification;
 import net.onrc.onos.ofcontroller.topology.TopologyElement;
 import net.onrc.onos.ofcontroller.util.Dpid;
 import net.onrc.onos.ofcontroller.util.FlowEntry;
@@ -33,9 +35,9 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.esotericsoftware.kryo2.Kryo;
-import com.esotericsoftware.kryo2.io.Input;
-import com.esotericsoftware.kryo2.io.Output;
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
 import com.hazelcast.config.Config;
 import com.hazelcast.config.FileSystemXmlConfig;
 import com.hazelcast.core.EntryEvent;
@@ -96,12 +98,18 @@
     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;
-    private List<IArpEventHandler> arpEventHandlers = new ArrayList<IArpEventHandler>();
+    // State related to the packet out map
+    protected static final String packetOutMapName = "packetOutMap";
+    private IMap<PacketOutNotification, byte[]> packetOutMap = null;
+    private List<IPacketOutEventHandler> packetOutEventHandlers = new ArrayList<IPacketOutEventHandler>();
+
     private final byte[] dummyByte = {0};
 
+    // State related to the ARP reply map
+    protected static final String arpReplyMapName = "arpReplyMap";
+    private IMap<ArpReplyNotification, byte[]> arpReplyMap = null;
+    private List<IArpReplyEventHandler> arpReplyEventHandlers = new ArrayList<IArpReplyEventHandler>();
+
     /**
      * Class for receiving notifications for Flow state.
      *
@@ -502,35 +510,23 @@
     }
 
     /**
-     * Class for receiving notifications for ARP requests.
+     * Class for receiving notifications for sending packet-outs.
      *
      * The datagrid map is:
-     *  - Key: Request ID (String)
-     *  - Value: ARP request packet (byte[])
+     *  - Key: Packet-out to send (PacketOutNotification)
+     *  - Value: dummy value (we only need the key) (byte[])
      */
-    class ArpMapListener implements EntryListener<ArpMessage, byte[]> {
+    class PacketOutMapListener implements EntryListener<PacketOutNotification, byte[]> {
 		/**
 		 * Receive a notification that an entry is added.
 		 *
 		 * @param event the notification event for the entry.
 		 */
 		@Override
-		public void entryAdded(EntryEvent<ArpMessage, byte[]> event) {
-		    for (IArpEventHandler arpEventHandler : arpEventHandlers) {
-		    	arpEventHandler.arpRequestNotification(event.getKey());
+		public void entryAdded(EntryEvent<PacketOutNotification, byte[]> event) {
+		    for (IPacketOutEventHandler packetOutEventHandler : packetOutEventHandlers) {
+		    	packetOutEventHandler.packetOutNotification(event.getKey());
 		    }
-
-		    //
-		    // Decode the value and deliver the notification
-		    //
-		    /*
-		    Kryo kryo = kryoFactory.newKryo();
-		    Input input = new Input(valueBytes);
-		    TopologyElement topologyElement =
-			kryo.readObject(input, TopologyElement.class);
-		    kryoFactory.deleteKryo(kryo);
-		    flowEventHandlerService.notificationRecvTopologyElementAdded(topologyElement);
-		    */
 		}
 
 		/**
@@ -539,7 +535,7 @@
 		 * @param event the notification event for the entry.
 		 */
 		@Override
-		public void entryRemoved(EntryEvent<ArpMessage, byte[]> event) {
+		public void entryRemoved(EntryEvent<PacketOutNotification, byte[]> event) {
 			// Not used
 		}
 
@@ -549,7 +545,7 @@
 		 * @param event the notification event for the entry.
 		 */
 		@Override
-		public void entryUpdated(EntryEvent<ArpMessage, byte[]> event) {
+		public void entryUpdated(EntryEvent<PacketOutNotification, byte[]> event) {
 			// Not used
 		}
 
@@ -559,12 +555,41 @@
 		 * @param event the notification event for the entry.
 		 */
 		@Override
-		public void entryEvicted(EntryEvent<ArpMessage, byte[]> event) {
+		public void entryEvicted(EntryEvent<PacketOutNotification, byte[]> event) {
 		    // Not used
 		}
     }
 
     /**
+     * Class for receiving notifications for sending packet-outs.
+     *
+     * The datagrid map is:
+     *  - Key: Packet-out to send (PacketOutNotification)
+     *  - Value: dummy value (we only need the key) (byte[])
+     */
+    class ArpReplyMapListener implements EntryListener<ArpReplyNotification, byte[]> {
+		/**
+		 * Receive a notification that an entry is added.
+		 *
+		 * @param event the notification event for the entry.
+		 */
+		@Override
+		public void entryAdded(EntryEvent<ArpReplyNotification, byte[]> event) {
+		    for (IArpReplyEventHandler arpReplyEventHandler : arpReplyEventHandlers) {
+		    	arpReplyEventHandler.arpReplyEvent(event.getKey());
+		    }
+		}
+
+		// These methods aren't used for ARP replies
+		@Override
+		public void entryRemoved(EntryEvent<ArpReplyNotification, byte[]> event) {}
+		@Override
+		public void entryUpdated(EntryEvent<ArpReplyNotification, byte[]> event) {}
+		@Override
+		public void entryEvicted(EntryEvent<ArpReplyNotification, byte[]> event) {}
+    }
+
+    /**
      * Initialize the Hazelcast Datagrid operation.
      *
      * @param conf the configuration filename.
@@ -680,8 +705,11 @@
 
 	restApi.addRestletRoutable(new DatagridWebRoutable());
 
-	arpMap = hazelcastInstance.getMap(arpMapName);
-	arpMap.addEntryListener(new ArpMapListener(), true);
+	packetOutMap = hazelcastInstance.getMap(packetOutMapName);
+	packetOutMap.addEntryListener(new PacketOutMapListener(), true);
+
+	arpReplyMap = hazelcastInstance.getMap(arpReplyMapName);
+	arpReplyMap.addEntryListener(new ArpReplyMapListener(), true);
     }
 
     /**
@@ -762,15 +790,27 @@
     }
 
     @Override
-    public void registerArpEventHandler(IArpEventHandler arpEventHandler) {
-    	if (arpEventHandler != null) {
-    		arpEventHandlers.add(arpEventHandler);
+    public void registerPacketOutEventHandler(IPacketOutEventHandler packetOutEventHandler) {
+    	if (packetOutEventHandler != null) {
+    		packetOutEventHandlers.add(packetOutEventHandler);
     	}
     }
 
     @Override
-    public void deregisterArpEventHandler(IArpEventHandler arpEventHandler) {
-    	arpEventHandlers.remove(arpEventHandler);
+    public void deregisterPacketOutEventHandler(IPacketOutEventHandler packetOutEventHandler) {
+    	packetOutEventHandlers.remove(packetOutEventHandler);
+    }
+
+    @Override
+    public void registerArpReplyEventHandler(IArpReplyEventHandler arpReplyEventHandler) {
+    	if (arpReplyEventHandler != null) {
+    		arpReplyEventHandlers.add(arpReplyEventHandler);
+    	}
+    }
+
+    @Override
+    public void deregisterArpReplyEventHandler(IArpReplyEventHandler arpReplyEventHandler) {
+    	arpReplyEventHandlers.remove(arpReplyEventHandler);
     }
 
     /**
@@ -1317,8 +1357,12 @@
     }
 
     @Override
-    public void sendArpRequest(ArpMessage arpMessage) {
-    	//log.debug("ARP bytes: {}", HexString.toHexString(arpRequest));
-     	arpMap.putAsync(arpMessage, dummyByte, 1L, TimeUnit.MILLISECONDS);
+    public void sendPacketOutNotification(PacketOutNotification packetOutNotification) {
+     	packetOutMap.putAsync(packetOutNotification, dummyByte, 1L, TimeUnit.MILLISECONDS);
     }
+
+	@Override
+	public void sendArpReplyNotification(ArpReplyNotification arpReply) {
+		arpReplyMap.putAsync(arpReply, dummyByte, 1L, TimeUnit.MILLISECONDS);
+	}
 }
diff --git a/src/main/java/net/onrc/onos/datagrid/IDatagridService.java b/src/main/java/net/onrc/onos/datagrid/IDatagridService.java
index a855798..80d1781 100644
--- a/src/main/java/net/onrc/onos/datagrid/IDatagridService.java
+++ b/src/main/java/net/onrc/onos/datagrid/IDatagridService.java
@@ -4,8 +4,10 @@
 
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.onrc.onos.ofcontroller.flowmanager.IFlowEventHandlerService;
-import net.onrc.onos.ofcontroller.proxyarp.ArpMessage;
-import net.onrc.onos.ofcontroller.proxyarp.IArpEventHandler;
+import net.onrc.onos.ofcontroller.proxyarp.ArpReplyNotification;
+import net.onrc.onos.ofcontroller.proxyarp.IArpReplyEventHandler;
+import net.onrc.onos.ofcontroller.proxyarp.IPacketOutEventHandler;
+import net.onrc.onos.ofcontroller.proxyarp.PacketOutNotification;
 import net.onrc.onos.ofcontroller.topology.TopologyElement;
 import net.onrc.onos.ofcontroller.util.Dpid;
 import net.onrc.onos.ofcontroller.util.FlowEntry;
@@ -40,18 +42,32 @@
     void deregisterFlowEventHandlerService(IFlowEventHandlerService flowEventHandlerService);
 
     /**
-     * Register event handler for ARP events.
+     * Register event handler for packet-out events.
      * 
-     * @param arpEventHandler The ARP event handler to register.
+     * @param packetOutEventHandler The packet-out event handler to register.
      */
-    public void registerArpEventHandler(IArpEventHandler arpEventHandler);
+    public void registerPacketOutEventHandler(IPacketOutEventHandler packetOutEventHandler);
     
     /**
-     * De-register event handler service for ARP events.
+     * Deregister event handler service for packet-out events.
      * 
-     * @param arpEventHandler The ARP event handler to de-register.
+     * @param packetOutEventHandler The packet-out event handler to deregister.
      */
-    public void deregisterArpEventHandler(IArpEventHandler arpEventHandler);
+    public void deregisterPacketOutEventHandler(IPacketOutEventHandler packetOutEventHandler);
+    
+    /**
+     * Register event handler for ARP reply events.
+     * 
+     * @param packetOutEventHandler The ARP reply event handler to register.
+     */
+    public void registerArpReplyEventHandler(IArpReplyEventHandler arpReplyEventHandler);
+    
+    /**
+     * Deregister event handler service for ARP reply events.
+     * 
+     * @param packetOutEventHandler The ARP reply event handler to deregister.
+     */
+    public void deregisterArpReplyEventHandler(IArpReplyEventHandler arpReplyEventHandler);
 
     /**
      * Get all Flows that are currently in the datagrid.
@@ -240,8 +256,21 @@
     void notificationSendAllTopologyElementsRemoved();
     
     /**
-     * Send an ARP request to other ONOS instances
-     * @param arpRequest The request packet to send
+     * Send a packet-out notification to other ONOS instances. This informs
+     * other instances that they should send this packet out some of the ports
+     * they control. Not all notifications are applicable to all instances 
+     * (i.e. some notifications specify a single port to send the packet out),
+     * so each instance must determine whether it needs to take action when it
+     * receives the notification.
+     * 
+     * @param packetOutNotification The packet notification to send
      */
-    public void sendArpRequest(ArpMessage arpMessage);  
+    public void sendPacketOutNotification(PacketOutNotification packetOutNotification);
+    
+    /**
+     * Send notification to other ONOS instances that an ARP reply has been 
+     * received.
+     * @param arpReply The notification of the ARP reply
+     */
+    public void sendArpReplyNotification(ArpReplyNotification arpReply);
 }
diff --git a/src/main/java/net/onrc/onos/graph/DBConnection.java b/src/main/java/net/onrc/onos/graph/DBConnection.java
new file mode 100644
index 0000000..dee458a
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/DBConnection.java
@@ -0,0 +1,19 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.graph;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public abstract class DBConnection implements IDBConnection {
+    public enum Transaction {
+        COMMIT, ROLLBACK
+    }
+
+    public enum GenerateEvent {
+        TRUE, FALSE
+    }
+}
diff --git a/src/main/java/net/onrc/onos/graph/DBOperation.java b/src/main/java/net/onrc/onos/graph/DBOperation.java
new file mode 100644
index 0000000..6e278d9
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/DBOperation.java
@@ -0,0 +1,450 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.graph;
+
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.impls.ramcloud.*;
+import com.tinkerpop.frames.FramedGraph;
+import com.tinkerpop.frames.structures.FramedVertexIterable;
+import com.tinkerpop.gremlin.java.GremlinPipeline;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IBaseObject;
+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;
+import net.onrc.onos.ofcontroller.util.FlowEntryId;
+import net.onrc.onos.ofcontroller.util.FlowId;
+
+public abstract class DBOperation implements IDBOperation {
+
+	protected DBConnection conn;
+	private final static Logger log = LoggerFactory.getLogger(DBOperation.class);
+
+
+	/**
+	 * Search and get an active switch object with DPID.
+	 * @param dpid DPID of the switch
+	 */
+	@Override
+	public ISwitchObject searchActiveSwitch(String dpid) {
+	    ISwitchObject sw = searchSwitch(dpid);
+	    if ((sw != null)
+		    && sw.getState().equals(ISwitchStorage.SwitchState.ACTIVE.toString())) {
+		return sw;
+	    }
+	    return null;
+	}
+
+	/**
+	 * Create a new switch and return the created switch object.
+	 * @param dpid DPID of the switch
+	 */
+	@Override
+	public ISwitchObject newSwitch(final String dpid) {
+	    //System.out.println("newSwitch");
+	    ISwitchObject obj = (ISwitchObject) conn.getFramedGraph().addVertex(null, ISwitchObject.class);
+	    if (obj != null) {
+		obj.setType("switch");
+		obj.setDPID(dpid);
+	    }
+	    return obj;
+	}
+
+	/**
+	 * Get all port objects.
+	 */
+	@Override
+	public Iterable<IPortObject> getAllPorts() {
+	    Iterable<IPortObject> ports = conn.getFramedGraph().getVertices("type", "port", IPortObject.class);
+	    return ports;
+	}
+
+	/**
+	 * Get all switch objects.
+	 */
+	@Override
+	public Iterable<ISwitchObject> getAllSwitches() {
+	    //System.out.println("getAllSwitches");
+	    Iterable<ISwitchObject> switches = conn.getFramedGraph().getVertices("type", "switch", ISwitchObject.class);
+	    return switches;
+	}
+
+	/**
+	 * Get all inactive switch objects.
+	 */
+	@Override
+	public Iterable<ISwitchObject> getInactiveSwitches() {
+	    //System.out.println("getInactiveSwitches");
+	    Iterable<ISwitchObject> switches = conn.getFramedGraph().getVertices("type", "switch", ISwitchObject.class);
+	    List<ISwitchObject> inactiveSwitches = new ArrayList<ISwitchObject>();
+
+	    for (ISwitchObject sw : switches) {
+		if (sw.getState().equals(ISwitchStorage.SwitchState.INACTIVE.toString())) {
+		    inactiveSwitches.add(sw);
+		}
+	    }
+	    return inactiveSwitches;
+	}
+
+	/**
+	 * Get all flow entries objects where their switches are not updated.
+	 */
+	@Override
+	public Iterable<INetMapTopologyObjects.IFlowEntry> getAllSwitchNotUpdatedFlowEntries() {
+	    //TODO: Should use an enum for flow_switch_state
+	    return conn.getFramedGraph().getVertices("switch_state", "FE_SWITCH_NOT_UPDATED", INetMapTopologyObjects.IFlowEntry.class);
+
+	}
+
+	/**
+	 * Remove specified switch.
+	 * @param sw switch object to remove
+	 */
+	@Override
+	public void removeSwitch(ISwitchObject sw) {
+	    //System.out.println("removeSwitch");
+	    conn.getFramedGraph().removeVertex(sw.asVertex());
+	}
+
+	@Override
+	public IPortObject newPort(String dpid, Short portNum) {
+	    //System.out.println("newPort");
+	    IPortObject obj = (IPortObject) conn.getFramedGraph().addVertex(null, IPortObject.class);
+	    if (obj != null) {
+		obj.setType("port");
+		String id = dpid + PORT_ID_DELIM + portNum.toString();
+		obj.setPortId(id);
+		obj.setNumber(portNum);
+	    }
+	    return obj;
+	}
+
+	/**
+	* Create a port having specified port number.
+	*
+	* @param portNumber port number
+	*/
+	@Override
+	@Deprecated
+	public IPortObject newPort(Short portNumber) {
+	    IPortObject obj = (IPortObject) conn.getFramedGraph().addVertex(null, IPortObject.class);
+	    if (obj != null) {
+		obj.setType("port");
+		obj.setNumber(portNumber);
+	    }
+	    return obj;
+	}
+
+	/**
+	 * Search and get a port object of specified switch and port number.
+	 * @param dpid DPID of a switch
+	 * @param number port number of the switch's port
+	 */
+	@Override
+	public IPortObject searchPort(String dpid, Short number) {
+	    FramedGraph fg = conn.getFramedGraph();
+	    if ( fg == null ) return null;
+	    String id = dpid + PORT_ID_DELIM + number.toString();
+	    Iterator<IPortObject> it = fg.getVertices("port_id", id, IPortObject.class).iterator();
+	    return (it.hasNext()) ? it.next() : null;
+
+	}
+
+	/**
+	 * Remove the specified switch port.
+	 * @param port switch port object to remove
+	 */
+	@Override
+	public void removePort(IPortObject port) {
+	    //System.out.println("removeProt");
+	    if (conn.getFramedGraph() != null) {
+		conn.getFramedGraph().removeVertex(port.asVertex());
+	    }
+	}
+
+	/**
+	 * Create and return a device object.
+	 */
+	@Override
+	public IDeviceObject newDevice() {
+	    //System.out.println("newDevice");
+	    IDeviceObject obj = (IDeviceObject) conn.getFramedGraph().addVertex(null, IDeviceObject.class);
+	    if (obj != null) {
+		obj.setType("device");
+	    }
+	    return obj;
+	}
+
+	/**
+	 * Get all devices.
+	 */
+	@Override
+	public Iterable<IDeviceObject> getDevices() {
+	    //System.out.println("getDeiveces");
+	    return conn.getFramedGraph() != null ? conn.getFramedGraph().getVertices("type", "device", IDeviceObject.class) : null;
+	}
+
+	/**
+	 * Remove the specified device.
+	 * @param dev a device object to remove
+	 */
+	@Override
+	public void removeDevice(IDeviceObject dev) {
+	    //System.out.println("removeDevice");
+	    if (conn.getFramedGraph() != null) {
+		conn.getFramedGraph().removeVertex(dev.asVertex());
+	    }
+	}
+
+	/**
+	* Create and return a flow path object.
+	*/
+	@Override
+	public IFlowPath newFlowPath() {
+	    //System.out.println("newFlowPath");
+	    IFlowPath flowPath = (IFlowPath)conn.getFramedGraph().addVertex(null, IFlowPath.class);
+	    //System.out.println("flowPath : " + flowPath);
+	    if (flowPath != null) {
+		flowPath.setType("flow");
+	    }
+	    return flowPath;
+	}
+
+	/**
+	 * Get a flow path object with a flow entry.
+	 * @param flowEntry flow entry object
+	 */
+	@Override
+	public IFlowPath getFlowPathByFlowEntry(INetMapTopologyObjects.IFlowEntry flowEntry) {
+	    GremlinPipeline<Vertex, IFlowPath> pipe = new GremlinPipeline<Vertex, IFlowPath>();
+	    pipe.start(flowEntry.asVertex());
+	    pipe.out("flow");
+	    FramedVertexIterable<IFlowPath> r = new FramedVertexIterable(conn.getFramedGraph(), pipe, IFlowPath.class);
+	    return r.iterator().hasNext() ? r.iterator().next() : null;
+	}
+
+
+	/**
+	* Search and get a switch object with DPID.
+	*
+	* @param dpid DPID of the switch
+	*/
+	@Override
+	public ISwitchObject searchSwitch(final String dpid) {
+	    FramedGraph fg = conn.getFramedGraph();
+	    if ( fg == null ) return null;
+	    Iterator<ISwitchObject> it = fg.getVertices("dpid", dpid, ISwitchObject.class).iterator();
+	    return (it.hasNext()) ? it.next() : null;
+	}
+
+	/**
+	 * Get all active switch objects.
+	 */
+	@Override
+	public Iterable<ISwitchObject> getActiveSwitches() {
+	    Iterable<ISwitchObject> switches = conn.getFramedGraph().getVertices("type", "switch", ISwitchObject.class);
+	    List<ISwitchObject> activeSwitches = new ArrayList<ISwitchObject>();
+
+	    for (ISwitchObject sw : switches) {
+		if (sw.getState().equals(ISwitchStorage.SwitchState.ACTIVE.toString())) {
+		    activeSwitches.add(sw);
+		}
+	    }
+	    return activeSwitches;
+	}
+
+	/**
+	 * Search and get a device object having specified MAC address.
+	 * @param macAddr MAC address to search and get
+	 */
+	@Override
+	public IDeviceObject searchDevice(String macAddr) {
+	    FramedGraph fg = conn.getFramedGraph();
+	    if ( fg == null ) return null;
+	    Iterator<IDeviceObject> it = fg.getVertices("dl_addr", macAddr, IDeviceObject.class).iterator();
+	    return (it.hasNext()) ? it.next() : null;
+	}
+
+	/**
+	 * Search and get a flow path object with specified flow ID.
+	 * @param flowId flow ID to search
+	 */
+	@Override
+	public IFlowPath searchFlowPath(final FlowId flowId) {
+	    FramedGraph fg = conn.getFramedGraph();
+	    if ( fg == null ) return null;
+	    Iterator<IFlowPath> it = fg.getVertices("flow_id", flowId.toString(), IFlowPath.class).iterator();
+	    return (it.hasNext()) ? it.next() : null;
+	}
+
+	/**
+	 * Get all flow path objects.
+	 */
+	@Override
+	public Iterable<IFlowPath> getAllFlowPaths() {
+	    //System.out.println("getAllFlowPaths");
+	    Iterable<IFlowPath> flowPaths = conn.getFramedGraph().getVertices("type", "flow", IFlowPath.class);
+
+	    List<IFlowPath> nonNullFlows = new ArrayList<IFlowPath>();
+
+	    for (IFlowPath fp : flowPaths) {
+		if (fp.getFlowId() != null) {
+		    nonNullFlows.add(fp);
+		}
+	    }
+	    return nonNullFlows;
+	}
+
+	/**
+	 * Remove the specified flow path.
+	 * @param flowPath flow path object to remove
+	 */
+	@Override
+	public void removeFlowPath(IFlowPath flowPath) {
+	    //System.out.println("removeFlowPath");
+	    conn.getFramedGraph().removeVertex(flowPath.asVertex());
+	}
+
+	/**
+	 * Search and get a flow entry object with flow entry ID.
+	 * @param flowEntryId flow entry ID to search
+	 */
+	@Override
+	public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId) {
+	    FramedGraph fg = conn.getFramedGraph();
+	    if ( fg == null ) return null;
+	    Iterator<IFlowEntry> it = fg.getVertices("flow_entry_id", flowEntryId.toString(), IFlowEntry.class).iterator();
+	    return (it.hasNext()) ? it.next() : null;
+	}
+
+	/**
+	 * Get all flow entry objects.
+	 */
+	@Override
+	public Iterable<IFlowEntry> getAllFlowEntries() {
+	    return conn.getFramedGraph().getVertices("type", "flow_entry", IFlowEntry.class);
+	}
+
+	/**
+	 * Remove the specified flow entry.
+	 * @param flowEntry flow entry object to remove
+	 */
+	@Override
+	public void removeFlowEntry(IFlowEntry flowEntry) {
+	    //System.out.println("removeFlowEntry");
+	    conn.getFramedGraph().removeVertex(flowEntry.asVertex());
+	}
+
+	/**
+	 * Create and return a flow entry object.
+	 */
+	@Override
+	public IFlowEntry newFlowEntry() {
+	    //System.out.println("newFlowEntry");
+	    IFlowEntry flowEntry = (IFlowEntry) conn.getFramedGraph().addVertex(null, IFlowEntry.class);
+	    if (flowEntry != null) {
+		flowEntry.setType("flow_entry");
+	    }
+	    return flowEntry;
+	}
+
+
+	public IIpv4Address newIpv4Address() {
+		return newVertex("ipv4Address", IIpv4Address.class);
+	}
+
+	private <T extends IBaseObject> T newVertex(String type, Class<T> vertexType) {
+		T newVertex = (T) conn.getFramedGraph().addVertex(null, vertexType);
+		if (newVertex != null) {
+			newVertex.setType(type);
+		}
+		return newVertex;
+	}
+
+	public IIpv4Address searchIpv4Address(int intIpv4Address) {
+		return searchForVertex("ipv4_address", intIpv4Address, IIpv4Address.class);
+	}
+
+
+	public IIpv4Address ensureIpv4Address(int intIpv4Address) {
+		IIpv4Address ipv4Vertex = searchIpv4Address(intIpv4Address);
+		if (ipv4Vertex == null) {
+			ipv4Vertex = newIpv4Address();
+			ipv4Vertex.setIpv4Address(intIpv4Address);
+		}
+		return ipv4Vertex;
+	}
+
+
+	private <T> T searchForVertex(String propertyName, Object propertyValue, Class<T> vertexType) {
+		if (conn.getFramedGraph() != null) {
+			Iterator<T> it = conn.getFramedGraph().getVertices(propertyName, propertyValue, vertexType).iterator();
+			if (it.hasNext()) {
+				return it.next();
+			}
+		}
+		return null;
+	}
+
+	public void removeIpv4Address(IIpv4Address ipv4Address) {
+		//System.out.println("removeIpv4Address");
+		conn.getFramedGraph().removeVertex(ipv4Address.asVertex());
+	}
+
+	/**
+	 * Get the instance of GraphDBConnection assigned to this class.
+	 */
+	@Override
+	public IDBConnection getDBConnection() {
+	    return conn;
+	}
+
+	@Override
+	public void commit() {
+	    conn.commit();
+	}
+
+	@Override
+	public void rollback() {
+	    conn.rollback();
+	}
+
+	@Override
+	public void close() {
+	    conn.close();
+	}
+
+	@Override
+	public void setVertexProperties(Vertex vertex, Map<String, Object> map) {
+		log.debug("setProperties start: size {}", map.size());
+		RamCloudVertex v = (RamCloudVertex) vertex;
+		v.setProperties(map);
+		log.debug("setProperties end: size {}, id {}", map.size(), v.getId());
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		for(ISwitchObject sw: getAllSwitches()) {
+			sb.append("sw: " + sw.getDPID() + "\n");
+			for(IPortObject port: sw.getPorts()) {
+				sb.append("  port: " + port.getPortId() + "\n");
+			}
+		}
+		return sb.toString();
+	}
+}
diff --git a/src/main/java/net/onrc/onos/graph/GraphDBConnection.java b/src/main/java/net/onrc/onos/graph/GraphDBConnection.java
index 16869c5..b504c4b 100644
--- a/src/main/java/net/onrc/onos/graph/GraphDBConnection.java
+++ b/src/main/java/net/onrc/onos/graph/GraphDBConnection.java
@@ -11,6 +11,8 @@
 import com.tinkerpop.blueprints.Vertex;
 import com.tinkerpop.blueprints.util.wrappers.event.EventTransactionalGraph;
 import com.tinkerpop.frames.FramedGraph;
+import com.tinkerpop.frames.FramedGraphFactory;
+import com.tinkerpop.frames.modules.gremlingroovy.GremlinGroovyModule;
 
 public class GraphDBConnection implements IDBConnection {
 	public enum Transaction {
@@ -33,6 +35,7 @@
 			.getLogger(GraphDBConnection.class);
 	private static GraphDBConnection singleton = new GraphDBConnection();
 	private static TitanGraph graph;
+	private static FramedGraphFactory factory;
 	private static FramedGraph<TitanGraph> fg;
 	private static EventTransactionalGraph<TitanGraph> eg;
 	private static String configFile;
@@ -86,7 +89,9 @@
 				graph.createKeyIndex("ipv4_address", Vertex.class);
 			}
 			graph.commit();
-			fg = new FramedGraph<TitanGraph>(graph);
+			// Make sure you reuse the factory when creating new framed graphs
+			factory = new FramedGraphFactory(new GremlinGroovyModule());
+            fg = factory.create(graph);
 			eg = new EventTransactionalGraph<TitanGraph>(graph);
 		}
 		return singleton;
@@ -97,7 +102,12 @@
 	 */
 	@Override
 	public FramedGraph<TitanGraph> getFramedGraph() {
-		return fg;
+		if (isValid()) {
+			return fg;
+		} else {
+			log.error("New FramedGraph failed");
+			return null;
+		}
 	}
 
 	/**
diff --git a/src/main/java/net/onrc/onos/graph/GraphDBManager.java b/src/main/java/net/onrc/onos/graph/GraphDBManager.java
new file mode 100644
index 0000000..ec7eb7f
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/GraphDBManager.java
@@ -0,0 +1,58 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.graph;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public class GraphDBManager {
+    private static ThreadLocal<HashMap<String, DBConnection>> connections = new ThreadLocal<HashMap<String, DBConnection>>();
+    private static DBOperation operation = null;
+    
+    static Map<String, DBConnection> getConnectionMap() {
+        if (connections.get() == null) {
+            connections.set(new HashMap<String, DBConnection>());
+        }
+        return connections.get();
+    }
+
+    public static DBOperation getDBOperation(final String dbStore, final String dbConfigFile) {
+	if (dbStore.equals("ramcloud")) {
+	    operation = new RamCloudDBOperation();
+	} else if (dbStore.equals("titan")) {
+	    operation = new TitanDBOperation();
+	}
+	if (operation != null) {
+	    operation.conn = GraphDBManager.getConnection(dbStore, dbConfigFile);
+	}
+        return operation;
+    }
+
+    public static DBConnection getConnection(final String dbStore, final String dbConfigFile) {
+        DBConnection conn = getConnectionMap().get(dbStore);
+        if (conn == null) {
+            if (dbStore.equals("ramcloud")) {
+                conn = new RamCloudDBConnection(dbConfigFile);
+            } else if (dbStore.equals("titan")) {
+                conn = new TitanDBConnection(dbConfigFile);
+            }
+
+            GraphDBManager.getConnectionMap().put(dbStore, conn);
+        } else {
+            GraphDBManager.getConnectionMap().get(dbStore);
+        }
+        return conn;
+    }
+
+    static List<DBConnection> getConnections() {
+        return new ArrayList<DBConnection>(getConnectionMap().values());
+    }
+}
diff --git a/src/main/java/net/onrc/onos/graph/GraphDBOperation.java b/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
deleted file mode 100644
index 26e6181..0000000
--- a/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
+++ /dev/null
@@ -1,457 +0,0 @@
-package net.onrc.onos.graph;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IBaseObject;
-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.util.FlowEntryId;
-import net.onrc.onos.ofcontroller.util.FlowId;
-
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.tinkerpop.blueprints.Vertex;
-import com.tinkerpop.frames.FramedGraph;
-import com.tinkerpop.frames.structures.FramedVertexIterable;
-import com.tinkerpop.gremlin.java.GremlinPipeline;
-
-public class GraphDBOperation implements IDBOperation {
-	private GraphDBConnection conn;
-
-	/**
-	 * Create a GraphDBOperation instance from specified GraphDBConnection's instance.
-	 * @param dbConnection an instance of GraphDBConnection
-	 */
-	public GraphDBOperation(GraphDBConnection dbConnection) {
-		this.conn = dbConnection;
-	}
-
-	/**
-	 * Create a GraphDBOperation instance from database configuration path.
-	 * @param dbConfPath a path for database configuration file.
-	 */
-	public GraphDBOperation(final String dbConfPath) {
-		this.conn = GraphDBConnection.getInstance(dbConfPath);
-	}
-
-	/**
-	 * Create a new switch and return the created switch object.
-	 * @param dpid DPID of the switch
-	 */
-	@Override
-	public ISwitchObject newSwitch(String dpid) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		ISwitchObject obj = fg.addVertex(null,ISwitchObject.class);
-		if (obj != null) {
-			obj.setType("switch");
-			obj.setDPID(dpid);
-		}
-		return obj;
-	}
-
-	/**
-	 * Search and get a switch object with DPID.
-	 * @param dpid DPID of the switch
-	 */
-	@Override
-	public ISwitchObject searchSwitch(String dpid) {
-
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if ( fg == null ) return null;
-		Iterator<ISwitchObject> it = fg.getVertices("dpid",dpid,ISwitchObject.class).iterator();
-		return (it.hasNext()) ? it.next() : null;
-
-	}
-
-	/**
-	 * Search and get an active switch object with DPID.
-	 * @param dpid DPID of the switch
-	 */
-	@Override
-	public ISwitchObject searchActiveSwitch(String dpid) {
-
-	    ISwitchObject sw = searchSwitch(dpid);
-	    if ((sw != null) &&
-	        sw.getState().equals(SwitchState.ACTIVE.toString())) {
-	        return sw;
-	    }
-	    return null;
-	}
-	
-	/**
-     * Get all switch objects.
-     */
-    @Override
-    public Iterable<IPortObject> getAllPorts() {
-        FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-        Iterable<IPortObject> ports =  fg.getVertices("type","port",IPortObject.class);
-        return ports;
-    }
-    
-	/**
-	 * Get all switch objects.
-	 */
-	@Override
-	public Iterable<ISwitchObject> getAllSwitches() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		Iterable<ISwitchObject> switches =  fg.getVertices("type","switch",ISwitchObject.class);
-		return switches;
-	}
-
-	/**
-	 * Get all active switch objects.
-	 */
-	@Override
-	public Iterable<ISwitchObject> getActiveSwitches() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		Iterable<ISwitchObject> switches =  fg.getVertices("type","switch",ISwitchObject.class);
-		List<ISwitchObject> activeSwitches = new ArrayList<ISwitchObject>();
-
-		for (ISwitchObject sw: switches) {
-			if(sw.getState().equals(SwitchState.ACTIVE.toString())) {
-				activeSwitches.add(sw);
-			}
-		}
-		return activeSwitches;
-	}
-
-	/**
-	 * Get all inactive switch objects.
-	 */
-	@Override
-	public Iterable<ISwitchObject> getInactiveSwitches() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		Iterable<ISwitchObject> switches =  fg.getVertices("type","switch",ISwitchObject.class);
-		List<ISwitchObject> inactiveSwitches = new ArrayList<ISwitchObject>();
-
-		for (ISwitchObject sw: switches) {
-			if(sw.getState().equals(SwitchState.INACTIVE.toString())) {
-				inactiveSwitches.add(sw);
-			}
-		}
-		return inactiveSwitches;
-	}
-
-	/**
-	 * Get all flow entries' objects where their switches are not updated.
-	 */
-	@Override
-	public Iterable<IFlowEntry> getAllSwitchNotUpdatedFlowEntries() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		//TODO: Should use an enum for flow_switch_state
-		return fg.getVertices("switch_state", "FE_SWITCH_NOT_UPDATED", IFlowEntry.class);
-	}
-
-	/**
-	 * Remove specified switch.
-	 * @param sw switch object to remove
-	 */
-	@Override
-	public void removeSwitch(ISwitchObject sw) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		fg.removeVertex(sw.asVertex());
-	}
-
-	@Override
-	public IPortObject newPort(String dpid, Short portNumber) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		IPortObject obj = fg.addVertex(null,IPortObject.class);
-		if (obj != null) {
-			obj.setType("port");
-			String id = dpid + PORT_ID_DELIM + portNumber.toString();
-			obj.setPortId(id);
-			obj.setNumber(portNumber);
-		}
-		return obj;
-
-	}
-
-	/**
-	 * Create a port having specified port number.
-	 * @param portNumber port number
-	 */
-	@Override
-	@Deprecated
-	public IPortObject newPort(Short portNumber) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		IPortObject obj = fg.addVertex(null,IPortObject.class);
-		if (obj != null) {
-			obj.setType("port");
-			obj.setNumber(portNumber);
-		}
-		return obj;
-	}
-
-	/**
-	 * Search and get a port object of specified switch and port number.
-	 * @param dpid DPID of a switch
-	 * @param number port number of the switch's port
-	 */
-	@Override
-	public IPortObject searchPort(String dpid, Short number) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if ( fg == null ) return null;
-		String id = dpid + IDBOperation.PORT_ID_DELIM + number.toString();
-		Iterator<IPortObject> ports =  fg.getVertices("port_id",id,IPortObject.class).iterator();
-		if ( ports.hasNext() ) {
-			return ports.next();
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * Remove the specified switch port.
-	 * @param port switch port object to remove
-	 */
-	@Override
-	public void removePort(IPortObject port) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-//		EventGraph<TitanGraph> eg = conn.getEventGraph();
-		if (fg != null) fg.removeVertex(port.asVertex());
-	}
-
-	/**
-	 * Create and return a device object.
-	 */
-	@Override
-	public IDeviceObject newDevice() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		IDeviceObject obj = fg.addVertex(null,IDeviceObject.class);
-		if (obj != null) obj.setType("device");
-		return obj;
-	}
-
-	/**
-	 * Search and get a device object having specified MAC address.
-	 * @param macAddr MAC address to search and get
-	 */
-	@Override
-	public IDeviceObject searchDevice(String macAddr) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if ( fg == null ) return null;
-		Iterator<IDeviceObject> devices =  fg.getVertices("dl_addr",macAddr, IDeviceObject.class).iterator();
-		if ( devices.hasNext() ) {
-			return devices.next();
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * Get all devices.
-	 */
-	@Override
-	public Iterable<IDeviceObject> getDevices() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		return fg != null ? fg.getVertices("type","device",IDeviceObject.class) : null;
-	}
-
-	/**
-	 * Remove the specified device.
-	 * @param dev a device object to remove
-	 */
-	@Override
-	public void removeDevice(IDeviceObject dev) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if (fg != null) fg.removeVertex(dev.asVertex());
-	}
-
-	public IIpv4Address newIpv4Address() {
-		return newVertex("ipv4Address", IIpv4Address.class);
-	}
-
-	private <T extends IBaseObject> T newVertex(String type, Class<T> vertexType) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		T newVertex = fg.addVertex(null, vertexType);
-		if (newVertex != null) {
-			newVertex.setType(type);
-		}
-		return newVertex;
-	}
-
-	public IIpv4Address searchIpv4Address(int intIpv4Address) {
-		return searchForVertex("ipv4_address", intIpv4Address, IIpv4Address.class);
-	}
-
-	private <T> T searchForVertex(String propertyName, Object propertyValue, Class<T> vertexType) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if (fg != null) {
-			Iterator<T> it =
-					fg.getVertices(propertyName, propertyValue, vertexType).iterator();
-			if (it.hasNext()) {
-				return it.next();
-			}
-		}
-		return null;
-	}
-
-	public IIpv4Address ensureIpv4Address(int intIpv4Address) {
-		IIpv4Address ipv4Vertex = searchIpv4Address(intIpv4Address);
-		if (ipv4Vertex == null) {
-			ipv4Vertex = newIpv4Address();
-			ipv4Vertex.setIpv4Address(intIpv4Address);
-		}
-		return ipv4Vertex;
-	}
-
-	public void removeIpv4Address(IIpv4Address ipv4Address) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		fg.removeVertex(ipv4Address.asVertex());
-	}
-
-	/**
-	 * Create and return a flow path object.
-	 */
-	@Override
-	public IFlowPath newFlowPath() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		IFlowPath flowPath = fg.addVertex(null, IFlowPath.class);
-		if (flowPath != null) flowPath.setType("flow");
-		return flowPath;
-	}
-
-	/**
-	 * Search and get a flow path object with specified flow ID.
-	 * @param flowId flow ID to search
-	 */
-	@Override
-	public IFlowPath searchFlowPath(FlowId flowId) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if ( fg == null ) return null;
-		Iterator<IFlowPath> flowpaths = fg.getVertices("flow_id", flowId.toString(), IFlowPath.class).iterator();
-		if ( flowpaths.hasNext() ) {
-			return flowpaths.next();
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * Get a flow path object with a flow entry.
-	 * @param flowEntry flow entry object
-	 */
-	@Override
-	public IFlowPath getFlowPathByFlowEntry(IFlowEntry flowEntry) {
-		GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
-		pipe.start(flowEntry.asVertex()).out("flow");
-		FramedVertexIterable<IFlowPath> r = new FramedVertexIterable<IFlowPath>(conn.getFramedGraph(),
-				pipe, IFlowPath.class);
-		return r.iterator().hasNext() ? r.iterator().next() : null;
-	}
-
-	/**
-	 * Get all flow path objects.
-	 */
-	@Override
-	public Iterable<IFlowPath> getAllFlowPaths() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		Iterable<IFlowPath> flowPaths = fg.getVertices("type", "flow", IFlowPath.class);
-
-		List<IFlowPath> nonNullFlows = new ArrayList<IFlowPath>();
-
-		for (IFlowPath fp: flowPaths) {
-			if (fp.getFlowId() != null) {
-				nonNullFlows.add(fp);
-			}
-		}
-		return nonNullFlows;
-	}
-
-    /**
-     * Remove the specified flow path.
-     * @param flowPath flow path object to remove
-     */
-	@Override
-	public void removeFlowPath(IFlowPath flowPath) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		fg.removeVertex(flowPath.asVertex());
-	}
-
-	/**
-	 * Create and return a flow entry object.
-	 */
-	@Override
-	public IFlowEntry newFlowEntry() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		IFlowEntry flowEntry = fg.addVertex(null, IFlowEntry.class);
-		if (flowEntry != null) flowEntry.setType("flow_entry");
-		return flowEntry;
-	}
-
-	/**
-	 * Search and get a flow entry object with flow entry ID.
-	 * @param flowEntryId flow entry ID to search
-	 */
-	@Override
-	public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if ( fg == null ) return null;
-		Iterator<IFlowEntry> flowentries = fg.getVertices("flow_entry_id", flowEntryId.toString(), IFlowEntry.class).iterator();
-		if ( flowentries.hasNext() ) {
-			return flowentries.next();
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * Get all flow entry objects.
-	 */
-	@Override
-	public Iterable<IFlowEntry> getAllFlowEntries() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-
-		return fg.getVertices("type", "flow_entry", IFlowEntry.class);
-	}
-
-	/**
-	 * Remove the specified flow entry.
-	 * @param flowEntry flow entry object to remove
-	 */
-	@Override
-	public void removeFlowEntry(IFlowEntry flowEntry) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		fg.removeVertex(flowEntry.asVertex());
-	}
-
-	/**
-	 * Get the instance of GraphDBConnection assigned to this class.
-	 */
-	@Override
-	public IDBConnection getDBConnection() {
-		return conn;
-	}
-
-	/**
-	 * Commit changes for the graph.
-	 */
-	@Override
-	public void commit() {
-		conn.commit();
-	}
-
-	/**
-	 * Rollback changes for the graph.
-	 */
-	@Override
-	public void rollback() {
-		conn.rollback();
-	}
-
-	/**
-	 * Close the connection of the assigned GraphDBConnection.
-	 */
-	@Override
-	public void close() {
-		conn.close();
-	}
-
-
-}
diff --git a/src/main/java/net/onrc/onos/graph/IDBConnection.java b/src/main/java/net/onrc/onos/graph/IDBConnection.java
index 82ebba2..cd65ec0 100644
--- a/src/main/java/net/onrc/onos/graph/IDBConnection.java
+++ b/src/main/java/net/onrc/onos/graph/IDBConnection.java
@@ -1,13 +1,12 @@
 package net.onrc.onos.graph;
 
-import com.thinkaurelius.titan.core.TitanGraph;
 import com.tinkerpop.frames.FramedGraph;
 
 public interface IDBConnection {
-	public FramedGraph<TitanGraph> getFramedGraph();
-	public void addEventListener(final LocalGraphChangedListener listener);
-	public Boolean isValid();
-	public void commit();
-	public void rollback();
-	public void close();
+    public FramedGraph getFramedGraph();
+    public void addEventListener(final LocalGraphChangedListener listener);
+    public Boolean isValid();
+    public void commit();
+    public void rollback();
+    public void close();
 }
diff --git a/src/main/java/net/onrc/onos/graph/IDBOperation.java b/src/main/java/net/onrc/onos/graph/IDBOperation.java
index 33d01fb..d2e8109 100644
--- a/src/main/java/net/onrc/onos/graph/IDBOperation.java
+++ b/src/main/java/net/onrc/onos/graph/IDBOperation.java
@@ -1,5 +1,9 @@
 package net.onrc.onos.graph;
 
+import java.util.Map;
+
+import com.tinkerpop.blueprints.Vertex;
+
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
@@ -10,7 +14,7 @@
 
 public interface IDBOperation {
 	public static final String PORT_ID_DELIM = "@";
-	
+
 	public ISwitchObject newSwitch(String dpid);
 	public ISwitchObject searchSwitch(String dpid);
 	public ISwitchObject searchActiveSwitch(String dpid);
@@ -19,13 +23,13 @@
 	public Iterable<ISwitchObject> getInactiveSwitches();
 	public Iterable<IFlowEntry> getAllSwitchNotUpdatedFlowEntries();
 	public void removeSwitch(ISwitchObject sw);
-	
+
 	@Deprecated
 	public IPortObject newPort(Short portNumber);
 	public IPortObject newPort(String dpid, Short portNum);
 	public IPortObject searchPort(String dpid, Short number);
 	public void removePort(IPortObject port);
-	
+
 	public IDeviceObject newDevice();
 	public IDeviceObject searchDevice(String macAddr);
 	public Iterable<IDeviceObject> getDevices();
@@ -41,10 +45,13 @@
 	public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId);
 	public Iterable<IFlowEntry> getAllFlowEntries();
 	public void removeFlowEntry(IFlowEntry flowEntry);
-	
-	public IDBConnection getDBConnection();	
+
+	public void setVertexProperties(Vertex vertex, Map<String, Object> map);
+
+	public IDBConnection getDBConnection();
 	public void commit();
 	public void rollback();
 	public void close();
-	Iterable<IPortObject> getAllPorts();
+
+	public Iterable<IPortObject> getAllPorts();
 }
diff --git a/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java b/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
index c005304..72227d5 100644
--- a/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
+++ b/src/main/java/net/onrc/onos/graph/LocalTopologyEventListener.java
@@ -13,12 +13,12 @@
 import com.tinkerpop.blueprints.Vertex;
 
 public class LocalTopologyEventListener implements LocalGraphChangedListener {
-	
+
 	protected final static Logger log = LoggerFactory.getLogger(LocalTopologyEventListener.class);
-	protected static GraphDBConnection conn;
-	
-	public LocalTopologyEventListener(GraphDBConnection conn) {
-		LocalTopologyEventListener.conn = conn;		
+	protected static DBConnection conn;
+
+	public LocalTopologyEventListener(DBConnection conn) {
+		LocalTopologyEventListener.conn = conn;
 	}
 
 	@Override
@@ -36,8 +36,7 @@
 	}
 
 	@Override
-	//public void edgeRemoved(Edge e, Map<String, Object> arg1) {
-	public void edgeRemoved(Edge e) {
+	public void edgeRemoved(Edge e, Map<String, Object> arg1) {
 		// TODO Auto-generated method stub
 		// Fire NetMapEvents (LinkRemoved, FlowEntryRemoved, HostRemoved, PortRemoved)
 		TitanEdge edge = (TitanEdge) e;
@@ -45,9 +44,9 @@
 		String label = edge.getLabel();
 		if (label.equals("link")) {
 			Vertex v = edge.getVertex(Direction.IN);
-			IPortObject src_port = conn.getFramedGraph().frame(v, IPortObject.class);
+			IPortObject src_port = (IPortObject) conn.getFramedGraph().frame(v, IPortObject.class);
 			v = edge.getVertex(Direction.OUT);
-			IPortObject dest_port = conn.getFramedGraph().frame(v, IPortObject.class);
+			IPortObject dest_port = (IPortObject) conn.getFramedGraph().frame(v, IPortObject.class);
 
 			log.debug("TopologyEvents: link broken {}", new Object []{src_port.getSwitch().getDPID(),
 																src_port.getNumber(),
@@ -75,16 +74,15 @@
 	}
 
 	@Override
-	//public void vertexRemoved(Vertex vertex, Map<String, Object> arg1) {
-	public void vertexRemoved(Vertex vertex) {
+	public void vertexRemoved(Vertex vertex, Map<String, Object> arg1) {
 		// TODO Auto-generated method stub
-		// Generate NetMapEvents 
+		// Generate NetMapEvents
 		String type = (String) vertex.getProperty("type");
 		log.debug("TopologyEvents: Received vertex removed event: {}",vertex);
 		if (type.equals("port")) {
 			// port is removed...lets fire reconcile here directly for now
-			
-			IPortObject src_port = conn.getFramedGraph().frame(vertex, IPortObject.class);
+
+			IPortObject src_port = (IPortObject) conn.getFramedGraph().frame(vertex, IPortObject.class);
 			log.debug("TopologyEvents: Port removed: {}:{}",src_port.getSwitch().getDPID(),src_port.getNumber());
 
 			// NOTE: Old code/logic.
@@ -99,14 +97,14 @@
 	public void edgePropertyChanged(Edge arg0, String arg1, Object arg2,
 			Object arg3) {
 		// TODO Auto-generated method stub
-		
+
 	}
 
 	@Override
 	public void vertexPropertyChanged(Vertex arg0, String arg1, Object arg2,
 			Object arg3) {
 		// TODO Auto-generated method stub
-		
+
 	}
 
 }
diff --git a/src/main/java/net/onrc/onos/graph/RamCloudDBConnection.java b/src/main/java/net/onrc/onos/graph/RamCloudDBConnection.java
new file mode 100644
index 0000000..547da44
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/RamCloudDBConnection.java
@@ -0,0 +1,126 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.graph;
+
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraph;
+import com.tinkerpop.frames.FramedGraph;
+import java.io.File;
+import java.util.Set;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public class RamCloudDBConnection extends DBConnection {
+    private RamCloudGraph graph;
+    private FramedGraph<RamCloudGraph> fg;
+    private static Logger log = LoggerFactory.getLogger(RamCloudDBConnection.class);
+    
+    public RamCloudDBConnection(final String dbConfigFile) {
+        final String coordinatorURL = open(getConfiguration(new File(dbConfigFile)));
+	graph = new RamCloudGraph(coordinatorURL);
+	Set<String> s = graph.getIndexedKeys(Vertex.class);
+        if (!s.contains("dpid")) {
+            graph.createKeyIndex("dpid", Vertex.class);
+        }
+        if (!s.contains("port_id")) {
+            graph.createKeyIndex("port_id", Vertex.class);
+        }
+        if (!s.contains("type")) {
+            graph.createKeyIndex("type", Vertex.class);
+        }
+        if (!s.contains("dl_addr")) {
+            graph.createKeyIndex("dl_addr", Vertex.class);
+        }
+        if (!s.contains("flow_id")) {
+            graph.createKeyIndex("flow_id", Vertex.class);
+        }
+        if (!s.contains("flow_entry_id")) {
+            graph.createKeyIndex("flow_entry_id", Vertex.class);
+        }
+        if (!s.contains("switch_state")) {
+            graph.createKeyIndex("switch_state", Vertex.class);
+	}
+	if (!s.contains("ipv4_address")) {
+	    graph.createKeyIndex("ipv4_address", Vertex.class);
+	}
+        fg = new FramedGraph<RamCloudGraph>(graph);
+    }
+    
+    @Override
+    public FramedGraph getFramedGraph() {
+        if (isValid()) {
+            return fg;
+        } else {
+            log.error("new FramedGraph failed");
+            return null;
+        }
+    }
+
+    @Override
+    public void addEventListener(LocalGraphChangedListener listener) {
+        //TO-DO
+    }
+
+    @Override
+    public Boolean isValid() {
+        return (graph != null);
+    }
+
+    @Override
+    public void commit() {
+        try {
+            graph.commit();
+        } catch (Exception e) {
+            log.error("{}", e.toString());
+        }
+    }
+
+    @Override
+    public void rollback() {
+        try {
+            graph.rollback();
+        } catch (Exception e) {
+            log.error("{}", e.toString());
+        }
+    }
+
+    @Override
+    public void close() {
+        commit();
+    }
+    
+     private static final Configuration getConfiguration(final File dirOrFile) {
+        if (dirOrFile == null) {
+            throw new IllegalArgumentException("Need to specify a configuration file or storage directory");
+        }
+
+        if (!dirOrFile.isFile()) {
+            throw new IllegalArgumentException("Location of configuration must be a file");
+        }
+
+        try {
+            return new PropertiesConfiguration(dirOrFile);
+        } catch (ConfigurationException e) {
+            throw new IllegalArgumentException("Could not load configuration at: " + dirOrFile, e);
+        }
+    }
+     
+    private String open(final Configuration configuration) {
+	final String coordinatorIp = configuration.getString("ramcloud.coordinatorIp", null);
+	final String coordinatorPort = configuration.getString("ramcloud.coordinatorPort", null);
+	final String coordinatorURL = coordinatorIp + "," + coordinatorPort;
+	if (coordinatorURL == null) {
+	    throw new RuntimeException("Configuration must contain a valid 'coordinatorURL' setting");
+	}
+	return coordinatorURL;
+    }
+}
diff --git a/src/main/java/net/onrc/onos/graph/RamCloudDBOperation.java b/src/main/java/net/onrc/onos/graph/RamCloudDBOperation.java
new file mode 100644
index 0000000..1487be7
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/RamCloudDBOperation.java
@@ -0,0 +1,27 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.graph;
+
+import com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraph;
+import com.tinkerpop.frames.FramedGraph;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects;
+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 org.apache.commons.configuration.Configuration;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public class RamCloudDBOperation extends DBOperation {
+
+    public RamCloudDBOperation() {
+    }
+}
diff --git a/src/main/java/net/onrc/onos/graph/TitanDBConnection.java b/src/main/java/net/onrc/onos/graph/TitanDBConnection.java
new file mode 100644
index 0000000..f46e417
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/TitanDBConnection.java
@@ -0,0 +1,122 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.graph;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.TransactionalGraph;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.util.wrappers.event.EventTransactionalGraph;
+import com.tinkerpop.frames.FramedGraph;
+import java.util.Set;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public class TitanDBConnection extends DBConnection {
+
+    private TitanGraph graph;
+    private static Logger log = LoggerFactory.getLogger(TitanDBConnection.class);
+    private EventTransactionalGraph<TitanGraph> eg;
+
+    public TitanDBConnection(final String dbConfigFile) {
+        graph = TitanFactory.open(dbConfigFile);
+        Set<String> s = graph.getIndexedKeys(Vertex.class);
+        if (!s.contains("dpid")) {
+            graph.createKeyIndex("dpid", Vertex.class);
+        }
+        if (!s.contains("port_id")) {
+            graph.createKeyIndex("port_id", Vertex.class);
+        }
+        if (!s.contains("type")) {
+            graph.createKeyIndex("type", Vertex.class);
+        }
+        if (!s.contains("dl_addr")) {
+            graph.createKeyIndex("dl_addr", Vertex.class);
+        }
+        if (!s.contains("flow_id")) {
+            graph.createKeyIndex("flow_id", Vertex.class);
+        }
+        if (!s.contains("flow_entry_id")) {
+            graph.createKeyIndex("flow_entry_id", Vertex.class);
+        }
+        if (!s.contains("switch_state")) {
+            graph.createKeyIndex("switch_state", Vertex.class);
+        }
+        graph.commit();
+        eg = new EventTransactionalGraph<TitanGraph>(graph);
+    }
+
+    class TransactionHandle {
+
+        protected TransactionalGraph tr;
+
+        public void create() {
+            tr = graph.newTransaction();
+        }
+    }
+
+    @Override
+    public FramedGraph getFramedGraph() {
+        if (isValid()) {
+            FramedGraph<TitanGraph> fg = new FramedGraph<TitanGraph>(graph);
+            return fg;
+        } else {
+            log.error("new FramedGraph failed");
+            return null;
+        }
+    }
+
+    @Override
+    public void addEventListener(LocalGraphChangedListener listener) {
+        EventTransactionalGraph<TitanGraph> eg = this.getEventGraph();
+        eg.addListener(listener);
+        log.debug("Registered listener {}", listener.getClass());
+    }
+
+    @Override
+    public Boolean isValid() {
+        return (graph != null || graph.isOpen());
+    }
+
+    @Override
+    public void commit() {
+        try {
+            graph.commit();
+        } catch (Exception e) {
+            log.error("{}", e.toString());
+        }
+    }
+
+    @Override
+    public void rollback() {
+        try {
+            graph.rollback();
+        } catch (Exception e) {
+            log.error("{}", e.toString());
+        }
+    }
+
+    @Override
+    public void close() {
+        commit();
+    }
+
+    /**
+     * Get EventTransactionalGraph of the titan graph.
+     *
+     * @return EventTransactionalGraph of the titan graph
+     */
+    private EventTransactionalGraph<TitanGraph> getEventGraph() {
+        if (isValid()) {
+            return eg;
+        } else {
+            return null;
+        }
+    }
+}
diff --git a/src/main/java/net/onrc/onos/graph/TitanDBOperation.java b/src/main/java/net/onrc/onos/graph/TitanDBOperation.java
new file mode 100644
index 0000000..1b211d6
--- /dev/null
+++ b/src/main/java/net/onrc/onos/graph/TitanDBOperation.java
@@ -0,0 +1,26 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.graph;
+
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.frames.FramedGraph;
+import com.tinkerpop.frames.structures.FramedVertexIterable;
+import com.tinkerpop.gremlin.java.GremlinPipeline;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.*;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage;
+import net.onrc.onos.ofcontroller.util.FlowEntryId;
+import net.onrc.onos.ofcontroller.util.FlowId;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public class TitanDBOperation extends DBOperation {
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/onrc/onos/graph/web/TopoDevicesResource.java b/src/main/java/net/onrc/onos/graph/web/TopoDevicesResource.java
index 18c1069..4f4abba 100644
--- a/src/main/java/net/onrc/onos/graph/web/TopoDevicesResource.java
+++ b/src/main/java/net/onrc/onos/graph/web/TopoDevicesResource.java
@@ -2,7 +2,8 @@
 
 import java.util.Iterator;
 
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
 
 import org.restlet.resource.Get;
@@ -12,7 +13,7 @@
 	
 	@Get("json")
 	public Iterator<IDeviceObject> retrieve() {
-		GraphDBOperation op = new GraphDBOperation("");
+		DBOperation op = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloud.conf");
 		
 		return op.getDevices().iterator();
 	}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
index 33280a6..4f6c310 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
@@ -41,7 +41,6 @@
 import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
 import net.onrc.onos.ofcontroller.proxyarp.BgpProxyArpManager;
 import net.onrc.onos.ofcontroller.proxyarp.IArpRequester;
-import net.onrc.onos.ofcontroller.proxyarp.IProxyArpService;
 import net.onrc.onos.ofcontroller.topology.ITopologyNetService;
 import net.onrc.onos.ofcontroller.topology.Topology;
 import net.onrc.onos.ofcontroller.topology.TopologyManager;
@@ -78,8 +77,7 @@
 
 public class BgpRoute implements IFloodlightModule, IBgpRouteService, 
 									ITopologyListener, IArpRequester,
-									IOFSwitchListener, IConfigInfoService,
-									IProxyArpService {
+									IOFSwitchListener, IConfigInfoService {
 	
 	private final static Logger log = LoggerFactory.getLogger(BgpRoute.class);
 
@@ -280,7 +278,7 @@
 		ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
 		topologyChangeDetectorTask = new SingletonTask(executor, new TopologyChangeDetector());
 
-		topologyNetService = new TopologyManager("");
+		topologyNetService = new TopologyManager(context);
 		
 		pathsWaitingOnArp = new HashMap<InetAddress, Path>();
 		prefixesWaitingOnArp = Multimaps.synchronizedSetMultimap(
@@ -1019,12 +1017,12 @@
 		}
 		
 		OFMatch matchLLDP = new OFMatch();
-		matchLLDP.setDataLayerType((short)0x8942);
+		matchLLDP.setDataLayerType((short)0x88cc);
 		matchLLDP.setWildcards(matchLLDP.getWildcards() & ~ OFMatch.OFPFW_DL_TYPE);
 		fmLLDP.setMatch(matchLLDP);
 		
 		OFMatch matchBDDP = new OFMatch();
-		matchBDDP.setDataLayerType((short)0x88cc);
+		matchBDDP.setDataLayerType((short)0x8942);
 		matchBDDP.setWildcards(matchBDDP.getWildcards() & ~ OFMatch.OFPFW_DL_TYPE);
 		fmBDDP.setMatch(matchBDDP);
 		
@@ -1287,27 +1285,4 @@
 	public short getVlan() {
 		return vlan;
 	}
-
-	/*
-	 * TODO This is a hack to get the REST API to work for ProxyArpManager.
-	 * The REST API is currently tied to the Floodlight module system and we
-	 * need to separate it to allow ONOS modules to use it. For now we will 
-	 * proxy calls through to the ProxyArpManager (which is not a Floodlight 
-	 * module) through this class which is a module.
-	 */
-	@Override
-	public MACAddress getMacAddress(InetAddress ipAddress) {
-		return proxyArp.getMacAddress(ipAddress);
-	}
-
-	@Override
-	public void sendArpRequest(InetAddress ipAddress, IArpRequester requester,
-			boolean retry) {
-		proxyArp.sendArpRequest(ipAddress, requester, retry);		
-	}
-
-	@Override
-	public List<String> getMappings() {
-		return proxyArp.getMappings();
-	}
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/RestClient.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/RestClient.java
index a9f2abe..9606d24 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/RestClient.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/RestClient.java
@@ -35,7 +35,7 @@
 				log.warn("The content received from {} is not json", str);
 			}		
 
-			BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream()))); 
+			BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
 			String line;
 			while ((line = br.readLine()) != null) {
 				response.append(line);
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/ILinkStorage.java b/src/main/java/net/onrc/onos/ofcontroller/core/ILinkStorage.java
index 8889092..6b285f4 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/ILinkStorage.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/ILinkStorage.java
@@ -10,7 +10,7 @@
     /*
 	 * Init with Storage conf
 	 */
-	public void init(String conf);
+	public void init(final String dbStore, final String conf);
 	
 	/*
 	 * Generic operation method
@@ -60,7 +60,8 @@
 	 * @param dpid DPID of desired switch.
 	 * @return List of reverse links. Empty list if no port was found.
 	 */
-	public List<Link> getReverseLinks(String dpid);
+
+        public List<Link> getReverseLinks(String dpid);
 
 	public List<Link> getActiveLinks();
 
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapStorage.java b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapStorage.java
index b052540..2cf0e18 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapStorage.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapStorage.java
@@ -14,6 +14,6 @@
 		DELETE, // Delete the object
 		UPDATE  // Update the object if exists or CREATE/INSERT if does not exist
 	}
-	public void init(String conf);
+	public void init(final String dbStore, final String conf);
 	public void close();
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/ISwitchStorage.java b/src/main/java/net/onrc/onos/ofcontroller/core/ISwitchStorage.java
index 2cfab3f..36729a6 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/ISwitchStorage.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/ISwitchStorage.java
@@ -16,7 +16,8 @@
 	/*
 	 * Initialize
 	 */
-	public void init(String conf);
+	public void init(final String dbStore, final String conf);
+
 	/*
 	 * Update the switch details
 	 */
@@ -49,7 +50,6 @@
 	 * Delete a port on a switch by num
 	 */
 	public boolean deletePort(String dpid, short port);
-
 	/**
 	 * Get list of all ports on the switch specified by given DPID.
 	 *
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 c830d44..6fcbb29 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
@@ -7,7 +7,8 @@
 
 import net.floodlightcontroller.devicemanager.IDevice;
 import net.floodlightcontroller.devicemanager.SwitchPort;
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.ofcontroller.core.IDeviceStorage;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IIpv4Address;
@@ -22,7 +23,6 @@
 import com.google.common.collect.Lists;
 import com.google.common.net.InetAddresses;
 import com.thinkaurelius.titan.core.TitanException;
-
 /**
  * This is the class for storing the information of devices into CassandraDB
  * @author Pankaj
@@ -30,17 +30,16 @@
 public class DeviceStorageImpl implements IDeviceStorage {
 	protected final static Logger log = LoggerFactory.getLogger(DeviceStorageImpl.class);
 
-	private GraphDBOperation ope;
-
+	private DBOperation ope;
 	/***
 	 * Initialize function. Before you use this class, please call this method
 	 * @param conf configuration file for Cassandra DB
 	 */
 	@Override
-	public void init(String conf) {
+	public void init(final String dbStore, final String conf) {
 		try {
-			ope = new GraphDBOperation(conf);
-		} catch (TitanException e) {
+			ope = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloud.conf");
+		} catch (Exception e) {
 			log.error("Couldn't open graph operation", e);
 		}
 	}
@@ -107,7 +106,6 @@
 
 		return obj;
 	}
-
 	/***
 	 * This function is for updating the Device properties.
 	 * @param device The device you want to add into the DB.
@@ -153,7 +151,6 @@
 
 		ope.removeDevice(deviceObject);
 	}
-
 	/***
 	 * This function is for getting the Device from the DB by Mac address of the device.
 	 * @param mac The device mac address you want to get from the DB.
@@ -161,7 +158,7 @@
 	 */
 	@Override
 	public IDeviceObject getDeviceByMac(String mac) {
-		return ope.searchDevice(mac);
+	    return ope.searchDevice(mac);
 	}
 
 	/***
@@ -191,15 +188,15 @@
 	@Override
 	public void changeDeviceAttachments(IDevice device) {
 		IDeviceObject obj = null;
- 		try {
-            if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
-                log.debug("Changing device ports {}: found existing device", device.getMACAddressString());
-                changeDeviceAttachments(device, obj);
-                ope.commit();
-            } else {
-   				log.debug("failed to search device...now adding {}", device.getMACAddressString());
-   				addDevice(device);
-            }
+		try {
+			if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
+				log.debug("Changing device ports {}: found existing device", device.getMACAddressString());
+				changeDeviceAttachments(device, obj);
+				ope.commit();
+			} else {
+				log.debug("failed to search device...now adding {}", device.getMACAddressString());
+				addDevice(device);
+			}
 		} catch (TitanException e) {
 			ope.rollback();
 			log.error(":addDevice mac:{} failed", device.getMACAddressString());
@@ -260,16 +257,15 @@
 		log.debug("Changing IP address for {} to {}", device.getMACAddressString(),
 				device.getIPv4Addresses());
 		IDeviceObject obj;
-  		try {
-  			if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
-  				changeDeviceIpv4Addresses(device, obj);
-
-              	ope.commit();
-  			} else {
-            	log.error(":changeDeviceIPv4Address mac:{} failed", device.getMACAddressString());
-            }
-  		} catch (TitanException e) {
-  			ope.rollback();
+		try {
+			if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
+				changeDeviceIpv4Addresses(device, obj);
+				ope.commit();
+			} else {
+				log.error(":changeDeviceIPv4Address mac:{} failed", device.getMACAddressString());
+			}
+		} catch (TitanException e) {
+			ope.rollback();
 			log.error(":changeDeviceIPv4Address mac:{} failed due to exception {}", device.getMACAddressString(), e);
 		}
 	}
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 16220b9..b43c58a 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
@@ -4,7 +4,7 @@
 import java.util.List;
 
 import net.floodlightcontroller.routing.Link;
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
 import net.onrc.onos.ofcontroller.core.ILinkStorage;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
@@ -15,22 +15,26 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
+import net.onrc.onos.graph.GraphDBManager;
+
 /**
  * This is the class for storing the information of links into GraphDB
  */
 public class LinkStorageImpl implements ILinkStorage {
 
 	protected final static Logger log = LoggerFactory.getLogger(LinkStorageImpl.class);
-	protected GraphDBOperation op;
-
+	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.
 	 */
 	@Override
-	public void init(String conf) {
-		this.op = new GraphDBOperation(conf);
+	public void init(final String dbStore, final String conf) {
+		this.dbop = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloud.conf");
+
 	}
 
 	// Method designing policy:
@@ -56,11 +60,11 @@
 			if (link != null) {
 				try {
 					if (addLinkImpl(link)) {
-						op.commit();
+						dbop.commit();
 						success = true;
 					}
 				} catch (Exception e) {
-					op.rollback();
+					dbop.rollback();
 					e.printStackTrace();
 		        	log.error("LinkStorageImpl:update {} link:{} failed", dmop, link);
 				}
@@ -70,11 +74,11 @@
 			if (link != null && linkinfo != null) {
 				try {
 					if (setLinkInfoImpl(link, linkinfo)) {
-						op.commit();
+						dbop.commit();
 						success = true;
 					}
 				} catch (Exception e) {
-					op.rollback();
+					dbop.rollback();
 					e.printStackTrace();
 		        	log.error("LinkStorageImpl:update {} link:{} failed", dmop, link);
 				}
@@ -84,15 +88,15 @@
 			if (link != null) {
 				try {
 					if (deleteLinkImpl(link)) {
-						op.commit();
+						dbop.commit();
 						success = true;
 		            	log.debug("LinkStorageImpl:update {} link:{} succeeded", dmop, link);
 		            } else {
-						op.rollback();
+						dbop.rollback();
 		            	log.debug("LinkStorageImpl:update {} link:{} failed", dmop, link);
 					}
 				} catch (Exception e) {
-					op.rollback();
+					dbop.rollback();
 					e.printStackTrace();
 					log.error("LinkStorageImpl:update {} link:{} failed", dmop, link);
 				}
@@ -110,7 +114,7 @@
 
 	private void deleteDeviceOnPort(Long dpid, Short number)
 	{
-		IPortObject srcPortObject = op.searchPort(HexString.toHexString(dpid), number);
+		IPortObject srcPortObject = dbop.searchPort(HexString.toHexString(dpid), number);
 		if (srcPortObject == null)
 		    return;
 		Iterable<IDeviceObject> devices = srcPortObject.getDevices();
@@ -135,22 +139,25 @@
 			deleteDeviceOnPort(link.getSrc(),link.getSrcPort());
 			deleteDeviceOnPort(link.getDst(),link.getDstPort());
 
+			pm.addlink_start();
 			if (addLinkImpl(link)) {
 				// Set LinkInfo only if linfo is non-null.
 				if (linfo != null && (! setLinkInfoImpl(link, linfo))) {
 					log.debug("Adding linkinfo failed: {}", link);
-					op.rollback();
+					dbop.rollback();
 				}
-				op.commit();
+				dbop.commit();
+				pm.addlink_end();
 				success = true;
 			} else {
+				pm.addlink_end();
 				// If we fail here that's because the ports aren't added
 				// before we try to add the link
 				log.debug("Adding link failed: {}", link);
-				op.rollback();
+				dbop.rollback();
 			}
 		} catch (Exception e) {
-			op.rollback();
+			dbop.rollback();
 			e.printStackTrace();
 			log.error("LinkStorageImpl:addLink link:{} linfo:{} failed", link, linfo);
 		}
@@ -174,10 +181,10 @@
 		}
 
 		try {
-			op.commit();
+			dbop.commit();
 			success = true;
 		} catch (Exception e) {
-			op.rollback();
+			dbop.rollback();
 			e.printStackTrace();
 			log.error("LinkStorageImpl:addLinks link:s{} failed", links);
 		}
@@ -197,15 +204,15 @@
 
         try {
          	if (deleteLinkImpl(lt)) {
-        		op.commit();
+        		dbop.commit();
         		success = true;
             	log.debug("LinkStorageImpl:deleteLink(): deleted edges {}", lt);
             } else {
-            	op.rollback();
+            	dbop.rollback();
             	log.error("LinkStorageImpl:deleteLink(): failed invalid vertices {}", lt);
             }
         } catch (Exception e) {
-        	op.rollback();
+        	dbop.rollback();
         	log.error("LinkStorageImpl:deleteLink(): failed {} {}",
         			new Object[]{lt, e.toString()});
         	e.printStackTrace();
@@ -225,14 +232,14 @@
 		try {
 			for (Link lt : links) {
 				if (! deleteLinkImpl(lt)) {
-					op.rollback();
+					dbop.rollback();
 					return false;
 				}
 			}
-			op.commit();
+			dbop.commit();
 			success = true;
 		} catch (Exception e) {
-        	op.rollback();
+        	dbop.rollback();
 			e.printStackTrace();
         	log.error("LinkStorageImpl:deleteLinks failed invalid vertices {}", links);
 		}
@@ -249,8 +256,7 @@
 	@Override
 	public List<Link> getLinks(Long dpid, short port) {
 	    List<Link> links = new ArrayList<Link>();
-
-	    IPortObject srcPort = op.searchPort(HexString.toHexString(dpid), port);
+	    IPortObject srcPort = dbop.searchPort(HexString.toHexString(dpid), port);
 	    if (srcPort == null)
 		return links;
 	    ISwitchObject srcSw = srcPort.getSwitch();
@@ -279,7 +285,7 @@
 	public List<Link> getReverseLinks(Long dpid, short port) {
 	    List<Link> links = new ArrayList<Link>();
 
-	    IPortObject srcPort = op.searchPort(HexString.toHexString(dpid), port);
+	    IPortObject srcPort = dbop.searchPort(HexString.toHexString(dpid), port);
 	    if (srcPort == null)
 		return links;
 	    ISwitchObject srcSw = srcPort.getSwitch();
@@ -311,15 +317,15 @@
 		try {
 			for(Link l : linksToDelete) {
 				if (! deleteLinkImpl(l)) {
-					op.rollback();
+					dbop.rollback();
 					log.error("LinkStorageImpl:deleteLinksOnPort dpid:{} port:{} failed", dpid, port);
 					return false;
 				}
 			}
-			op.commit();
+			dbop.commit();
 			success = true;
 		} catch (Exception e) {
-        	op.rollback();
+        	dbop.rollback();
 			e.printStackTrace();
         	log.error("LinkStorageImpl:deleteLinksOnPort dpid:{} port:{} failed", dpid, port);
 		}
@@ -335,8 +341,7 @@
 	@Override
 	public List<Link> getLinks(String dpid) {
 		List<Link> links = new ArrayList<Link>();
-
-		ISwitchObject srcSw = op.searchSwitch(dpid);
+		ISwitchObject srcSw = dbop.searchSwitch(dpid);
 
 		if(srcSw != null) {
 			for(IPortObject srcPort : srcSw.getPorts()) {
@@ -366,7 +371,7 @@
 	public List<Link> getReverseLinks(String dpid) {
 		List<Link> links = new ArrayList<Link>();
 
-		ISwitchObject srcSw = op.searchSwitch(dpid);
+		ISwitchObject srcSw = dbop.searchSwitch(dpid);
 
 		if(srcSw != null) {
 			for(IPortObject srcPort : srcSw.getPorts()) {
@@ -394,7 +399,7 @@
 	 */
 	@Override
 	public List<Link> getActiveLinks() {
-		Iterable<ISwitchObject> switches = op.getActiveSwitches();
+		Iterable<ISwitchObject> switches = dbop.getActiveSwitches();
 
 		List<Link> links = new ArrayList<Link>();
 
@@ -458,17 +463,22 @@
 		// get source port vertex
 		String dpid = HexString.toHexString(lt.getSrc());
 		short port = lt.getSrcPort();
-		vportSrc = op.searchPort(dpid, port);
+		log.debug("addLinkImpl Src dpid : {} port : {}", dpid, port);
+		vportSrc = dbop.searchPort(dpid, port);
 
 		// get dest port vertex
 		dpid = HexString.toHexString(lt.getDst());
 		port = lt.getDstPort();
-		vportDst = op.searchPort(dpid, port);
+		log.debug("addLinkImpl Dst dpid : {} port : {}", dpid, port);
+		vportDst = dbop.searchPort(dpid, port);
+
+		log.debug("addLinkImpl vportSrc : {} vportDst : {}", vportSrc, vportDst);
 
 		if (vportSrc != null && vportDst != null) {
 			IPortObject portExist = null;
 			// check if the link exists
 			for (IPortObject V : vportSrc.getLinkedPorts()) {
+			        log.debug("vportSrc.getLinkedPorts() :{}", V);
 				if (V.equals(vportDst)) {
 					portExist = V;
 					break;
@@ -479,8 +489,8 @@
 				vportSrc.setLinkPort(vportDst);
 				success = true;
 			} else {
-				log.debug("LinkStorageImpl:addLinkImpl failed link exists {} {} src {} dst {}",
-						new Object[]{op, lt, vportSrc, vportDst});
+				log.error("LinkStorageImpl:addLinkImpl failed link exists {} {} src {} dst {}",
+						new Object[]{dbop, lt, vportSrc, vportDst});
 			}
 		} else {
 			log.error("Ports not found : {}", lt);
@@ -496,12 +506,12 @@
 	    // get source port vertex
 	 	String dpid = HexString.toHexString(lt.getSrc());
 	 	short port = lt.getSrcPort();
-	 	vportSrc = op.searchPort(dpid, port);
+	 	vportSrc = dbop.searchPort(dpid, port);
 
 	    // get dst port vertex
 	 	dpid = HexString.toHexString(lt.getDst());
 	 	port = lt.getDstPort();
-	 	vportDst = op.searchPort(dpid, port);
+	 	vportDst = dbop.searchPort(dpid, port);
 
 		// FIXME: This needs to remove all edges
 		if (vportSrc != null && vportDst != null) {
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 9963887..ab73961 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
@@ -3,9 +3,12 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
+
 import net.floodlightcontroller.core.IOFSwitch;
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.graph.GraphDBManager;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
@@ -21,19 +24,24 @@
  * This is the class for storing the information of switches into GraphDB
  */
 public class SwitchStorageImpl implements ISwitchStorage {
-	protected GraphDBOperation op;
+
+	protected DBOperation op;
 	protected final static Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+	public final long measureONOSTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOS", "0"));
+	public final long measureAllTimeProp = Long.valueOf(System.getProperty("benchmark.measureAll", "0"));
+
+	private static PerfMon pm = PerfMon.getInstance();
 
 	/***
 	 * Initialize function. Before you use this class, please call this method
 	 * @param conf configuration file for Cassandra DB
 	 */
 	@Override
-	public void init(String conf) {
-		GraphDBConnection conn = GraphDBConnection.getInstance(conf);
-		op = new GraphDBOperation(conn);
+	public void init(final String dbStore, final String conf) {
+		op = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloud.conf");
 	}
 
+
 	/***
 	 * Finalize/close function. After you use this class, please call this method.
 	 * It will close the DB connection.
@@ -136,27 +144,65 @@
 
 		String dpid = sw.getStringId();
 		log.info("SwitchStorage:addSwitch(): dpid {} ", dpid);
-
+                long startSwitchTime = 0, endSwitchTime = 0;
+                long startUpdSwitchTime = 0, endUpdSwitchTime=0;
+                long startPortTime = 0, endPortTime=0;
+                long totalStartTime =0, totalEndTime=0;
+                long Tstamp1=0;
+		
 		try {
+			if (measureONOSTimeProp == 1) {
+		            log.error("Performance: addSwitch dpid= {} Start", dpid);
+			    totalStartTime = System.nanoTime();
+			}
+			pm.addswitch_start();
 			ISwitchObject curr = op.searchSwitch(dpid);
+			if (measureONOSTimeProp == 1) {
+			    Tstamp1 = System.nanoTime();
+		            log.error("Performance: addSwitch dpid= {} searchSwitch done at {} took {}", dpid, Tstamp1, Tstamp1-totalStartTime);
+			}
+
 			if (curr != null) {
 				//If existing the switch. set The SW state ACTIVE.
 				log.info("SwitchStorage:addSwitch dpid:{} already exists", dpid);
+				if (measureONOSTimeProp == 1) {
+				    startUpdSwitchTime = System.nanoTime();
+				}
 				setSwitchStateImpl(curr, SwitchState.ACTIVE);
+				if (measureONOSTimeProp == 1) {
+				    endUpdSwitchTime = System.nanoTime();
+				}
 			} else {
+				if (measureONOSTimeProp == 1) {
+				    startSwitchTime = System.nanoTime();
+				}
 				curr = addSwitchImpl(dpid);
+			        pm.addswitch_end();
+				if (measureONOSTimeProp == 1) {
+				    endSwitchTime = System.nanoTime();
+		                    //log.error("Performance: addSwitch dpid= {} addSwitchImpl done at {} took {}", dpid, endSwitchTime, endSwitchTime-startSwitchTime);
+		                    log.error("Performance: addSwitch dpid= {} End searchSwitch {} addSwitchImpl {} total {} diff {}", dpid, Tstamp1-totalStartTime, endSwitchTime-startSwitchTime, endSwitchTime-totalStartTime,endSwitchTime-totalStartTime-(Tstamp1-totalStartTime)-(endSwitchTime-startSwitchTime)); 
+				}
 			}
-
+			if (measureONOSTimeProp == 1) {
+			    startPortTime = System.nanoTime();
+			}
+                        long noOfPorts = 0;
+			pm.addport_start();
 			for (OFPhysicalPort port: sw.getPorts()) {
 				//addPort(dpid, port);
 				addPortImpl(curr, port);
-
+                                noOfPorts++;
+			    	pm.addport_incr();
 			}
-
+			pm.addport_end();
+			if (measureONOSTimeProp == 1) {
+			    endPortTime = System.nanoTime();
+			}
 			// XXX for now delete devices when we change a port to prevent
 			// having stale devices.
 			DeviceStorageImpl deviceStorage = new DeviceStorageImpl();
-			deviceStorage.init("");
+			deviceStorage.init("","");
 			for (IPortObject portObject : curr.getPorts()) {
 				for (IDeviceObject deviceObject : portObject.getDevices()) {
 					// The deviceStorage has to remove on the object gained by its own
@@ -166,6 +212,22 @@
 			}
 
 			op.commit();
+			if (measureONOSTimeProp == 1) {
+			    totalEndTime = System.nanoTime();
+			}
+                        if (startSwitchTime != 0) {
+                            //log.error("Performance -- switch add total time {}", endSwitchTime - startSwitchTime);
+                            log.error("Performance -- switch add total time {} including_search {}", endSwitchTime - startSwitchTime, endSwitchTime - totalStartTime);
+                        }
+                        if (startUpdSwitchTime != 0) {
+                            log.error("Performance -- switch update total time {} including_search {}", endUpdSwitchTime - startUpdSwitchTime, endUpdSwitchTime - totalStartTime);
+                        }
+                        if (startPortTime != 0) {
+                            log.error("Performance @@ port add total time {} no of ports written {}", endPortTime - startPortTime, noOfPorts);
+                        }
+			if (totalStartTime != 0) {
+			    log.error("Performance && total time for add switch {}", totalEndTime - totalStartTime);
+			}
 			success = true;
 		} catch (Exception e) {
 			op.rollback();
@@ -312,7 +374,7 @@
 	        	// XXX for now delete devices when we change a port to prevent
 	    		// having stale devices.
 	    		DeviceStorageImpl deviceStorage = new DeviceStorageImpl();
-	    		deviceStorage.init("");
+	    		deviceStorage.init("","");
 
 	    		for (IDeviceObject deviceObject : portObject.getDevices()) {
 	    			deviceStorage.removeDevice(deviceObject);
@@ -342,7 +404,7 @@
 		boolean success = false;
 
 		DeviceStorageImpl deviceStorage = new DeviceStorageImpl();
-		deviceStorage.init("");
+		deviceStorage.init("","");
 
 		try {
 			ISwitchObject sw = op.searchSwitch(dpid);
@@ -494,4 +556,4 @@
 	    			new Object[] {port.getPortId(), state, desc});
 		}
 	}
-}
\ No newline at end of file
+}
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 7c897d4..99a2eb1 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
@@ -4,7 +4,7 @@
 import java.util.List;
 
 import net.floodlightcontroller.routing.Link;
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoLinkService;
 
@@ -14,12 +14,13 @@
 
 import com.tinkerpop.blueprints.Vertex;
 import com.tinkerpop.gremlin.java.GremlinPipeline;
+import net.onrc.onos.graph.GraphDBManager;
 import com.tinkerpop.pipes.PipeFunction;
 import com.tinkerpop.pipes.transform.PathPipe;
 
 public class TopoLinkServiceImpl implements ITopoLinkService {
-
-	protected GraphDBOperation op;
+	
+	protected DBOperation dbop;
 	protected final static Logger log = LoggerFactory.getLogger(TopoLinkServiceImpl.class);
 
 	@Override
@@ -29,15 +30,16 @@
 
 	@Override
 	public void close() {
-		op.close();
+		dbop.close();
 	}
 
 	@Override
 	public List<Link> getActiveLinks() {
-		op = new GraphDBOperation("");
-		op.commit(); //Commit to ensure we see latest data
-		Iterable<ISwitchObject> switches = op.getActiveSwitches();
-		List<Link> links = new ArrayList<Link>();
+		dbop = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
+		//dbop = GraphDBManager.getDBOperation("", "");
+		//dbop.commit(); //Commit to ensure we see latest data
+		Iterable<ISwitchObject> switches = dbop.getActiveSwitches();
+		List<Link> links = new ArrayList<Link>(); 
 		for (ISwitchObject sw : switches) {
 			GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
 			ExtractLink extractor = new ExtractLink();
@@ -52,14 +54,14 @@
 			}
 
 		}
-		op.commit();
+		dbop.commit();
 		return links;
 	}
 
 	@Override
 	public List<Link> getLinksOnSwitch(String dpid) {
-		List<Link> links = new ArrayList<Link>();
-		ISwitchObject sw = op.searchSwitch(dpid);
+		List<Link> links = new ArrayList<Link>(); 
+		ISwitchObject sw = dbop.searchSwitch(dpid);
 		GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
 		ExtractLink extractor = new ExtractLink();
 
@@ -75,7 +77,7 @@
 
 	}
 
-	private class ExtractLink implements PipeFunction<PathPipe<Vertex>, Link> {
+	private static class ExtractLink implements PipeFunction<PathPipe<Vertex>, Link> {
 		@Override
 		public Link compute(PathPipe<Vertex> pipe) {
 			long s_dpid = 0;
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 52a5817..df5ab70 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
@@ -1,6 +1,7 @@
 package net.onrc.onos.ofcontroller.core.internal;
 
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoSwitchService;
@@ -10,15 +11,15 @@
 
 public class TopoSwitchServiceImpl implements ITopoSwitchService {
 
-	private GraphDBOperation op;
+	private DBOperation op;
 	protected final static Logger log = LoggerFactory.getLogger(TopoSwitchServiceImpl.class);
 
-	public TopoSwitchServiceImpl(String conf) {
-		op = new GraphDBOperation(conf);
+	public TopoSwitchServiceImpl(final String dbStore, String conf) {
+		op = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloud.conf");
 	}
 
 	public TopoSwitchServiceImpl() {
-		this("");
+		this("","");
 	}
 
 	@Override
@@ -34,27 +35,27 @@
 	@Override
 	public Iterable<ISwitchObject> getActiveSwitches() {
 		// TODO Auto-generated method stub
-		op.close(); //Commit to ensure we see latest data
+		//op.close(); //Commit to ensure we see latest data
 		return op.getActiveSwitches();
 	}
 
 	@Override
 	public Iterable<ISwitchObject> getAllSwitches() {
 		// TODO Auto-generated method stub
-		op.close(); //Commit to ensure we see latest data
+		//op.close(); //Commit to ensure we see latest data
 		return op.getAllSwitches();
 	}
 
 	@Override
 	public Iterable<ISwitchObject> getInactiveSwitches() {
 		// TODO Auto-generated method stub
-		op.close(); //Commit to ensure we see latest data
+		//op.close(); //Commit to ensure we see latest data
 		return op.getInactiveSwitches();
 	}
 
 	@Override
 	public Iterable<IPortObject> getPortsOnSwitch(String dpid) {
-		op.close(); //Commit to ensure we see latest data
+		//op.close(); //Commit to ensure we see latest data
 		ISwitchObject switchObject = op.searchSwitch(dpid);
 		if (switchObject != null) {
 			return switchObject.getPorts();
diff --git a/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDeviceManager.java b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDeviceManager.java
index f75a2b0..1b14875 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDeviceManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDeviceManager.java
@@ -179,7 +179,7 @@
 		floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
 		
 		deviceStorage = new DeviceStorageImpl();
-		deviceStorage.init("");
+		deviceStorage.init("","");
 	}
 
 	@Override
diff --git a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
index 6638ac0..98b80e6 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
@@ -20,9 +20,11 @@
 import net.floodlightcontroller.devicemanager.IDeviceListener;
 import net.floodlightcontroller.routing.Link;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.graph.DBConnection;
+import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.datagrid.IDatagridService;
-import net.onrc.onos.graph.GraphDBConnection;
-import net.onrc.onos.graph.GraphDBOperation;
 import net.onrc.onos.graph.IDBConnection;
 import net.onrc.onos.graph.LocalTopologyEventListener;
 import net.onrc.onos.ofcontroller.core.IDeviceStorage;
@@ -37,7 +39,7 @@
 import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
 import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
 import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
-import net.onrc.onos.ofcontroller.proxyarp.ArpMessage;
+import net.onrc.onos.ofcontroller.proxyarp.ArpReplyNotification;
 import net.onrc.onos.ofcontroller.topology.TopologyElement;
 import net.onrc.onos.registry.controller.IControllerRegistryService;
 import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
@@ -65,9 +67,10 @@
 	protected final static Logger log = LoggerFactory.getLogger(NetworkGraphPublisher.class);
 	//protected IDeviceService deviceService;
 	protected IControllerRegistryService registryService;
-	protected GraphDBOperation op;
+	protected DBOperation op;
 
 	protected static final String DBConfigFile = "dbconf";
+        protected static final String GraphDBStore = "graph_db_store";
 	protected static final String CleanupEnabled = "EnableCleanup";
 	protected IThreadPoolService threadPool;
 	protected IFloodlightProviderService floodlightProvider;
@@ -88,6 +91,7 @@
             Thread.currentThread().setName("SwitchCleanup@" + old);
             try {
             	log.debug("Running cleanup thread");
+		op = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloud.conf");
                 switchCleanup();
             }
             catch (Exception e) {
@@ -151,7 +155,7 @@
     }
 
     protected void switchCleanup() {
-    	op.close();
+    	//op.close();
     	Iterable<ISwitchObject> switches = op.getActiveSwitches();
 
     	log.debug("Checking for inactive switches");
@@ -393,8 +397,9 @@
 		log.debug("{}:deviceAdded(): Adding device {}",this.getClass(),device.getMACAddressString());
 		devStore.addDevice(device);
 		for (int intIpv4Address : device.getIPv4Addresses()) {
-			datagridService.sendArpRequest(
-					ArpMessage.newReply(InetAddresses.fromInteger(intIpv4Address)));
+			datagridService.sendArpReplyNotification(new ArpReplyNotification(
+					InetAddresses.fromInteger(intIpv4Address), 
+					MACAddress.valueOf(device.getMACAddress())));
 		}
 	}
 
@@ -454,7 +459,11 @@
 			throws FloodlightModuleException {
 		Map<String, String> configMap = context.getConfigParams(this);
 		String conf = configMap.get(DBConfigFile);
-		op = new GraphDBOperation(conf);
+                String dbStore = configMap.get(GraphDBStore);
+		op = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloud.conf");
+		if (op == null) {
+		    System.out.println("publisher op is null");
+		}
 
 		floodlightProvider =
 	            context.getServiceImpl(IFloodlightProviderService.class);
@@ -465,13 +474,13 @@
 		datagridService = context.getServiceImpl(IDatagridService.class);
 
 		devStore = new DeviceStorageImpl();
-		devStore.init(conf);
+		devStore.init(dbStore, conf);
 
 		swStore = new SwitchStorageImpl();
-		swStore.init(conf);
+		swStore.init(dbStore, conf);
 
 		linkStore = new LinkStorageImpl();
-		linkStore.init(conf);
+		linkStore.init(dbStore, conf);
 
 		log.debug("Initializing NetworkGraphPublisher module with {}", conf);
 
@@ -488,7 +497,7 @@
 
 		log.debug("Adding EventListener");
 		IDBConnection conn = op.getDBConnection();
-		conn.addEventListener(new LocalTopologyEventListener((GraphDBConnection) conn));
+		conn.addEventListener(new LocalTopologyEventListener((DBConnection) conn));
 	       // Setup the Cleanup task.
 		if (cleanupNeeded == null || !cleanupNeeded.equals("False")) {
 				ScheduledExecutorService ses = threadPool.getScheduledExecutor();
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/ApplnObjectType.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/ApplnObjectType.java
new file mode 100644
index 0000000..8cb1316
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/ApplnObjectType.java
@@ -0,0 +1,16 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.ofcontroller.flowmanager;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public enum ApplnObjectType {
+    FLOWPATH,
+    FLOWENTRY,  
+    UNKNOWN
+}
+
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/DBOperationType.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/DBOperationType.java
new file mode 100644
index 0000000..e0de595
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/DBOperationType.java
@@ -0,0 +1,18 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.ofcontroller.flowmanager;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public enum DBOperationType {
+    ADD,
+    UPDATE,
+    QUERY,
+    REMOVE,
+    INVALID
+}
+
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
old mode 100644
new mode 100755
index 1fb18db..d8e50fc
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
@@ -1,18 +1,17 @@
 package net.onrc.onos.ofcontroller.flowmanager;
 
+import com.tinkerpop.blueprints.Direction;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedList;
-import java.util.List;
 import java.util.Map;
 
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.util.MACAddress;
-
-import net.onrc.onos.graph.GraphDBOperation;
-
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IBaseObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
@@ -22,148 +21,150 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
+import com.tinkerpop.blueprints.impls.ramcloud.RamCloudVertex;
+
 /**
  * Class for performing Flow-related operations on the Database.
  */
 public class FlowDatabaseOperation {
     private final static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
+    private static final boolean measureONOSFlowTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlow", "0")) != 0;
+    private static final boolean measureONOSFlowEntryTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlowEntry", "0")) != 0;
 
     /**
-     * Add a flow.
+     * Add a flow by batching all flow path properties and flow entries together.
+     * This is done for performance reasons.
      *
      * @param dbHandler the Graph Database handler to use.
      * @param flowPath the Flow Path to install.
      * @return true on success, otherwise false.
      */
-    static boolean addFlow(GraphDBOperation dbHandler, FlowPath flowPath) {
-	IFlowPath flowObj = null;
-	boolean found = false;
-	try {
-	    if ((flowObj = dbHandler.searchFlowPath(flowPath.flowId())) != null) {
-		found = true;
-	    } else {
-		flowObj = dbHandler.newFlowPath();
+    static boolean addFlowFast(DBOperation dbHandler, FlowPath flowPath) {
+	IFlowPath flowPathObj;
+	FlowPathProperty flowProp = new FlowPathProperty();
+        FlowEntity flowPathEntity = new FlowEntity();
+        boolean flowPathUpdate = false;
+	
+	flowPathObj = dbHandler.searchFlowPath(flowPath.flowId()); // getVertices("flow_id")
+	if (flowPathObj == null) {
+	    try {
+                flowPathEntity.operationBegin(DBOperationType.ADD.toString());
+		flowPathObj = dbHandler.newFlowPath();
+	    } catch (Exception e) {
+		flowPathObj = null;
+		StringWriter sw = new StringWriter();
+		e.printStackTrace(new PrintWriter(sw));
+		log.error(":addFlow FlowId:{} failed: {}", flowPath.flowId(), sw.toString());
 	    }
-	} catch (Exception e) {
-	    dbHandler.rollback();
-
-	    StringWriter sw = new StringWriter();
-	    e.printStackTrace(new PrintWriter(sw));
-	    String stacktrace = sw.toString();
-
-	    log.error(":addFlow FlowId:{} failed: {}",
-		      flowPath.flowId(),
-		      stacktrace);
-	    return false;
+            flowPathEntity.setProperty("user_state", "FP_USER_ADD");
+	    flowProp.setFlowPathUserState("FP_USER_ADD");
+	} else {
+            flowPathUpdate = true;
+	    // Remove the old Flow Entries (this is special for RAMCloud)
+	    for (IFlowEntry flowEntryObj : flowPathObj.getFlowEntries()) { // get.@Adjacency("flow", IN)
+                flowPathEntity.operationBegin(DBOperationType.REMOVE.toString());
+		dbHandler.removeFlowEntry(flowEntryObj); // removeVertex()
+                flowPathEntity.operationEnd(DBOperationType.REMOVE.toString());
+	    }
+            flowPathEntity.operationBegin(DBOperationType.UPDATE.toString());
+            flowPathEntity.setProperty("user_state", "FP_USER_ADD");
+	    flowProp.setFlowPathUserState("FP_USER_MODIFY");
 	}
-	if (flowObj == null) {
-	    log.error(":addFlow FlowId:{} failed: Flow object not created",
-		      flowPath.flowId());
+	if (flowPathObj == null) {
+	    log.error(":addFlow FlowId:{} failed: Flow object not created", flowPath.flowId());
 	    dbHandler.rollback();
 	    return false;
 	}
 
-	//
-	// Remove the old Flow Entries
-	//
-	if (found) {
-	    Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
-	    LinkedList<IFlowEntry> deleteFlowEntries =
-		new LinkedList<IFlowEntry>();
-	    for (IFlowEntry flowEntryObj : flowEntries)
-		deleteFlowEntries.add(flowEntryObj);
-	    for (IFlowEntry flowEntryObj : deleteFlowEntries) {
-		flowObj.removeFlowEntry(flowEntryObj);
-		dbHandler.removeFlowEntry(flowEntryObj);
-	    }
-	}
+        flowPathEntity.setProperty("flow_id", flowPath.flowId().toString());
+	// Set the Flow key
+	flowProp.setFlowId(flowPath.flowId().toString());
 
-	//
-	// Set the Flow key:
-	// - flowId
-	//
-	flowObj.setFlowId(flowPath.flowId().toString());
-	flowObj.setType("flow");
+	// Set the Flow attributes
+        flowPathEntity.setProperty("installer_id", flowPath.installerId().toString());
+	flowProp.setInstallerId(flowPath.installerId().toString());
 
-	//
-	// Set the Flow attributes:
-	// - flowPath.installerId()
-	// - flowPath.flowPathType()
-	// - flowPath.flowPathUserState()
-	// - flowPath.flowPathFlags()
-	// - flowPath.idleTimeout()
-	// - flowPath.hardTimeout()
-	// - flowPath.dataPath().srcPort()
-	// - flowPath.dataPath().dstPort()
-	// - flowPath.matchSrcMac()
-	// - flowPath.matchDstMac()
-	// - flowPath.matchEthernetFrameType()
-	// - flowPath.matchVlanId()
-	// - flowPath.matchVlanPriority()
-	// - flowPath.matchSrcIPv4Net()
-	// - flowPath.matchDstIPv4Net()
-	// - flowPath.matchIpProto()
-	// - flowPath.matchIpToS()
-	// - flowPath.matchSrcTcpUdpPort()
-	// - flowPath.matchDstTcpUdpPort()
-	// - flowPath.flowEntryActions()
-	//
-	flowObj.setInstallerId(flowPath.installerId().toString());
-	flowObj.setFlowPathType(flowPath.flowPathType().toString());
-	flowObj.setFlowPathUserState(flowPath.flowPathUserState().toString());
-	flowObj.setFlowPathFlags(flowPath.flowPathFlags().flags());
-	flowObj.setIdleTimeout(flowPath.idleTimeout());
-	flowObj.setHardTimeout(flowPath.hardTimeout());
-	flowObj.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
-	flowObj.setSrcPort(flowPath.dataPath().srcPort().port().value());
-	flowObj.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
-	flowObj.setDstPort(flowPath.dataPath().dstPort().port().value());
+        flowPathEntity.setProperty("flow_path_type", flowPath.flowPathType().toString());
+	flowProp.setFlowPathType(flowPath.flowPathType().toString());
+
+        flowPathEntity.setProperty("user_state", flowPath.flowPathUserState().toString());
+	flowProp.setFlowPathUserState(flowPath.flowPathUserState().toString());
+
+
+        flowPathEntity.setProperty("flow_path_flags", flowPath.flowPathFlags().flags());
+	flowProp.setFlowPathFlags(flowPath.flowPathFlags().flags());
+
+        flowPathEntity.setProperty("idle_timeout", flowPath.idleTimeout());
+	flowProp.setIdleTimeout(flowPath.idleTimeout());
+
+        flowPathEntity.setProperty("hard_timeout", flowPath.hardTimeout());
+	flowProp.setHardTimeout(flowPath.hardTimeout());
+
+        flowPathEntity.setProperty("src_switch", flowPath.dataPath().srcPort().dpid().toString());
+	flowProp.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
+
+        flowPathEntity.setProperty("src_port", flowPath.dataPath().srcPort().port().value());
+	flowProp.setSrcPort(flowPath.dataPath().srcPort().port().value());
+
+        flowPathEntity.setProperty("dst_switch", flowPath.dataPath().dstPort().dpid().toString());
+	flowProp.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
+
+        flowPathEntity.setProperty("dst_port", flowPath.dataPath().dstPort().port().value());
+	flowProp.setDstPort(flowPath.dataPath().dstPort().port().value());
+
 	if (flowPath.flowEntryMatch().matchSrcMac()) {
-	    flowObj.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
+            flowPathEntity.setProperty("matchSrcMac",flowPath.flowEntryMatch().srcMac().toString());
+	    flowProp.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
 	}
 	if (flowPath.flowEntryMatch().matchDstMac()) {
-	    flowObj.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
+            flowPathEntity.setProperty("matchDstMac", flowPath.flowEntryMatch().dstMac().toString());
+	    flowProp.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
 	}
 	if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
-	    flowObj.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
+            flowPathEntity.setProperty("matchEthernetFrameType", flowPath.flowEntryMatch().ethernetFrameType());
+	    flowProp.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
 	}
 	if (flowPath.flowEntryMatch().matchVlanId()) {
-	    flowObj.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
+            flowPathEntity.setProperty("matchVlanId", flowPath.flowEntryMatch().vlanId());
+	    flowProp.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
 	}
 	if (flowPath.flowEntryMatch().matchVlanPriority()) {
-	    flowObj.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
+            flowPathEntity.setProperty("matchVlanPriority", flowPath.flowEntryMatch().vlanPriority());
+	    flowProp.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
 	}
 	if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
-	    flowObj.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
+            flowPathEntity.setProperty("matchSrcIPv4Net", flowPath.flowEntryMatch().srcIPv4Net().toString());
+	    flowProp.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
 	}
 	if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
-	    flowObj.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
+            flowPathEntity.setProperty("matchDstIPv4Net", flowPath.flowEntryMatch().dstIPv4Net().toString());
+	    flowProp.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
 	}
 	if (flowPath.flowEntryMatch().matchIpProto()) {
-	    flowObj.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
+            flowPathEntity.setProperty("matchIpProto", flowPath.flowEntryMatch().ipProto());
+	    flowProp.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
 	}
 	if (flowPath.flowEntryMatch().matchIpToS()) {
-	    flowObj.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
+            flowPathEntity.setProperty("matchIpToS", flowPath.flowEntryMatch().ipToS());
+	    flowProp.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
 	}
 	if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
-	    flowObj.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
+            flowPathEntity.setProperty("matchSrcTcpUdpPort", flowPath.flowEntryMatch().srcTcpUdpPort());
+	    flowProp.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
 	}
 	if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
-	    flowObj.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
+            flowPathEntity.setProperty("matchDstTcpUdpPort", flowPath.flowEntryMatch().dstTcpUdpPort());
+	    flowProp.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
 	}
 	if (! flowPath.flowEntryActions().actions().isEmpty()) {
-	    flowObj.setActions(flowPath.flowEntryActions().toString());
+            flowPathEntity.setProperty("actions", flowPath.flowEntryActions().toString());
+	    flowProp.setActions(flowPath.flowEntryActions().toString());
 	}
-	flowObj.setDataPathSummary(flowPath.dataPath().dataPathSummary());
+        flowPathEntity.setProperty("data_path_summary", flowPath.dataPath().dataPathSummary());
+	flowProp.setDataPathSummary(flowPath.dataPath().dataPathSummary());
 
-	if (found)
-	    flowObj.setFlowPathUserState("FP_USER_MODIFY");
-	else
-	    flowObj.setFlowPathUserState("FP_USER_ADD");
-
-	// Flow edges:
-	//   HeadFE
-
+	flowProp.commitProperties(dbHandler, flowPathObj);
 
 	//
 	// Flow Entries:
@@ -173,15 +174,129 @@
 	    if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
 		continue;	// Skip: all Flow Entries were deleted earlier
 
-	    if (addFlowEntry(dbHandler, flowObj, flowEntry) == null) {
-		dbHandler.rollback();
-		return false;
+	    IFlowEntry iFlowEntry;
+	    FlowEntryProperty flowEntryProp = new FlowEntryProperty();
+            FlowEntity flowEntryEntity = new FlowEntity();
+            boolean updateFlowEntry = false;
+	    
+	    try {
+		iFlowEntry = dbHandler.searchFlowEntry(flowEntry.flowEntryId()); // getVertices()
+		if (iFlowEntry != null) {
+                    updateFlowEntry = true;
+                    flowEntryEntity.operationBegin(DBOperationType.UPDATE.toString());
+                    flowEntryEntity.setProperty("user_state", "FE_USER_MODIFY");
+		    flowEntryProp.setUserState("FE_USER_MODIFY");
+		} else {
+                    flowEntryEntity.operationBegin(DBOperationType.ADD.toString());
+                    flowEntryEntity.setProperty("user_state", "FE_USER_ADD");
+		    flowEntryProp.setUserState("FE_USER_ADD");
+                    flowEntryEntity.addEdge(flowPathObj, Direction.OUT, "flow");
+		}
+	    } catch (Exception e) {
+                // TODO do we really need to catch this exception.
 	    }
-	}
-	dbHandler.commit();
+	    
+            flowEntryEntity.setProperty("flow_id", flowEntry.flowEntryId().toString());
+	    // Set the Flow Entry key
+           flowEntryEntity.setProperty("flow_entry_id", flowEntry.flowEntryId().toString());
 
+            flowEntryEntity.setProperty("type", "flow_entry");
+
+	    // Set the Flow Entry Edges
+	    ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString()); // toshi memo: getVertices()
+
+            flowEntryEntity.setProperty("idle_timeout", flowEntry.idleTimeout());
+
+            flowEntryEntity.setProperty("hard_timeout", flowEntry.hardTimeout());
+
+            flowEntryEntity.setProperty("switch_dpid", flowEntry.dpid().toString());
+
+            flowEntryEntity.addEdge(sw, Direction.OUT, "switch");
+	    if (flowEntry.flowEntryMatch().matchInPort()) {
+		IPortObject inport = dbHandler.searchPort(flowEntry.dpid().toString(), flowEntry.flowEntryMatch().inPort().value()); // toshi memo: getVertices()
+
+                flowEntryEntity.setProperty("matchInPort", flowEntry.flowEntryMatch().inPort().value());
+                flowEntryEntity.addEdge(inport, Direction.OUT, "inport");
+	    }
+
+	    // Set the Flow Entry attributes
+	    if (flowEntry.flowEntryMatch().matchSrcMac()) {
+                flowEntryEntity.setProperty("matchSrcMac", flowEntry.flowEntryMatch().srcMac().toString());
+	    }
+	    if (flowEntry.flowEntryMatch().matchDstMac()) {
+                flowEntryEntity.setProperty("matchDstMac", flowEntry.flowEntryMatch().dstMac().toString());
+	    }
+	    if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
+                flowEntryEntity.setProperty("matchEthernetFrameType", flowEntry.flowEntryMatch().ethernetFrameType());
+	    }
+	    if (flowEntry.flowEntryMatch().matchVlanId()) {
+                flowEntryEntity.setProperty("matchVlanId", flowEntry.flowEntryMatch().vlanId());
+	    }
+	    if (flowEntry.flowEntryMatch().matchVlanPriority()) {
+                flowEntryEntity.setProperty("matchVlanPriority", flowEntry.flowEntryMatch().vlanPriority());
+	    }
+	    if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
+                flowEntryEntity.setProperty("matchSrcIPv4Net", flowEntry.flowEntryMatch().srcIPv4Net().toString());
+	    }
+	    if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
+                flowEntryEntity.setProperty("matchDstIPv4Net", flowEntry.flowEntryMatch().dstIPv4Net().toString());
+	    }
+	    if (flowEntry.flowEntryMatch().matchIpProto()) {
+                flowEntryEntity.setProperty("matchIpProto", flowEntry.flowEntryMatch().ipProto());
+	    }
+	    if (flowEntry.flowEntryMatch().matchIpToS()) {
+                flowEntryEntity.setProperty("matchIpToS", flowEntry.flowEntryMatch().ipToS());
+	    }
+	    if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
+                flowEntryEntity.setProperty("matchSrcTcpUdpPort", flowEntry.flowEntryMatch().srcTcpUdpPort());
+	    }
+	    if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
+                flowEntryEntity.setProperty("matchDstTcpUdpPort", flowEntry.flowEntryMatch().dstTcpUdpPort());
+	    }
+
+	    for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
+		if (fa.actionOutput() != null) {
+		    IPortObject outport = dbHandler.searchPort(flowEntry.dpid().toString(), fa.actionOutput().port().value()); // toshi memo: getVertices()
+                    flowEntryEntity.setProperty("actionOutputPort", fa.actionOutput().port().value());
+                    flowEntryEntity.addEdge(outport, Direction.OUT, "outport");
+		}
+	    }
+	    if (! flowEntry.flowEntryActions().isEmpty()) {
+                flowEntryEntity.setProperty("actions", flowEntry.flowEntryActions().toString());
+	    }
+
+            flowEntryEntity.setProperty("switch_state", flowEntry.flowEntrySwitchState().toString());
+            if (updateFlowEntry) {
+               flowEntryEntity.operationEnd(DBOperationType.UPDATE.toString());
+            } else {
+               flowEntryEntity.operationEnd(DBOperationType.ADD.toString());
+            }
+            flowPathEntity.append(flowEntryEntity);
+	}
+	
+        if (flowPathUpdate) {
+            flowPathEntity.operationEnd(DBOperationType.UPDATE.toString());
+        } else {
+            flowPathEntity.operationEnd(DBOperationType.ADD.toString());
+        }
+        flowPathEntity.persist(dbHandler);
 	return true;
     }
+    
+    /**
+     * Add a flow.
+     *
+     * @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) {
+        PerfMon pm = PerfMon.getInstance();
+        pm.addflowpath_start();
+        boolean retValue = addFlowFast(dbHandler, flowPath);
+        pm.addflowpath_end();
+        return retValue;
+    }
 
     /**
      * Add a flow entry to the Network MAP.
@@ -191,20 +306,65 @@
      * @param flowEntry the Flow Entry to install.
      * @return the added Flow Entry object on success, otherwise null.
      */
-    static IFlowEntry addFlowEntry(GraphDBOperation dbHandler,
+    static IFlowEntry addFlowEntry(DBOperation dbHandler,
 				   IFlowPath flowObj,
 				   FlowEntry flowEntry) {
 	// Flow edges
 	//   HeadFE (TODO)
+	long startAddFlowEntry = 0;
+	long endAddFlowEntry = 0;
+
+	long endSearchFlowEntry = 0;
+
+	long startCreateNewFlowEntry = 0;
+	long endCreateNewFlowEntry = 0;
+
+	long startSetProperties = 0;
+	long endSetProperties = 0;
+	int numProperties = 0;
+
+	long startSearchSwitch = 0;
+	long endSearchSwitch = 0;
+
+	long startAddEdgeToSwitch =0;
+	long endAddEdgeToSwitch =0;
+
+	long startSearchInPort = 0;
+	long endSearchInPort = 0;
+
+	long startAddEdgeToInPort =0;
+	long endAddEdgeToInPort =0;
+
+	long startSearchOutPort = 0;
+	long endSearchOutPort = 0;
+
+	long startAddEdgeToOutPort =0;
+	long endAddEdgeToOutPort =0;
+
+	long startAddEdgeBetweenFlowPath = 0;
+	long endAddEdgeBetweenFlowPath = 0;
+
+	if (measureONOSFlowEntryTimeProp) {
+		startAddFlowEntry = System.nanoTime();
+	}
 
 	IFlowEntry flowEntryObj = null;
 	boolean found = false;
 	try {
-	    if ((flowEntryObj =
-		 dbHandler.searchFlowEntry(flowEntry.flowEntryId())) != null) {
+	    flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
+	    if (measureONOSFlowEntryTimeProp) {
+		endSearchFlowEntry = System.nanoTime();
+	    }
+	    if (flowEntryObj != null) {
 		found = true;
 	    } else {
+		if (measureONOSFlowEntryTimeProp) {
+		    startCreateNewFlowEntry = System.nanoTime();
+		}
 		flowEntryObj = dbHandler.newFlowEntry();
+		if (measureONOSFlowEntryTimeProp) {
+		    endCreateNewFlowEntry = System.nanoTime();
+		}
 	    }
 	} catch (Exception e) {
 	    log.error(":addFlow FlowEntryId:{} failed",
@@ -217,14 +377,23 @@
 	    return null;
 	}
 
+	if (measureONOSFlowEntryTimeProp) {
+	    startSetProperties = System.nanoTime();
+	}
+
+	FlowEntryProperty flowProp = new FlowEntryProperty();
+
 	//
 	// Set the Flow Entry key:
 	// - flowEntry.flowEntryId()
 	//
-	flowEntryObj.setFlowEntryId(flowEntry.flowEntryId().toString());
-	flowEntryObj.setType("flow_entry");
+	flowProp.setFlowEntryId(flowEntry.flowEntryId().toString());
+	flowProp.setType("flow_entry");
+	if (measureONOSFlowEntryTimeProp) {
+	    numProperties += 2;
+	}
 
-	// 
+	//
 	// Set the Flow Entry Edges and attributes:
 	// - Switch edge
 	// - InPort edge
@@ -251,77 +420,207 @@
 	// - flowEntry.actionOutputPort()
 	// - flowEntry.actions()
 	//
+	if (measureONOSFlowEntryTimeProp) {
+	    startSearchSwitch = System.nanoTime();
+	}
 	ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
-	flowEntryObj.setIdleTimeout(flowEntry.idleTimeout());
-	flowEntryObj.setHardTimeout(flowEntry.hardTimeout());
-	flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
+	if (measureONOSFlowEntryTimeProp) {
+	    endSearchSwitch = System.nanoTime();
+	}
+
+	flowProp.setIdleTimeout(flowEntry.idleTimeout());
+	flowProp.setHardTimeout(flowEntry.hardTimeout());
+	flowProp.setSwitchDpid(flowEntry.dpid().toString());
+	if (measureONOSFlowEntryTimeProp) {
+	    numProperties += 3;
+	}
+
+	if (measureONOSFlowEntryTimeProp) {
+	    startAddEdgeToSwitch = System.nanoTime();
+	}
 	flowEntryObj.setSwitch(sw);
+	if (measureONOSFlowEntryTimeProp) {
+	    endAddEdgeToSwitch = System.nanoTime();
+	}
 	if (flowEntry.flowEntryMatch().matchInPort()) {
+	    if (measureONOSFlowEntryTimeProp) {
+		startSearchInPort = System.nanoTime();
+	    }
 	    IPortObject inport =
-		dbHandler.searchPort(flowEntry.dpid().toString(),
-					flowEntry.flowEntryMatch().inPort().value());
-	    flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
+		    dbHandler.searchPort(flowEntry.dpid().toString(),
+			    flowEntry.flowEntryMatch().inPort().value());
+	    if (measureONOSFlowEntryTimeProp) {
+		endSearchInPort = System.nanoTime();
+	    }
+
+	    flowProp.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
+
+	    if (measureONOSFlowEntryTimeProp) {
+		startAddEdgeToInPort = System.nanoTime();
+	    }
 	    flowEntryObj.setInPort(inport);
+	    if (measureONOSFlowEntryTimeProp) {
+		endAddEdgeToInPort = System.nanoTime();
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchSrcMac()) {
-	    flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
+		flowProp.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchDstMac()) {
-	    flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
+		flowProp.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
-	    flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
+		flowProp.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchVlanId()) {
-	    flowEntryObj.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
+		flowProp.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchVlanPriority()) {
-	    flowEntryObj.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
+		flowProp.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
-	    flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
+		flowProp.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
-	    flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
+		flowProp.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchIpProto()) {
-	    flowEntryObj.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
+		flowProp.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchIpToS()) {
-	    flowEntryObj.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
+		flowProp.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
-	    flowEntryObj.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
+		flowProp.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 	if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
-	    flowEntryObj.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
+		flowProp.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 
 	for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
 	    if (fa.actionOutput() != null) {
+		if (measureONOSFlowEntryTimeProp) {
+		    if ( startSearchOutPort != 0 ) log.error("Performance addFlowEntry(_,{},{}) -- Multiple output port action unexpected.", flowEntry.flowId(), flowEntry.flowEntryId());
+		    startSearchOutPort = System.nanoTime();
+		}
 		IPortObject outport =
-		    dbHandler.searchPort(flowEntry.dpid().toString(),
-					      fa.actionOutput().port().value());
-		flowEntryObj.setActionOutputPort(fa.actionOutput().port().value());
+			dbHandler.searchPort(flowEntry.dpid().toString(),
+				fa.actionOutput().port().value());
+		if (measureONOSFlowEntryTimeProp) {
+		    endSearchOutPort = System.nanoTime();
+		}
+
+		flowProp.setActionOutputPort(fa.actionOutput().port().value());
+		if (measureONOSFlowEntryTimeProp) {
+		    ++numProperties;
+		}
+
+		if (measureONOSFlowEntryTimeProp) {
+		    startAddEdgeToOutPort = System.nanoTime();
+		}
 		flowEntryObj.setOutPort(outport);
+		if (measureONOSFlowEntryTimeProp) {
+		    endAddEdgeToOutPort = System.nanoTime();
+		}
 	    }
 	}
 	if (! flowEntry.flowEntryActions().isEmpty()) {
-	    flowEntryObj.setActions(flowEntry.flowEntryActions().toString());
+		flowProp.setActions(flowEntry.flowEntryActions().toString());
+	    if (measureONOSFlowEntryTimeProp) {
+		++numProperties;
+	    }
 	}
 
-	flowEntryObj.setUserState(flowEntry.flowEntryUserState().toString());
-	flowEntryObj.setSwitchState(flowEntry.flowEntrySwitchState().toString());
+	flowProp.setUserState(flowEntry.flowEntryUserState().toString());
+	flowProp.setSwitchState(flowEntry.flowEntrySwitchState().toString());
+	if (measureONOSFlowEntryTimeProp) {
+	    numProperties += 2;
+	}
+	flowProp.commitProperties(dbHandler, flowEntryObj);
 	//
 	// TODO: Take care of the FlowEntryErrorState.
 	//
+	if (measureONOSFlowEntryTimeProp) {
+	    endSetProperties = System.nanoTime();
+	}
 
 	// Flow Entries edges:
 	//   Flow
 	//   NextFE (TODO)
 	if (! found) {
-	    flowObj.addFlowEntry(flowEntryObj);
+	    if (measureONOSFlowEntryTimeProp) {
+		startAddEdgeBetweenFlowPath = System.nanoTime();
+	    }
+	    //flowObj.addFlowEntry(flowEntryObj);
 	    flowEntryObj.setFlow(flowObj);
+	    if (measureONOSFlowEntryTimeProp) {
+		endAddEdgeBetweenFlowPath = System.nanoTime();
+	    }
+	}
+	if (measureONOSFlowEntryTimeProp) {
+	    endAddFlowEntry = System.nanoTime();
+
+	    log.error("Performance addFlowEntry(_,{},{}) -- "
+		    + "GrandTotal: {} "
+		    + "SearchExistingFE: {} "
+		    + "CreateNewFE: {} "
+		    + "SetProp+Edge: {} #Props: {} "
+		    + "SearchSwitch: {} "
+		    + "AddEdgeToSwitch: {} "
+		    + "SearchInPort: {} "
+		    + "AddEdgeToInPort: {} "
+		    + "SearchOutPort: {} "
+		    + "AddEdgeToOutPort: {} "
+		    + "AddEdgeBetweenFlowPath: {} "
+		    , flowEntry.flowId(), flowEntry.flowEntryId()
+		    , endAddFlowEntry - startAddFlowEntry
+		    , endSearchFlowEntry - startAddFlowEntry
+		    , endCreateNewFlowEntry - startCreateNewFlowEntry
+		    , endSetProperties - startSetProperties, numProperties
+		    , endSearchSwitch - startSearchSwitch
+		    , endAddEdgeToSwitch - startAddEdgeToSwitch
+		    , endSearchInPort - startSearchInPort
+		    , endAddEdgeToInPort - startAddEdgeToInPort
+		    , endSearchOutPort - startSearchOutPort
+		    , endAddEdgeToOutPort - startAddEdgeToOutPort
+		    , endAddEdgeBetweenFlowPath - startAddEdgeBetweenFlowPath
+		    );
 	}
 
 	return flowEntryObj;
@@ -335,7 +634,7 @@
      * @param flowEntry the Flow Entry to delete.
      * @return true on success, otherwise false.
      */
-    static boolean deleteFlowEntry(GraphDBOperation dbHandler,
+    static boolean deleteFlowEntry(DBOperation dbHandler,
 				   IFlowPath flowObj,
 				   FlowEntry flowEntry) {
 	IFlowEntry flowEntryObj = null;
@@ -371,25 +670,15 @@
      * @param dbHandler the Graph Database handler to use.
      * @return true on success, otherwise false.
      */
-    static boolean deleteAllFlows(GraphDBOperation dbHandler) {
-	List<FlowId> allFlowIds = new LinkedList<FlowId>();
-
-	// Get all Flow IDs
+    static boolean deleteAllFlows(DBOperation dbHandler) {
 	Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
 	for (IFlowPath flowPathObj : allFlowPaths) {
 	    if (flowPathObj == null)
 		continue;
-	    String flowIdStr = flowPathObj.getFlowId();
-	    if (flowIdStr == null)
-		continue;
-	    FlowId flowId = new FlowId(flowIdStr);
-	    allFlowIds.add(flowId);
-	}
 
-	// Delete all flows one-by-one
-	for (FlowId flowId : allFlowIds) {
-	    deleteFlow(dbHandler, flowId);
+	    deleteIFlowPath(dbHandler, flowPathObj);
 	}
+	dbHandler.commit();
 
 	return true;
     }
@@ -401,7 +690,7 @@
      * @param flowId the Flow ID of the flow to delete.
      * @return true on success, otherwise false.
      */
-    static boolean deleteFlow(GraphDBOperation dbHandler, FlowId flowId) {
+    static boolean deleteFlow(DBOperation dbHandler, FlowId flowId) {
 	IFlowPath flowObj = null;
 	try {
 	    flowObj = dbHandler.searchFlowPath(flowId);
@@ -416,6 +705,18 @@
 	    return true;		// OK: No such flow
 	}
 
+	deleteIFlowPath(dbHandler, flowObj);
+	dbHandler.commit();
+	return true;
+    }
+
+    /**
+     * Delete a previously added flow.
+     * @note You need to call commit after calling this method.
+     * @param dbHandler the Graph Database handler to use.
+     * @param flowObj IFlowPath object to delete.
+     */
+    private static void deleteIFlowPath(DBOperation dbHandler, IFlowPath flowObj) {
 	//
 	// Remove all Flow Entries
 	//
@@ -426,9 +727,6 @@
 	}
 	// Remove the Flow itself
 	dbHandler.removeFlowPath(flowObj);
-	dbHandler.commit();
-
-	return true;
     }
 
     /**
@@ -438,7 +736,7 @@
      * @param flowId the Flow ID of the flow to get.
      * @return the Flow Path if found, otherwise null.
      */
-    static FlowPath getFlow(GraphDBOperation dbHandler, FlowId flowId) {
+    static FlowPath getFlow(DBOperation dbHandler, FlowId flowId) {
 	IFlowPath flowObj = null;
 	try {
 	    flowObj = dbHandler.searchFlowPath(flowId);
@@ -469,7 +767,7 @@
      * @param flowEntryId the Flow Entry ID of the flow entry to get.
      * @return the Flow Entry if found, otherwise null.
      */
-    static FlowEntry getFlowEntry(GraphDBOperation dbHandler,
+    static FlowEntry getFlowEntry(DBOperation dbHandler,
 				  FlowEntryId flowEntryId) {
 	IFlowEntry flowEntryObj = null;
 	try {
@@ -501,7 +799,7 @@
      * @param flowId the Flow ID of the flow to get.
      * @return the source switch DPID if found, otherwise null.
      */
-    static Dpid getFlowSourceDpid(GraphDBOperation dbHandler, FlowId flowId) {
+    static Dpid getFlowSourceDpid(DBOperation dbHandler, FlowId flowId) {
 	IFlowPath flowObj = null;
 	try {
 	    flowObj = dbHandler.searchFlowPath(flowId);
@@ -539,7 +837,7 @@
      * @param dbHandler the Graph Database handler to use.
      * @return the Flow Paths if found, otherwise null.
      */
-    static ArrayList<FlowPath> getAllFlows(GraphDBOperation dbHandler) {
+    static ArrayList<FlowPath> getAllFlows(DBOperation dbHandler) {
 	Iterable<IFlowPath> flowPathsObj = null;
 	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
 
@@ -579,7 +877,7 @@
      * instance.
      * @return the Flow Paths if found, otherwise null.
      */
-    static ArrayList<FlowPath> getAllMyFlows(GraphDBOperation dbHandler,
+    static ArrayList<FlowPath> getAllMyFlows(DBOperation dbHandler,
 					     Map<Long, IOFSwitch> mySwitches) {
 	Iterable<IFlowPath> flowPathsObj = null;
 	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
@@ -631,7 +929,7 @@
      * @param flowIds the collection of Flow IDs to get.
      * @return the Flow Paths if found, otherwise null.
      */
-    static ArrayList<FlowPath> getFlows(GraphDBOperation dbHandler,
+    static ArrayList<FlowPath> getFlows(DBOperation dbHandler,
 					Collection<FlowId> flowIds) {
 	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
 
@@ -656,17 +954,47 @@
 	//
 	// Extract the Flow state
 	//
-	String flowIdStr = flowObj.getFlowId();
-	String installerIdStr = flowObj.getInstallerId();
-	String flowPathType = flowObj.getFlowPathType();
-	String flowPathUserState = flowObj.getFlowPathUserState();
-	Long flowPathFlags = flowObj.getFlowPathFlags();
-	Integer idleTimeout = flowObj.getIdleTimeout();
-	Integer hardTimeout = flowObj.getHardTimeout();
-	String srcSwitchStr = flowObj.getSrcSwitch();
-	Short srcPortShort = flowObj.getSrcPort();
-	String dstSwitchStr = flowObj.getDstSwitch();
-	Short dstPortShort = flowObj.getDstPort();
+    log.info("extractFlowPath: start");
+	String flowIdStr;
+	String installerIdStr;
+	String flowPathType;
+	String flowPathUserState;
+	Long flowPathFlags;
+	Integer idleTimeout;
+	Integer hardTimeout;
+	String srcSwitchStr;
+	Short srcPortShort;
+	String dstSwitchStr;
+	Short dstPortShort;
+
+	if ( flowObj.asVertex() instanceof RamCloudVertex ) {
+	    RamCloudVertex v = (RamCloudVertex)flowObj.asVertex();
+	    Map<String,Object> propMap = v.getProperties();
+
+	    flowIdStr = (String) propMap.get("flow_id");
+	    installerIdStr = (String) propMap.get("installer_id");
+	    flowPathType = (String) propMap.get("flow_path_type");
+	    flowPathUserState = (String) propMap.get("user_state");
+	    flowPathFlags = (Long)propMap.get("flow_path_flags");
+	    idleTimeout = (Integer) propMap.get("idle_timeout");
+	    hardTimeout = (Integer) propMap.get("hard_timeout");
+	    srcSwitchStr = (String) propMap.get("src_switch");
+	    srcPortShort = (Short)propMap.get("src_port");
+	    dstSwitchStr = (String) propMap.get("dst_switch");
+	    dstPortShort = (Short)propMap.get("dst_port");
+	} else {
+	    flowIdStr = flowObj.getFlowId();
+	    installerIdStr = flowObj.getInstallerId();
+	    flowPathType = flowObj.getFlowPathType();
+	    flowPathUserState = flowObj.getFlowPathUserState();
+	    flowPathFlags = flowObj.getFlowPathFlags();
+	    idleTimeout = flowObj.getIdleTimeout();
+	    hardTimeout = flowObj.getHardTimeout();
+	    srcSwitchStr = flowObj.getSrcSwitch();
+	    srcPortShort = flowObj.getSrcPort();
+	    dstSwitchStr = flowObj.getDstSwitch();
+	    dstPortShort = flowObj.getDstPort();
+	}
 
 	if ((flowIdStr == null) ||
 	    (installerIdStr == null) ||
@@ -679,7 +1007,8 @@
 	    (srcPortShort == null) ||
 	    (dstSwitchStr == null) ||
 	    (dstPortShort == null)) {
-	    // TODO: A work-around, becauuse of some bogus database objects
+	    // TODO: A work-around, because of some bogus database objects
+	    log.error("extractFlowPath: wrong properties");
 	    return null;
 	}
 
@@ -699,40 +1028,7 @@
 	// Extract the match conditions common for all Flow Entries
 	//
 	{
-	    FlowEntryMatch match = new FlowEntryMatch();
-	    String matchSrcMac = flowObj.getMatchSrcMac();
-	    if (matchSrcMac != null)
-		match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
-	    String matchDstMac = flowObj.getMatchDstMac();
-	    if (matchDstMac != null)
-		match.enableDstMac(MACAddress.valueOf(matchDstMac));
-	    Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
-	    if (matchEthernetFrameType != null)
-		match.enableEthernetFrameType(matchEthernetFrameType);
-	    Short matchVlanId = flowObj.getMatchVlanId();
-	    if (matchVlanId != null)
-		match.enableVlanId(matchVlanId);
-	    Byte matchVlanPriority = flowObj.getMatchVlanPriority();
-	    if (matchVlanPriority != null)
-		match.enableVlanPriority(matchVlanPriority);
-	    String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
-	    if (matchSrcIPv4Net != null)
-		match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
-	    String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
-	    if (matchDstIPv4Net != null)
-		match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
-	    Byte matchIpProto = flowObj.getMatchIpProto();
-	    if (matchIpProto != null)
-		match.enableIpProto(matchIpProto);
-	    Byte matchIpToS = flowObj.getMatchIpToS();
-	    if (matchIpToS != null)
-		match.enableIpToS(matchIpToS);
-	    Short matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
-	    if (matchSrcTcpUdpPort != null)
-		match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
-	    Short matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
-	    if (matchDstTcpUdpPort != null)
-		match.enableDstTcpUdpPort(matchDstTcpUdpPort);
+	    FlowEntryMatch match = extractMatch(flowObj);
 
 	    flowPath.setFlowEntryMatch(match);
 	}
@@ -758,6 +1054,7 @@
 	    flowPath.dataPath().flowEntries().add(flowEntry);
 	}
 
+    log.info("extractFlowPath: end");
 	return flowPath;
     }
 
@@ -768,18 +1065,39 @@
      * @return the extracted Flow Entry State.
      */
     public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
+	log.info("extractFlowEntry: start");
 	IFlowPath flowObj = flowEntryObj.getFlow();
-	if (flowObj == null)
+	if (flowObj == null) {
+		log.error("extractFlowEntry: no flowPath exists");
 	    return null;
+	}
 
 	String flowIdStr = flowObj.getFlowId();
 	//
-	String flowEntryIdStr = flowEntryObj.getFlowEntryId();
-	Integer idleTimeout = flowEntryObj.getIdleTimeout();
-	Integer hardTimeout = flowEntryObj.getHardTimeout();
-	String switchDpidStr = flowEntryObj.getSwitchDpid();
-	String userState = flowEntryObj.getUserState();
-	String switchState = flowEntryObj.getSwitchState();
+	String flowEntryIdStr;
+	Integer idleTimeout;
+	Integer hardTimeout;
+	String switchDpidStr;
+	String userState;
+	String switchState;
+	if ( flowEntryObj.asVertex() instanceof RamCloudVertex ) {
+	    RamCloudVertex v = (RamCloudVertex)flowEntryObj.asVertex();
+	    Map<String,Object> propMap = v.getProperties();
+
+	    flowEntryIdStr = (String) propMap.get("flow_entry_id");
+	    idleTimeout = (Integer) propMap.get("idle_timeout");
+	    hardTimeout = (Integer) propMap.get("hard_timeout");
+	    switchDpidStr = (String) propMap.get("switch_dpid");
+	    userState = (String) propMap.get("user_state");
+	    switchState = (String) propMap.get("switch_state");
+	} else {
+	    flowEntryIdStr = flowEntryObj.getFlowEntryId();
+	    idleTimeout = flowEntryObj.getIdleTimeout();
+	    hardTimeout = flowEntryObj.getHardTimeout();
+	    switchDpidStr = flowEntryObj.getSwitchDpid();
+	    userState = flowEntryObj.getUserState();
+	    switchState = flowEntryObj.getSwitchState();
+	}
 
 	if ((flowIdStr == null) ||
 	    (flowEntryIdStr == null) ||
@@ -789,6 +1107,7 @@
 	    (userState == null) ||
 	    (switchState == null)) {
 	    // TODO: A work-around, because of some bogus database objects
+		log.error("extractFlowEntry: wrong properties");
 	    return null;
 	}
 
@@ -802,43 +1121,7 @@
 	//
 	// Extract the match conditions
 	//
-	FlowEntryMatch match = new FlowEntryMatch();
-	Short matchInPort = flowEntryObj.getMatchInPort();
-	if (matchInPort != null)
-	    match.enableInPort(new Port(matchInPort));
-	String matchSrcMac = flowEntryObj.getMatchSrcMac();
-	if (matchSrcMac != null)
-	    match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
-	String matchDstMac = flowEntryObj.getMatchDstMac();
-	if (matchDstMac != null)
-	    match.enableDstMac(MACAddress.valueOf(matchDstMac));
-	Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
-	if (matchEthernetFrameType != null)
-	    match.enableEthernetFrameType(matchEthernetFrameType);
-	Short matchVlanId = flowEntryObj.getMatchVlanId();
-	if (matchVlanId != null)
-	    match.enableVlanId(matchVlanId);
-	Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
-	if (matchVlanPriority != null)
-	    match.enableVlanPriority(matchVlanPriority);
-	String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
-	if (matchSrcIPv4Net != null)
-	    match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
-	String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
-	if (matchDstIPv4Net != null)
-	    match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
-	Byte matchIpProto = flowEntryObj.getMatchIpProto();
-	if (matchIpProto != null)
-	    match.enableIpProto(matchIpProto);
-	Byte matchIpToS = flowEntryObj.getMatchIpToS();
-	if (matchIpToS != null)
-	    match.enableIpToS(matchIpToS);
-	Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
-	if (matchSrcTcpUdpPort != null)
-	    match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
-	Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
-	if (matchDstTcpUdpPort != null)
-	    match.enableDstTcpUdpPort(matchDstTcpUdpPort);
+	FlowEntryMatch match = extractMatch(flowEntryObj);
 	flowEntry.setFlowEntryMatch(match);
 
 	//
@@ -854,6 +1137,101 @@
 	//
 	// TODO: Take care of FlowEntryErrorState.
 	//
+	log.info("extractFlowEntry: end");
 	return flowEntry;
     }
+
+    /**
+     * Extract FlowEntryMatch from IFlowPath or IFlowEntry
+     * @param flowObj : either IFlowPath or IFlowEntry
+     * @return extracted Match info
+     */
+    private static FlowEntryMatch extractMatch(IBaseObject flowObj) {
+	FlowEntryMatch match = new FlowEntryMatch();
+
+	Short matchInPort = null; // Only for IFlowEntry
+	String matchSrcMac = null;
+	String matchDstMac = null;
+	Short matchEthernetFrameType = null;
+	Short matchVlanId = null;
+	Byte matchVlanPriority = null;
+	String matchSrcIPv4Net = null;
+	String matchDstIPv4Net = null;
+	Byte matchIpProto = null;
+	Byte matchIpToS = null;
+	Short matchSrcTcpUdpPort = null;
+	Short matchDstTcpUdpPort = null;
+
+	if ( flowObj.asVertex() instanceof RamCloudVertex ) {
+	    RamCloudVertex v = (RamCloudVertex)flowObj.asVertex();
+	    Map<String,Object> propMap = v.getProperties();
+	    matchInPort = (Short) propMap.get("matchInPort");
+	    matchSrcMac = (String) propMap.get("matchSrcMac");
+	    matchDstMac = (String) propMap.get("matchDstMac");
+	    matchEthernetFrameType = (Short) propMap.get("matchEthernetFrameType");
+	    matchVlanId = (Short) propMap.get("matchVlanId");
+	    matchVlanPriority = (Byte) propMap.get("matchVlanPriority");
+	    matchSrcIPv4Net = (String) propMap.get("matchSrcIPv4Net");
+	    matchDstIPv4Net = (String) propMap.get("matchDstIPv4Net");
+	    matchIpProto = (Byte) propMap.get("matchIpProto");
+	    matchIpToS = (Byte) propMap.get("matchIpToS");
+	    matchSrcTcpUdpPort = (Short) propMap.get("matchSrcTcpUdpPort");
+	    matchDstTcpUdpPort = (Short) propMap.get("matchDstTcpUdpPort");
+	} else {
+	    if (flowObj instanceof IFlowEntry ){
+		IFlowEntry flowEntry = (IFlowEntry) flowObj;
+		matchInPort = flowEntry.getMatchInPort();
+		matchSrcMac = flowEntry.getMatchSrcMac();
+		matchDstMac = flowEntry.getMatchDstMac();
+		matchEthernetFrameType = flowEntry.getMatchEthernetFrameType();
+		matchVlanId = flowEntry.getMatchVlanId();
+		matchVlanPriority = flowEntry.getMatchVlanPriority();
+		matchSrcIPv4Net = flowEntry.getMatchSrcIPv4Net();
+		matchDstIPv4Net = flowEntry.getMatchDstIPv4Net();
+		matchIpProto = flowEntry.getMatchIpProto();
+		matchIpToS = flowEntry.getMatchIpToS();
+		matchSrcTcpUdpPort = flowEntry.getMatchSrcTcpUdpPort();
+		matchDstTcpUdpPort = flowEntry.getMatchDstTcpUdpPort();
+	    } else if(flowObj instanceof IFlowPath) {
+		IFlowPath flowPath = (IFlowPath) flowObj;
+		matchSrcMac = flowPath.getMatchSrcMac();
+		matchDstMac = flowPath.getMatchDstMac();
+		matchEthernetFrameType = flowPath.getMatchEthernetFrameType();
+		matchVlanId = flowPath.getMatchVlanId();
+		matchVlanPriority = flowPath.getMatchVlanPriority();
+		matchSrcIPv4Net = flowPath.getMatchSrcIPv4Net();
+		matchDstIPv4Net = flowPath.getMatchDstIPv4Net();
+		matchIpProto = flowPath.getMatchIpProto();
+		matchIpToS = flowPath.getMatchIpToS();
+		matchSrcTcpUdpPort = flowPath.getMatchSrcTcpUdpPort();
+		matchDstTcpUdpPort = flowPath.getMatchDstTcpUdpPort();
+	    }
+	}
+
+	if (matchInPort != null)
+	    match.enableInPort(new Port(matchInPort));
+	if (matchSrcMac != null)
+	    match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
+	if (matchDstMac != null)
+	    match.enableDstMac(MACAddress.valueOf(matchDstMac));
+	if (matchEthernetFrameType != null)
+	    match.enableEthernetFrameType(matchEthernetFrameType);
+	if (matchVlanId != null)
+	    match.enableVlanId(matchVlanId);
+	if (matchVlanPriority != null)
+	    match.enableVlanPriority(matchVlanPriority);
+	if (matchSrcIPv4Net != null)
+	    match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
+	if (matchDstIPv4Net != null)
+	    match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
+	if (matchIpProto != null)
+	    match.enableIpProto(matchIpProto);
+	if (matchIpToS != null)
+	    match.enableIpToS(matchIpToS);
+	if (matchSrcTcpUdpPort != null)
+	    match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
+	if (matchDstTcpUdpPort != null)
+	    match.enableDstTcpUdpPort(matchDstTcpUdpPort);
+	return match;
+    }
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEntity.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEntity.java
new file mode 100644
index 0000000..ff890b6
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEntity.java
@@ -0,0 +1,252 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.ofcontroller.flowmanager;
+
+import com.tinkerpop.blueprints.Direction;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.Edge;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IBaseObject;
+import com.tinkerpop.blueprints.impls.ramcloud.RamCloudGraph;
+import com.tinkerpop.blueprints.impls.ramcloud.RamCloudVertex;
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public class FlowEntity implements FlowEntityManager {
+    private String primaryKey;
+    // TODO: Should remove since not implemented.
+    private Class<?> hasMany;
+    private Collection<?> many = new ArrayList<>();
+    private Map<String, Object> properties;
+    private Map<String, Map<String, Object>> operations = new HashMap<>();
+    private ArrayList<Object> children = new ArrayList<>();
+    private ArrayList<Object> edges = new ArrayList<>();
+    private int opCount;
+    public Direction dir;
+
+    public FlowEntity() {
+        opCount = 0;
+    }
+    
+    private class EntityEdge {
+        private Object src;
+        private Object dst;
+        private Direction dir;
+        private String label;
+        private DBOperationType op;
+        
+        public EntityEdge(Object src, Object dst, DBOperationType op, Direction dir, String label) {
+            this.src = src;
+            this.dst = dst;
+            this.dir = dir;
+            this.label = label;
+            this.op = op;
+        }
+        
+        public EntityEdge(Object src, Object dst, String label) {
+            this.src = src;
+            this.dst = dst;
+            this.label = label;
+        }
+        
+        @Override
+        public String toString() {
+            return "EntityEdge: " + src + " " + dst + " " + label;
+        }
+    }
+
+    private class RamCloudEdgeEntity implements Edge {
+        private Vertex src;
+        private Vertex dst;
+        private Direction direction;
+        private String label;
+
+        public RamCloudEdgeEntity(Vertex src, Vertex dst, Direction direction, String label) {
+            this.src = src;
+            this.dst = dst;
+            this.direction = direction;
+            this.label = label;
+        }
+        
+        @Override
+        public Vertex getVertex(com.tinkerpop.blueprints.Direction dir) throws IllegalArgumentException {
+            if (dir == Direction.IN) {
+                return dst;
+            } else if (dir == Direction.OUT) {
+                return src;
+            }
+            return null;
+        }
+
+        @Override
+        public String getLabel() {
+            return this.label;
+        }
+
+        @Override
+        public <T> T getProperty(String key) {
+            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+        }
+
+        @Override
+        public Set<String> getPropertyKeys() {
+            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+        }
+
+        @Override
+        public void setProperty(String key, Object value) {
+            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+        }
+
+        @Override
+        public <T> T removeProperty(String key) {
+            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+        }
+
+        @Override
+        public Object getId() {
+            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+        }
+        
+    }
+    
+    @Override
+    public void setPrimaryKey(String key) {
+        primaryKey = key;
+    }
+    
+    @Override
+    public String getPrimaryKey() {
+        return primaryKey;
+    }
+
+    @Override
+    public void hasMany(Class<?> cClass) {
+        hasMany = cClass;
+    }
+    
+    @Override
+    public void operationBegin(String opName) {
+        properties = new HashMap<>();
+        operations.put(getOpKey(opName), properties);
+        opCount++;
+    }
+    
+    @Override
+    public void operationEnd(String opName) {
+        // TODO: This method is implemented in case we need to reset any variables.
+        /*
+        String opKey = getOpKey(opName);
+        if (operations.containsKey(opKey)) {
+            System.out.println(operations);
+        }
+        */
+    }
+    
+    
+    private String getOpKey(String opName) {
+        return opName + new Integer(opCount).toString();
+        
+    }
+
+    @Override
+    public void setProperty(String propertyName, Object value) {
+        properties.put(propertyName, value);
+    }
+
+    @Override
+    public FlowEntityManager append(Object entity) {
+        children.add(entity);
+        return this;
+    }
+    
+    @Override
+    public Object getProperty(String propertyName) {
+        if (properties.containsKey(propertyName)) {
+            return properties.get(propertyName);
+        }
+        return null;
+    }
+    
+    @Override
+    public void persist(DBOperation dbHandler) {
+        // get a hold of all the flow entries for the current flowpath.
+        if (children.size() > 0) {
+            int noOfChildren = children.size();
+            if (noOfChildren > 0) {
+                // construct a list of null ids for creating vertices for all
+                // flow entries.
+                ArrayList<Object> ids = new ArrayList<>(noOfChildren);
+                // set properties
+                Map<RamCloudVertex, Map<String, Object>> propertiesToSet = new HashMap<>();
+                
+                RamCloudGraph graph = (RamCloudGraph)dbHandler.getDBConnection().getFramedGraph().getBaseGraph();
+                for (int i = 0; i < noOfChildren; i++) {
+                    ids.add(null);
+                }
+                List<RamCloudVertex> addedVertices = graph.addVertices(ids);
+                //Iterable<Vertex> vertices = dbHandler.setVertices(ids);
+                //Iterator vi = vertices.iterator();
+                // get source and destination edge match vertex v construct list
+                // of edges
+                ArrayList<Edge> edgesToSet = new ArrayList<>();
+                for (int i = 0; i < noOfChildren; i++) {
+                    FlowEntity childEntity = (FlowEntity)children.get(i);
+                    Vertex srcVertex = addedVertices.get(i);                    
+                    propertiesToSet.put((RamCloudVertex)srcVertex, childEntity.properties);
+
+                    if (srcVertex == null) continue;
+                    for (int j = 0; j < childEntity.edges.size(); j++) {
+                        EntityEdge edge = (EntityEdge) childEntity.edges.get(j);
+                        edgesToSet.add(new RamCloudEdgeEntity(srcVertex, ((IBaseObject) edge.dst).asVertex(), edge.dir, edge.label));
+                    }
+                }
+                graph.addEdges(edgesToSet);
+                graph.setProperties(propertiesToSet);
+            }
+        }
+    }
+
+    private Vertex getVertexEdge(Iterator vi, int idx) {
+        int i = 0;
+        while (vi.hasNext()) {
+            Vertex v = (Vertex)vi.next();
+            if (i == idx) {
+                return v;
+            }
+            i++;
+        }
+        return null;
+    }
+    
+    @Override
+    public Map<String, Object> getProperties() {
+        return properties;
+    }
+    
+    @Override
+    public void addEdge(Object dst, Direction dir, String label) {
+        edges.add(new EntityEdge(this, dst, DBOperationType.ADD, dir, label));
+    }
+    
+    @Override
+    public void removeEdge(Object src, Object dst, Direction dir, String label) {
+        edges.add(new EntityEdge(src, dst, DBOperationType.REMOVE, dir, label));
+    }
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEntityManager.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEntityManager.java
new file mode 100644
index 0000000..38e694b
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEntityManager.java
@@ -0,0 +1,29 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.ofcontroller.flowmanager;
+
+import com.tinkerpop.blueprints.Direction;
+import java.util.Map;
+import net.onrc.onos.graph.DBOperation;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public interface FlowEntityManager {
+    public void setPrimaryKey(String key);
+    public String getPrimaryKey();
+    public void hasMany(Class<?> cClass);
+    public void operationBegin(String opName);
+    public void operationEnd(String opName);
+    public void setProperty(String propertyName, Object value);
+    public Object getProperty(String propertyName);
+    public Map<String, Object> getProperties();
+    public FlowEntityManager append(Object entity);
+    public void addEdge(Object dst, Direction dir, String label);
+    public void removeEdge(Object src, Object dst, Direction dir, String label);
+    public void persist(DBOperation dbHandler);
+}
+
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEntryProperty.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEntryProperty.java
new file mode 100644
index 0000000..b45f8ff
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEntryProperty.java
@@ -0,0 +1,143 @@
+package net.onrc.onos.ofcontroller.flowmanager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+
+public class FlowEntryProperty {
+    private Map<String, Object> map = new HashMap<>();
+    
+    public void setFlowId(String value) {
+        map.put("flow_id", value);
+    }
+    
+    public void setUserState(String value) {
+        map.put("user_state", value);
+    }
+    
+    public void setFlowEntryId(String value) {
+        map.put("flow_entry_id", value);
+    }
+    
+    public void setType(String value) {
+        map.put("type", value);
+    }
+    
+    public void setInstallerId(String value) {
+        map.put("installer_id", value);
+    }
+    
+    public void setFlowPathType(String value) {
+        map.put("flow_path_type", value);
+    }
+    
+    public void setFlowPathUserState(String value) {
+        map.put("user_state", value);
+    }
+    
+    public void flow_path_flags(Long value) {
+        map.put("flow_path_flags", value);
+    }
+    
+    public void setIdleTimeout(Integer value) {
+        map.put("idle_timeout", value);
+    }
+    
+    public void setHardTimeout(Integer value) {
+        map.put("hard_timeout", value);
+    }
+    
+    public void setSwitchDpid(String value) {
+        map.put("switch_dpid", value);
+    }
+    
+    public void setSwitchState(String value) {
+        map.put("switch_state", value);
+    }
+    
+    public void setSrcSwitch(String value) {
+        map.put("src_switch", value);
+    }
+    
+    public void setSrcPort(Short value) {
+        map.put("src_port", value);
+    }
+    
+    public void setDstSwitch(String value) {
+        map.put("dst_switch", value);
+    }
+    
+    public void setDstPort(Short value) {
+        map.put("dst_port", value);
+    }
+    
+    public void setMatchSrcMac(String value) {
+        map.put("matchSrcMac", value);
+    }
+    
+    public void setMatchDstMac(String value) {
+        map.put("matchDstMac", value);
+    }
+    
+    public void setMatchEthernetFrameType(Short value) {
+        map.put("matchEthernetFrameType", value);
+    }
+    
+    public void setMatchVlanId(Short value) {
+        map.put("matchVlanId", value);
+    }
+    
+    public void setMatchVlanPriority(Byte value) {
+        map.put("matchVlanPriority", value);
+    }
+    
+    public void setMatchSrcIPv4Net(String value) {
+        map.put("matchSrcIPv4Net", value);
+    }
+    
+    public void setMatchDstIPv4Net(String value) {
+        map.put("matchDstIPv4Net", value);
+    }
+    
+    public void setMatchIpProto(Byte value) {
+        map.put("matchIpProto", value);
+    }
+    
+    public void setMatchIpToS(Byte value) {
+        map.put("matchIpToS", value);
+    }
+    
+    public void setMatchInPort(Short value) {
+        map.put("matchInPort", value);
+    }
+    
+    public void setMatchSrcTcpUdpPort(Short value) {
+        map.put("matchSrcTcpUdpPort", value);
+    }
+    
+    public void setMatchDstTcpUdpPort(Short value) {
+        map.put("matchDstTcpUdpPort", value);
+    }
+    
+    public void setActions(String value) {
+        map.put("actions", value);
+    }
+    
+    public void setActionOutputPort(Short value) {
+        map.put("actionOutputPort", value);
+    }
+    
+    public void setDataPathSummary(String value) {
+        map.put("data_path_summary", value);
+    }
+    
+    /**
+     *
+     * @param dbhandler
+     */
+    public void commitProperties(DBOperation dbhandler, IFlowEntry flowEntry) {
+        dbhandler.setVertexProperties(flowEntry.asVertex(), map);
+    }
+}
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 662e81b..1705569 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
@@ -8,15 +8,17 @@
 import java.util.List;
 import java.util.Map;
 import java.util.SortedMap;
+import java.util.Timer;
+import java.util.TimerTask;
 import java.util.TreeMap;
 import java.util.concurrent.BlockingQueue;
 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.GraphDBOperation;
+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;
@@ -37,7 +39,8 @@
 import net.onrc.onos.ofcontroller.util.Port;
 import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
 
-import com.esotericsoftware.kryo2.Kryo;
+import com.esotericsoftware.kryo.Kryo;
+import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -58,7 +61,7 @@
     /** The logger. */
     private final static Logger log = LoggerFactory.getLogger(FlowEventHandler.class);
 
-    private GraphDBOperation dbHandler;
+    private DBOperation dbHandler;
 
     private FlowManager flowManager;		// The Flow Manager to use
     private IDatagridService datagridService;	// The Datagrid Service to use
@@ -127,7 +130,7 @@
      * Startup processing.
      */
     private void startup() {
-	this.dbHandler = new GraphDBOperation("");
+	this.dbHandler = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloudconf");
 
 	//
 	// Obtain the initial Topology state
@@ -184,6 +187,7 @@
 	synchronized (allFlowPaths) {
 	    processEvents();
 	}
+
     }
 
     /**
@@ -471,6 +475,10 @@
 
 	for (FlowPath flowPath : flowPaths) {
 	    boolean isInstalled = true;
+	    
+	    if (flowPath.flowEntries().isEmpty()) {
+	    	continue;
+	    }
 
 	    //
 	    // Check whether all Flow Entries have been installed
@@ -900,10 +908,14 @@
 
 	    switch (eventEntry.eventType()) {
 	    case ENTRY_ADD:
-		isTopologyModified |= topology.addTopologyElement(topologyElement);
+    	synchronized (topology) {
+    		isTopologyModified |= topology.addTopologyElement(topologyElement);
+    	}
 		break;
 	    case ENTRY_REMOVE:
-		isTopologyModified |= topology.removeTopologyElement(topologyElement);
+    	synchronized (topology) {
+    		isTopologyModified |= topology.removeTopologyElement(topologyElement);
+    	}
 		break;
 	    }
 	}
@@ -1200,9 +1212,11 @@
 	DataPath oldDataPath = flowPath.dataPath();
 
 	// Compute the new path
-	DataPath newDataPath = TopologyManager.computeNetworkPath(topology,
+	DataPath newDataPath;
+	synchronized (topology) {
+	newDataPath = TopologyManager.computeNetworkPath(topology,
 								  flowPath);
-	
+	}
 	if (newDataPath == null) {
 	    // We need the DataPath to compare the paths
 	    newDataPath = new DataPath();
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 5651f73..de847de 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -19,8 +19,10 @@
 import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.restserver.IRestApiService;
+import net.floodlightcontroller.util.OFMessageDamper;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.datagrid.IDatagridService;
-import net.onrc.onos.graph.GraphDBOperation;
 import net.onrc.onos.ofcontroller.core.INetMapStorage;
 import net.onrc.onos.ofcontroller.floodlightlistener.INetworkGraphService;
 import net.onrc.onos.ofcontroller.flowmanager.web.FlowWebRoutable;
@@ -39,7 +41,8 @@
 import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
 
 import com.thinkaurelius.titan.core.TitanException;
-import com.esotericsoftware.kryo2.Kryo;
+
+import com.esotericsoftware.kryo.Kryo;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -51,8 +54,8 @@
 
     private boolean enableOnrc2014MeasurementsFlows = true;
 
-    protected GraphDBOperation dbHandlerApi;
-    protected GraphDBOperation dbHandlerInner;
+    protected DBOperation dbHandlerApi;
+    protected DBOperation dbHandlerInner;
 
     protected volatile IFloodlightProviderService floodlightProvider;
     protected volatile IDatagridService datagridService;
@@ -84,9 +87,9 @@
      * @param conf the Graph Database configuration string.
      */
     @Override
-    public void init(String conf) {
-    	dbHandlerApi = new GraphDBOperation(conf);
-    	dbHandlerInner = new GraphDBOperation(conf);
+    public void init(final String dbStore, final String conf) {
+	dbHandlerApi = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloud.conf");
+	dbHandlerInner = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloud.conf");
     }
 
     /**
@@ -176,7 +179,7 @@
 	pusher = context.getServiceImpl(IFlowPusherService.class);
 	forwardingService = context.getServiceImpl(IForwardingService.class);
 
-	this.init("");
+	this.init("","");
     }
 
     /**
@@ -471,6 +474,11 @@
 	if (srcDpid.value() != sw.getId())
 	    return;
 	deleteFlow(flowPath.flowId());
+	
+	// Send flow deleted notification to the Forwarding module
+	// TODO This is a quick fix for flow-removed notifications. We
+	// should think more about the design of these notifications.
+	notificationFlowPathRemoved(flowPath);
     }
 
     /**
@@ -543,6 +551,20 @@
     }
 
     /**
+     * Generate a notification that a FlowPath has been removed from the 
+     * network. This means we've received an expiry message for the flow
+     * from the switch, and send flowmods to remove any remaining parts of
+     * the path.
+     * 
+     * @param flowPath FlowPath object that was removed from the network.
+     */
+    void notificationFlowPathRemoved(FlowPath flowPath) {
+	if (forwardingService != null) {
+		forwardingService.flowRemoved(flowPath);
+	}
+    }
+
+    /**
      * Push modified Flow-related state as appropriate.
      *
      * @param modifiedFlowPaths the collection of modified Flow Paths.
@@ -828,15 +850,25 @@
 	    do {
 		retry = false;
 		try {
+                    long startTime = System.nanoTime();
 		    if (! FlowDatabaseOperation.addFlow(dbHandlerInner, flowPath)) {
 			log.error("Cannot write to Network Map Flow Path {}", flowPath.flowId());
 			retry = true;
 		    }
+ 		    // FIXME Flag to turn ON logging
+                    //long endTime = System.nanoTime();
+                    //log.error("Performance %% Flow path total time {} : {}", endTime - startTime, flowPath.toString());
 		} catch (TitanException te) {
 		    log.error("Titan Exception writing Flow Path to Network MAP: ", te);
 		    retry = true;
+ 		    // FIXME Flag to turn ON logging
+                    //long endTime = System.nanoTime();
+                    //log.error("Performance %% Flow path total time {} : {}", endTime - startTime, flowPath.toString());
 		} catch (Exception e) {
 		    log.error("Exception writing Flow Path to Network MAP: ", e);
+ 		    // FIXME Flag to turn ON logging
+                    //long endTime = System.nanoTime();
+                    //log.error("Performance %% Flow path total time {} : {}", endTime - startTime, flowPath.toString());
 		}
 	    } while (retry);
 
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowPathProperty.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowPathProperty.java
new file mode 100644
index 0000000..21db7bc
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowPathProperty.java
@@ -0,0 +1,119 @@
+package net.onrc.onos.ofcontroller.flowmanager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+
+public class FlowPathProperty {
+	private Map<String, Object> map = new HashMap<>();
+
+	public void setType(String typeStr) {
+		map.put("type", typeStr);
+	}
+
+	public void setFlowId(String flowId) {
+		map.put("flow_id", flowId);
+	}
+
+	public void setInstallerId(String installerId) {
+		map.put("installer_id", installerId);
+	}
+
+	public void setFlowPathType(String flowPathType) {
+		map.put("flow_path_type", flowPathType);
+	}
+
+	public void setFlowPathUserState(String userState) {
+		map.put("user_state", userState);
+	}
+
+	public void setFlowPathFlags(Long flowPathFlags) {
+		map.put("flow_path_flags", flowPathFlags);
+	}
+
+	public void setIdleTimeout(Integer idleTimeout) {
+		map.put("idle_timeout", idleTimeout);
+	}
+
+	public void setHardTimeout(Integer hardTimeout) {
+		map.put("hard_timeout", hardTimeout);
+	}
+
+	public void setSrcSwitch(String srcSwitch) {
+		map.put("src_switch", srcSwitch);
+	}
+
+	public void setSrcPort(Short srcPort) {
+		map.put("src_port", srcPort);
+	}
+
+	public void setDstSwitch(String dstSwitch) {
+		map.put("dst_switch", dstSwitch);
+	}
+
+	public void setDstPort(Short dstPort) {
+		map.put("dst_port", dstPort);
+	}
+
+	public void setDataPathSummary(String dataPathSummary) {
+		map.put("data_path_summary", dataPathSummary);
+	}
+
+	public void setMatchSrcMac(String matchSrcMac) {
+		map.put("matchSrcMac", matchSrcMac);
+	}
+
+	public void setMatchDstMac(String matchDstMac) {
+		map.put("matchDstMac", matchDstMac);
+	}
+
+	public void setMatchEthernetFrameType(Short matchEthernetFrameType) {
+		map.put("matchEthernetFrameType", matchEthernetFrameType);
+	}
+
+	public void setMatchVlanId(Short matchVlanId) {
+		map.put("matchVlanId", matchVlanId);
+	}
+
+	public void setMatchVlanPriority(Byte matchVlanPriority) {
+		map.put("matchVlanPriority", matchVlanPriority);
+	}
+
+	public void setMatchSrcIPv4Net(String matchSrcIPv4Net) {
+		map.put("matchSrcIPv4Net", matchSrcIPv4Net);
+	}
+
+	public void setMatchDstIPv4Net(String matchDstIPv4Net) {
+		map.put("matchDstIPv4Net", matchDstIPv4Net);
+	}
+
+	public void setMatchIpProto(Byte matchIpProto) {
+		map.put("matchIpProto", matchIpProto);
+	}
+
+	public void setMatchIpToS(Byte matchIpToS) {
+		map.put("matchIpToS", matchIpToS);
+	}
+
+	public void setMatchSrcTcpUdpPort(Short matchSrcTcpUdpPort) {
+		map.put("matchSrcTcpUdpPort", matchSrcTcpUdpPort);
+	}
+
+	public void setMatchDstTcpUdpPort(Short matchDstTcpUdpPort) {
+		map.put("matchDstTcpUdpPort", matchDstTcpUdpPort);
+	}
+
+	public void setActions(String actionsStr) {
+		map.put("actions", actionsStr);
+	}
+    
+    /**
+     *
+     * @param dbhandler
+     */
+    public void commitProperties(DBOperation dbhandler, IFlowPath flowPath) {
+        dbhandler.setVertexProperties(flowPath.asVertex() ,map);
+    }
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/ParallelFlowDatabaseOperation.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/ParallelFlowDatabaseOperation.java
index 59a2139..ec03d09 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/ParallelFlowDatabaseOperation.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/ParallelFlowDatabaseOperation.java
@@ -16,7 +16,7 @@
 import org.slf4j.LoggerFactory;
 
 import net.onrc.onos.datagrid.IDatagridService;
-import net.onrc.onos.graph.GraphDBOperation;
+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;
@@ -50,7 +50,7 @@
      * @param dbHandler the Graph Database handler to use.
      * @return the Flow Paths if found, otherwise an empty list.
      */
-    static ArrayList<FlowPath> getAllFlows(GraphDBOperation dbHandler) {
+    static ArrayList<FlowPath> getAllFlows(DBOperation dbHandler) {
 	Iterable<IFlowPath> flowPathsObj = null;
 	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
 
@@ -97,7 +97,7 @@
      * @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(GraphDBOperation dbHandler, Collection<Dpid> switches) {
+    static ArrayList<FlowPath> getFlowsForSwitches(DBOperation dbHandler, Collection<Dpid> switches) {
 	Iterable<IFlowPath> flowPathsObj = null;
 	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
 
@@ -166,7 +166,7 @@
      * @param flowIds the collection of Flow IDs to get.
      * @return the Flow Paths if found, otherwise an empty list.
      */
-    static ArrayList<FlowPath> getFlows(GraphDBOperation dbHandler,
+    static ArrayList<FlowPath> getFlows(DBOperation dbHandler,
 		  			Collection<FlowId> flowIds) {
 	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
 
@@ -197,10 +197,10 @@
      * This is simply a wrapper for FlowDatabaseOperation.getFlow()
      */
     private final static class GetFlowTask implements Callable<FlowPath> {
-	private final GraphDBOperation dbHandler;
+	private final DBOperation dbHandler;
 	private final FlowId flowId;
-	
-	GetFlowTask(GraphDBOperation dbHandler, FlowId flowId) {
+
+	GetFlowTask(DBOperation dbHandler, FlowId flowId) {
 	    this.dbHandler = dbHandler;
 	    this.flowId = flowId;
 	}
@@ -219,7 +219,7 @@
      * @param flowPath the Flow Path to install.
      * @return true on success, otherwise false.
      */
-    static boolean addFlow(GraphDBOperation dbHandler, FlowPath flowPath) {
+    static boolean addFlow(DBOperation dbHandler, FlowPath flowPath) {
 	Future<Boolean> result = executor.submit(new AddFlowTask(dbHandler, flowPath, null));
 	// NOTE: This function is blocking
 	try {
@@ -237,7 +237,7 @@
      * @param datagridService the notification service for when the task is completed
      * @return true always
      */
-    static boolean addFlow(GraphDBOperation dbHandler, FlowPath flowPath, IDatagridService datagridService) {
+    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. 
@@ -252,11 +252,11 @@
      * which also sends a notification if a datagrid services is provided
      */
     private final static class AddFlowTask implements Callable<Boolean> {
-	private final GraphDBOperation dbHandler;
+	private final DBOperation dbHandler;
 	private final FlowPath flowPath;
 	private final IDatagridService datagridService;
-	
-	AddFlowTask(GraphDBOperation dbHandler, 
+
+	AddFlowTask(DBOperation dbHandler,
 		    FlowPath flowPath,
 		    IDatagridService datagridService) {
 	    this.dbHandler = dbHandler;
@@ -331,7 +331,7 @@
      * @param flowId the Flow ID of the flow to delete.
      * @return true on success, otherwise false.
      */
-    static boolean deleteFlow(GraphDBOperation dbHandler, FlowId flowId) {
+    static boolean deleteFlow(DBOperation dbHandler, FlowId flowId) {
 	Future<Boolean> result = executor.submit(new DeleteFlowTask(dbHandler, flowId, null));
 	// NOTE: This function is blocking
 	try {
@@ -349,7 +349,7 @@
      * @param datagridService the notification service for when the task is completed
      * @return true always
      */
-    static boolean deleteFlow(GraphDBOperation dbHandler, FlowId flowId, IDatagridService datagridService) {
+    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. 
@@ -363,11 +363,11 @@
      * which also sends a notification if a datagrid services is provided
      */
     private final static class DeleteFlowTask implements Callable<Boolean> {
-	private final GraphDBOperation dbHandler;
+	private final DBOperation dbHandler;
 	private final FlowId flowId;
 	private final IDatagridService datagridService;
-	
-	DeleteFlowTask(GraphDBOperation dbHandler, FlowId flowId, IDatagridService datagridService) {
+
+	DeleteFlowTask(DBOperation dbHandler, FlowId flowId, IDatagridService datagridService) {
 	    this.dbHandler = dbHandler;
 
 	    // Create a copy of the FlowId object
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowProgrammer.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowProgrammer.java
index e94d948..4915cc7 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowProgrammer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowProgrammer.java
@@ -44,7 +44,7 @@
 				       IOFSwitchListener {
     // flag to enable FlowSynchronizer
     private static final boolean enableFlowSync = true;
-    protected static Logger log = LoggerFactory.getLogger(FlowProgrammer.class);
+    protected static final Logger log = LoggerFactory.getLogger(FlowProgrammer.class);
     protected volatile IFloodlightProviderService floodlightProvider;
     protected volatile IControllerRegistryService registryService;
     protected volatile IRestApiService restApi;
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 ab2b31d..bd98527 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
@@ -24,7 +24,8 @@
 import org.slf4j.LoggerFactory;
 
 import net.floodlightcontroller.core.IOFSwitch;
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
 import net.onrc.onos.ofcontroller.flowmanager.FlowDatabaseOperation;
@@ -44,12 +45,12 @@
 
     private static Logger log = LoggerFactory.getLogger(FlowSynchronizer.class);
 
-    private GraphDBOperation dbHandler;
+    private DBOperation dbHandler;
     protected IFlowPusherService pusher;
     private Map<IOFSwitch, FutureTask<SyncResult>> switchThreads; 
 
     public FlowSynchronizer() {
-	dbHandler = new GraphDBOperation("");
+	dbHandler = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloud.conf");
 	switchThreads = new HashMap<IOFSwitch, FutureTask<SyncResult>>();
     }
 
@@ -102,6 +103,10 @@
 	    Set<FlowEntryWrapper> graphEntries = getFlowEntriesFromGraph();
 	    long step1 = System.nanoTime();
 	    Set<FlowEntryWrapper> switchEntries = getFlowEntriesFromSwitch();
+	    if (switchEntries == null) {
+	    	log.debug("getFlowEntriesFromSwitch() failed");
+	    	return null;
+	    }
 	    long step2 = System.nanoTime();
 	    SyncResult result = compare(graphEntries, switchEntries);
 	    long step3 = System.nanoTime();
@@ -216,12 +221,15 @@
 	    } catch (IOException e) {
 		// TODO Auto-generated catch block
 		e.printStackTrace();
+		return null;
 	    } catch (InterruptedException e) {
 		// TODO Auto-generated catch block
 		e.printStackTrace();
+		return null;
 	    } catch (ExecutionException e) {
 		// TODO Auto-generated catch block
 		e.printStackTrace();
+		return null;
 	    }
 
 	    Set<FlowEntryWrapper> results = new HashSet<FlowEntryWrapper>();
@@ -337,7 +345,7 @@
 	 */
 	@Override
 	public boolean equals(Object obj){
-	    if(obj.getClass() == this.getClass()) {
+	    if(obj != null && obj.getClass() == this.getClass()) {
 		FlowEntryWrapper entry = (FlowEntryWrapper) obj;
 		// TODO: we need to actually compare the match + actions
 		return this.flowEntryId.equals(entry.flowEntryId);
diff --git a/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java b/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
index 8ca3989..882d5fa 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
@@ -1,6 +1,5 @@
 package net.onrc.onos.ofcontroller.forwarding;
 
-import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -16,7 +15,6 @@
 import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPv4;
 import net.floodlightcontroller.util.MACAddress;
 import net.onrc.onos.datagrid.IDatagridService;
 import net.onrc.onos.ofcontroller.core.IDeviceStorage;
@@ -27,11 +25,13 @@
 import net.onrc.onos.ofcontroller.devicemanager.IOnosDeviceService;
 import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
 import net.onrc.onos.ofcontroller.flowprogrammer.IFlowPusherService;
-import net.onrc.onos.ofcontroller.proxyarp.ArpMessage;
+import net.onrc.onos.ofcontroller.proxyarp.BroadcastPacketOutNotification;
+import net.onrc.onos.ofcontroller.proxyarp.IProxyArpService;
 import net.onrc.onos.ofcontroller.topology.TopologyManager;
 import net.onrc.onos.ofcontroller.util.CallerId;
 import net.onrc.onos.ofcontroller.util.DataPath;
 import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.FlowEntry;
 import net.onrc.onos.ofcontroller.util.FlowEntryMatch;
 import net.onrc.onos.ofcontroller.util.FlowId;
 import net.onrc.onos.ofcontroller.util.FlowPath;
@@ -53,7 +53,6 @@
 
 import com.google.common.collect.LinkedListMultimap;
 import com.google.common.collect.ListMultimap;
-import com.google.common.net.InetAddresses;
 
 public class Forwarding implements IOFMessageListener, IFloodlightModule,
 									IForwardingService {
@@ -61,8 +60,8 @@
 
 	private final int IDLE_TIMEOUT = 5; // seconds
 	private final int HARD_TIMEOUT = 0; // seconds
-
-	private final int PATH_PUSHED_TIMEOUT = 3000; // milliseconds
+	
+	private final CallerId callerId = new CallerId("Forwarding");
 	
 	private IFloodlightProviderService floodlightProvider;
 	private IFlowService flowService;
@@ -72,7 +71,6 @@
 	private IDeviceStorage deviceStorage;
 	private TopologyManager topologyService;
 	
-	//private Map<Path, Long> pendingFlows;
 	// TODO it seems there is a Guava collection that will time out entries.
 	// We should see if this will work here.
 	private Map<Path, PushedFlow> pendingFlows;
@@ -92,31 +90,18 @@
 	
 	private class PushedFlow {
 		public final long flowId;
-		private final long pushedTime;
-		public short firstHopOutPort = OFPort.OFPP_NONE.getValue();
+		public boolean installed = false;
 		
 		public PushedFlow(long flowId) {
 			this.flowId = flowId;
-			pushedTime = System.currentTimeMillis();
-		}
-		
-		public boolean isExpired() {
-			return (System.currentTimeMillis() - pushedTime) > PATH_PUSHED_TIMEOUT;
 		}
 	}
 	
 	private final class Path {
-		public final SwitchPort srcPort;
-		public final SwitchPort dstPort;
 		public final MACAddress srcMac;
 		public final MACAddress dstMac;
 		
-		public Path(SwitchPort src, SwitchPort dst, 
-				MACAddress srcMac, MACAddress dstMac) {
-			srcPort = new SwitchPort(new Dpid(src.dpid().value()), 
-					new Port(src.port().value()));
-			dstPort = new SwitchPort(new Dpid(dst.dpid().value()), 
-					new Port(dst.port().value()));
+		public Path(MACAddress srcMac, MACAddress dstMac) {
 			this.srcMac = srcMac;
 			this.dstMac = dstMac;
 		}
@@ -128,17 +113,13 @@
 			}
 			
 			Path otherPath = (Path) other;
-			return srcPort.equals(otherPath.srcPort) && 
-					dstPort.equals(otherPath.dstPort) &&
-					srcMac.equals(otherPath.srcMac) &&
+			return srcMac.equals(otherPath.srcMac) &&
 					dstMac.equals(otherPath.dstMac);
 		}
 		
 		@Override
 		public int hashCode() {
 			int hash = 17;
-			hash = 31 * hash + srcPort.hashCode();
-			hash = 31 * hash + dstPort.hashCode();
 			hash = 31 * hash + srcMac.hashCode();
 			hash = 31 * hash + dstMac.hashCode();
 			return hash;
@@ -146,8 +127,7 @@
 		
 		@Override
 		public String toString() {
-			return "(" + srcMac + " at " + srcPort + ") => (" 
-					+ dstPort + " at " + dstMac + ")";
+			return "(" + srcMac + ") => (" + dstMac + ")";
 		}
 	}
 	
@@ -175,6 +155,9 @@
 		dependencies.add(IFlowService.class);
 		dependencies.add(IFlowPusherService.class);
 		dependencies.add(IOnosDeviceService.class);
+		// We don't use the IProxyArpService directly, but reactive forwarding
+		// requires it to be loaded and answering ARP requests
+		dependencies.add(IProxyArpService.class);
 		return dependencies;
 	}
 	
@@ -187,18 +170,14 @@
 		datagrid = context.getServiceImpl(IDatagridService.class);
 		
 		floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-		
-		//pendingFlows = new ConcurrentHashMap<Path, Long>();
+
 		pendingFlows = new HashMap<Path, PushedFlow>();
-		//waitingPackets = Multimaps.synchronizedSetMultimap(
-				//HashMultimap.<Long, PacketToPush>create());
-		//waitingPackets = HashMultimap.create();
 		waitingPackets = LinkedListMultimap.create();
 		
 		deviceStorage = new DeviceStorageImpl();
-		deviceStorage.init("");
+		deviceStorage.init("","");
 		topologyService = new TopologyManager();
-		topologyService.init("");
+		topologyService.init("","");
 	}
 	
 	@Override
@@ -242,7 +221,6 @@
 		
 		if (eth.isBroadcast() || eth.isMulticast()) {
 			handleBroadcast(sw, pi, eth);
-			//return Command.CONTINUE;
 		}
 		else {
 			// Unicast
@@ -256,24 +234,9 @@
 		if (log.isTraceEnabled()) {
 			log.trace("Sending broadcast packet to other ONOS instances");
 		}
-		
-		IPv4 ipv4Packet = (IPv4) eth.getPayload();
-		
-		// TODO We'll put the destination address here, because the current
-		// architecture needs an address. Addresses are only used for replies
-		// however, which don't apply to non-ARP packets. The ArpMessage class
-		// has become a bit too overloaded and should be refactored to 
-		// handle all use cases nicely.
-		 InetAddress targetAddress = 
-				InetAddresses.fromInteger(ipv4Packet.getDestinationAddress());
-		
-		// Piggy-back on the ARP mechanism to broadcast this packet out the
-		// edge. Luckily the ARP module doesn't check that the packet is
-		// actually ARP before broadcasting, so we can trick it into sending
-		// our non-ARP packets.
-		// TODO This should be refactored later to account for the new use case.
-		datagrid.sendArpRequest(ArpMessage.newRequest(targetAddress, eth.serialize(),
-				-1L, (short)-1, sw.getId(), pi.getInPort()));
+
+		 datagrid.sendPacketOutNotification(new BroadcastPacketOutNotification(
+				 eth.serialize(), sw.getId(), pi.getInPort()));
 	}
 	
 	private void handlePacketIn(IOFSwitch sw, OFPacketIn pi, Ethernet eth) {
@@ -303,7 +266,6 @@
 		long destinationDpid = HexString.toLong(switchObject.getDPID());
 		
 		// TODO SwitchPort, Dpid and Port should probably be immutable
-		// (also, are Dpid and Port are even necessary?)
 		SwitchPort srcSwitchPort = new SwitchPort(
 				new Dpid(sw.getId()), new Port(pi.getInPort())); 
 		SwitchPort dstSwitchPort = new SwitchPort(
@@ -312,26 +274,50 @@
 		MACAddress srcMacAddress = MACAddress.valueOf(eth.getSourceMACAddress());
 		MACAddress dstMacAddress = MACAddress.valueOf(eth.getDestinationMACAddress());
 		
-		
 		FlowPath flowPath, reverseFlowPath;
 		
-		Path pathspec = new Path(srcSwitchPort, dstSwitchPort, 
-				srcMacAddress, dstMacAddress);
+		Path pathspec = new Path(srcMacAddress, dstMacAddress);
 		// TODO check concurrency
 		synchronized (lock) {
 			PushedFlow existingFlow = pendingFlows.get(pathspec);
-			//Long existingFlowId = pendingFlows.get(pathspec);
-			
-			if (existingFlow != null && !existingFlow.isExpired()) {
+
+			if (existingFlow != null) {
+				// We've already installed a flow for this pair of MAC addresses
 				log.debug("Found existing flow {}", 
 						HexString.toHexString(existingFlow.flowId));
 				
 				OFPacketOut po = constructPacketOut(pi, sw);
 				
-				if (existingFlow.firstHopOutPort != OFPort.OFPP_NONE.getValue()) {
+				// Find the correct port here. We just assume the PI is from 
+				// the first hop switch, but this is definitely not always
+				// the case. We'll have to retrieve the flow from HZ every time
+				// because it could change (be rerouted) sometimes.
+				if (existingFlow.installed) {
 					// Flow has been sent to the switches so it is safe to
 					// send a packet out now
-					sendPacketOut(sw, po, existingFlow.firstHopOutPort);
+					FlowPath flow = datagrid.getFlow(new FlowId(existingFlow.flowId));
+					FlowEntry flowEntryForThisSwitch = null;
+					
+					if (flow != null) {
+						for (FlowEntry flowEntry : flow.flowEntries()) {
+							if (flowEntry.dpid().equals(new Dpid(sw.getId()))) {
+								flowEntryForThisSwitch = flowEntry;
+								break;
+							}
+						}
+					}
+					
+					if (flowEntryForThisSwitch == null) {
+						// If we don't find a flow entry for that switch, then we're
+						// in the middle of a rerouting (or something's gone wrong). 
+						// This packet will be dropped as a victim of the rerouting.
+						log.debug("Dropping packet on flow {} between {}-{}, flow path {}",
+								new Object[] {new FlowId(existingFlow.flowId),
+								srcMacAddress, dstMacAddress, flow});
+					}
+					else {
+						sendPacketOut(sw, po, flowEntryForThisSwitch.outPort().value());
+					}
 				}
 				else {
 					// Flow has not yet been sent to switches so save the
@@ -341,21 +327,16 @@
 				}
 				return;
 			}
-			
-			//log.debug("Couldn't match {} in {}", pathspec, pendingFlows);
-			
+
 			log.debug("Adding new flow between {} at {} and {} at {}",
 					new Object[]{srcMacAddress, srcSwitchPort, dstMacAddress, dstSwitchPort});
 			
-			
-			CallerId callerId = new CallerId("Forwarding");
-			
 			DataPath datapath = new DataPath();
 			datapath.setSrcPort(srcSwitchPort);
 			datapath.setDstPort(dstSwitchPort);
 			
 			flowPath = new FlowPath();
-			flowPath.setInstallerId(callerId);
+			flowPath.setInstallerId(new CallerId(callerId));
 	
 			flowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
 			flowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
@@ -375,7 +356,7 @@
 			
 			// TODO implement copy constructor for FlowPath
 			reverseFlowPath = new FlowPath();
-			reverseFlowPath.setInstallerId(callerId);
+			reverseFlowPath.setInstallerId(new CallerId(callerId));
 			reverseFlowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
 			reverseFlowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
 			reverseFlowPath.setIdleTimeout(IDLE_TIMEOUT);
@@ -387,9 +368,7 @@
 			reverseFlowPath.flowEntryMatch().enableEthernetFrameType(Ethernet.TYPE_IPv4);
 			reverseFlowPath.setDataPath(reverseDataPath);
 			reverseFlowPath.dataPath().srcPort().dpid().toString();
-			
-			// TODO what happens if no path exists? cleanup
-			
+
 			FlowId flowId = new FlowId(flowService.getNextFlowEntryId());
 			FlowId reverseFlowId = new FlowId(flowService.getNextFlowEntryId());
 			
@@ -397,50 +376,23 @@
 			reverseFlowPath.setFlowId(reverseFlowId);
 			
 			OFPacketOut po = constructPacketOut(pi, sw);
-			Path reversePathSpec = new Path(dstSwitchPort, srcSwitchPort, 
-					dstMacAddress, srcMacAddress);
+			Path reversePathSpec = new Path(dstMacAddress, srcMacAddress);
 			
 			// Add to waiting lists
-			//pendingFlows.put(pathspec, flowId.value());
-			//pendingFlows.put(reversePathSpec, reverseFlowId.value());
 			pendingFlows.put(pathspec, new PushedFlow(flowId.value()));
 			pendingFlows.put(reversePathSpec, new PushedFlow(reverseFlowId.value()));
 			waitingPackets.put(flowId.value(), new PacketToPush(po, sw.getId()));
 		
 		}
 		
+		log.debug("Adding reverse {} to {} flowid {}", new Object[] {
+				dstMacAddress, srcMacAddress, reverseFlowPath.flowId()});
 		flowService.addFlow(reverseFlowPath);
+		log.debug("Adding forward {} to {} flowid {}", new Object[] {
+				srcMacAddress, dstMacAddress, flowPath.flowId()});
 		flowService.addFlow(flowPath);
 		
 	}
-	
-	/*
-	private boolean flowExists(SwitchPort srcPort, MACAddress srcMac, 
-			SwitchPort dstPort, MACAddress dstMac) {
-		for (FlowPath flow : datagridService.getAllFlows()) {
-			FlowEntryMatch match = flow.flowEntryMatch();
-			// TODO implement FlowEntryMatch.equals();
-			// This is painful to do properly without support in the FlowEntryMatch
-			boolean same = true;
-			if (!match.srcMac().equals(srcMac) ||
-				!match.dstMac().equals(dstMac)) {
-				same = false;
-			}
-			if (!flow.dataPath().srcPort().equals(srcPort) || 
-				!flow.dataPath().dstPort().equals(dstPort)) {
-				same = false;
-			}
-			
-			if (same) {
-				log.debug("found flow entry that's the same {}-{}:::{}-{}",
-						new Object[] {srcPort, srcMac, dstPort, dstMac});
-				return true;
-			}
-		}
-		
-		return false;
-	}
-	*/
 
 	private OFPacketOut constructPacketOut(OFPacketIn pi, IOFSwitch sw) {	
 		OFPacketOut po = new OFPacketOut();
@@ -467,36 +419,64 @@
 			flowInstalled(flowPath);
 		}
 	}
+	
+	@Override
+	public void flowRemoved(FlowPath removedFlowPath) {
+		if (!removedFlowPath.installerId().equals(callerId)) {
+			// Not our flow path, ignore
+			return;
+		}
+		
+		MACAddress srcMacAddress = removedFlowPath.flowEntryMatch().srcMac();
+		MACAddress dstMacAddress = removedFlowPath.flowEntryMatch().dstMac();
+		
+		Path removedPath = new Path(srcMacAddress, dstMacAddress);
+		
+		synchronized (lock) {
+			pendingFlows.remove(removedPath);
+			
+			// There *shouldn't* be any packets queued if the flow has 
+			// just been removed. 
+			List<PacketToPush> packets = 
+					waitingPackets.removeAll(removedFlowPath.flowId().value());
+			if (!packets.isEmpty()) {
+				log.warn("Removed flow {} has packets queued", 
+						removedFlowPath.flowId());
+			}
+		}
+	}
 
 	private void flowInstalled(FlowPath installedFlowPath) {
 		long flowId = installedFlowPath.flowId().value();
 		
+		if (!installedFlowPath.installerId().equals(callerId)) {
+			// Not our flow path, ignore
+			return;
+		}
+		
+		// TODO waiting packets should time out. We could request a path that
+		// can't be installed right now because of a network partition. The path
+		// may eventually be installed, but we may have received thousands of 
+		// packets in the meantime and probably don't want to send very old packets.
 		short outPort = 
 				installedFlowPath.flowEntries().get(0).outPort().value();
 		
 		MACAddress srcMacAddress = installedFlowPath.flowEntryMatch().srcMac();
 		MACAddress dstMacAddress = installedFlowPath.flowEntryMatch().dstMac();
 		
-		if (srcMacAddress == null || dstMacAddress == null) {
-			// Not our flow path, ignore
-			return;
-		}
-		
 		Collection<PacketToPush> packets;
 		synchronized (lock) {
-			log.debug("Flow {} has been installed, sending queued packets",
-					installedFlowPath.flowId());
-			
 			packets = waitingPackets.removeAll(flowId);
 			
+			log.debug("Flow {} has been installed, sending {} queued packets",
+					installedFlowPath.flowId(), packets.size());
+			
 			// remove pending flows entry
-			Path installedPath = new Path(installedFlowPath.dataPath().srcPort(),
-					installedFlowPath.dataPath().dstPort(),
-					srcMacAddress, dstMacAddress);
-			//pendingFlows.remove(pathToRemove);
+			Path installedPath = new Path(srcMacAddress, dstMacAddress);
 			PushedFlow existingFlow = pendingFlows.get(installedPath);
-			if (existingFlow != null)
-			    existingFlow.firstHopOutPort = outPort;
+			if (existingFlow != null) {
+			    existingFlow.installed = true;
+			}
 		}
 		
 		for (PacketToPush packet : packets) {
@@ -514,4 +494,5 @@
 		
 		flowPusher.add(sw, po);
 	}
+
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/forwarding/IForwardingService.java b/src/main/java/net/onrc/onos/ofcontroller/forwarding/IForwardingService.java
index e5bd714..0e0d1da 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/forwarding/IForwardingService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/forwarding/IForwardingService.java
@@ -22,4 +22,12 @@
 	 * been installed in the network.
 	 */
 	public void flowsInstalled(Collection<FlowPath> installedFlowPaths);
+	
+	/**
+	 * Notify the Forwarding module that a flow has expired and been 
+	 * removed from the network.
+	 * 
+	 * @param removedFlowPath The FlowPath that was removed
+	 */
+	public void flowRemoved(FlowPath removedFlowPath);
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpMessage.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpMessage.java
deleted file mode 100644
index 44b9ea0..0000000
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpMessage.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package net.onrc.onos.ofcontroller.proxyarp;
-
-import java.io.Serializable;
-import java.net.InetAddress;
-import net.floodlightcontroller.util.MACAddress;
-
-// TODO This is getting very messy!!! Needs refactoring
-public class ArpMessage implements Serializable {
-
-	private static final long serialVersionUID = 1L;
-	
-	private final Type type;
-	private final InetAddress forAddress;
-	private final byte[] packetData;
-	
-	// ARP reply message needs MAC info
-	private final MACAddress mac;
-	// Only send the ARP request message to the device attachment needs the 
-	// attachment switch and port. 
-	private final long outSwitch; 
-	private final short outPort;
-	
-	private final long inSwitch;
-	private final short inPort;
-
-	public enum Type {
-		REQUEST,
-		REPLY
-	}
-	
-	private ArpMessage(Type type, InetAddress address, byte[] eth, 
-			long outSwitch, short outPort, long inSwitch, short inPort) {
-		this.type = type;
-		this.forAddress = address;
-		this.packetData = eth;
-		this.mac = null;
-		this.outSwitch = -1;
-		this.outPort = -1;
-		this.inSwitch = inSwitch;
-		this.inPort = inPort;
-	}
-	
-	private ArpMessage(Type type, InetAddress address) {
-		this.type = type;
-		this.forAddress = address;
-		this.packetData = null;
-		this.mac = null;
-		this.outSwitch = -1;
-		this.outPort = -1;
-		
-		this.inSwitch = -1;
-		this.inPort = -1;
-	}
-	// the ARP reply message with MAC
-	private ArpMessage(Type type, InetAddress address, MACAddress mac) {
-		this.type = type;
-		this.forAddress = address;
-		this.packetData = null;
-		this.mac = mac;
-		this.outSwitch = -1;
-		this.outPort = -1;
-		
-		this.inSwitch = -1;
-		this.inPort = -1;
-	}
-	
-	// construct ARP request message with attachment switch and port
-	private ArpMessage(Type type, InetAddress address, byte[] arpRequest,
-			long outSwitch, short outPort) {
-		this.type = type;
-		this.forAddress = address;
-		this.packetData = arpRequest; 	
-		this.mac = null;
-		this.outSwitch = outSwitch; 
-		this.outPort = outPort;	
-		
-		this.inSwitch = -1;
-		this.inPort = -1;
-	}
-
-	// TODO Awful quick fix - caller has to supply dummy outSwitch and outPort
-	public static ArpMessage newRequest(InetAddress forAddress, byte[] arpRequest,
-			long outSwitch, short outPort, long inSwitch, short inPort) {
-		return new ArpMessage(Type.REQUEST, forAddress, arpRequest, 
-				outSwitch, outPort, inSwitch, inPort);
-	}
-	
-	public static ArpMessage newReply(InetAddress forAddress) {
-		return new ArpMessage(Type.REPLY, forAddress);
-	}
-	
-	//ARP reply message with MAC
-	public static ArpMessage newReply(InetAddress forAddress, MACAddress mac) {
-		return new ArpMessage(Type.REPLY, forAddress, mac);
-	}
-	
-	//ARP request message with attachment switch and port
-	public static ArpMessage newRequest(InetAddress forAddress, 
-			byte[] arpRequest, long outSwitch, short outPort ) {
-		return new ArpMessage(Type.REQUEST, forAddress, arpRequest, outSwitch, 
-				outPort);
-	}
-
-	public Type getType() {
-		return type;
-	}
-	
-	public InetAddress getAddress() {
-		return forAddress;
-	}
-	
-	public byte[] getPacket() {
-		return packetData;
-	}
-	
-	public MACAddress getMAC() {
-		return mac;
-	}
-
-	public long getOutSwitch() {
-		return outSwitch;
-	}
-
-	public short getOutPort() {
-		return outPort;
-	}
-	
-	public long getInSwitch() {
-		return inSwitch;
-	}
-
-	public short getInPort() {
-		return inPort;
-	}
-}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpReplyNotification.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpReplyNotification.java
new file mode 100644
index 0000000..a8afc55
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpReplyNotification.java
@@ -0,0 +1,28 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+
+import net.floodlightcontroller.util.MACAddress;
+
+public class ArpReplyNotification implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+	
+	private InetAddress targetAddress;
+	private MACAddress targetMacAddress;
+	
+	public ArpReplyNotification(InetAddress targetAddress, MACAddress targetMacAddress) {
+		this.targetAddress = targetAddress;
+		this.targetMacAddress = targetMacAddress;
+	}
+
+	public InetAddress getTargetAddress() {
+		return targetAddress;
+	}
+
+	public MACAddress getTargetMacAddress() {
+		return targetMacAddress;
+	}
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BgpProxyArpManager.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BgpProxyArpManager.java
index 801e414..3dba4f8 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BgpProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BgpProxyArpManager.java
@@ -143,7 +143,7 @@
 		floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
 		
 		deviceStorage = new DeviceStorageImpl();
-		deviceStorage.init("");
+		deviceStorage.init("","");
 		
 		Timer arpTimer = new Timer("arp-processing");
 		arpTimer.scheduleAtFixedRate(new TimerTask() {
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BroadcastPacketOutNotification.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BroadcastPacketOutNotification.java
new file mode 100644
index 0000000..73d2163
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BroadcastPacketOutNotification.java
@@ -0,0 +1,34 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+/**
+ * Notification to all ONOS instances to broadcast this packet out the edge of
+ * the network. The edge is defined as any port that doesn't have a link to
+ * another switch. The one exception is the port that the packet was received
+ * on.
+ *
+ */
+public class BroadcastPacketOutNotification extends
+		PacketOutNotification {
+	
+	private static final long serialVersionUID = 1L;
+	
+	private final long inSwitch;
+	private final short inPort;
+
+	public BroadcastPacketOutNotification(byte[] packet, long inSwitch, 
+			short inPort) {
+		super(packet);
+		
+		this.inSwitch = inSwitch;
+		this.inPort = inPort;
+	}
+
+	public long getInSwitch() {
+		return inSwitch;
+	}
+
+	public short getInPort() {
+		return inPort;
+	}
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpEventHandler.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpEventHandler.java
deleted file mode 100644
index 4ec32ec..0000000
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpEventHandler.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package net.onrc.onos.ofcontroller.proxyarp;
-
-public interface IArpEventHandler {
-
-	/**
-	 * Notify the ARP event handler that an ARP request has been received.
-	 * @param id The string ID of the ARP request
-	 * @param arpRequest The ARP request packet
-	 */
-	public void arpRequestNotification(ArpMessage arpMessage);
-}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpReplyEventHandler.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpReplyEventHandler.java
new file mode 100644
index 0000000..75f1d5d
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpReplyEventHandler.java
@@ -0,0 +1,5 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+public interface IArpReplyEventHandler {
+	public void arpReplyEvent(ArpReplyNotification arpReply);
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IPacketOutEventHandler.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IPacketOutEventHandler.java
new file mode 100644
index 0000000..86b3728
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IPacketOutEventHandler.java
@@ -0,0 +1,18 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+/**
+ * Classes may implement this interface if they wish to subscribe to 
+ * packet out notifications from the datagrid service. Packet out notifications
+ * are used to direct other ONOS instances to send packets out particular
+ * ports under their control.
+ *
+ */
+public interface IPacketOutEventHandler {
+
+	/**
+	 * Notify the packet out event handler that an packet out notification has
+	 * been received.
+	 * @param packetOutNotification An object describing the notification
+	 */
+	public void packetOutNotification(PacketOutNotification packetOutNotification);
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/PacketOutNotification.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/PacketOutNotification.java
new file mode 100644
index 0000000..3d37d25
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/PacketOutNotification.java
@@ -0,0 +1,21 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+import java.io.Serializable;
+
+/**
+ * A PacketOutNotification contains data sent between ONOS instances that
+ * directs other instances to send a packet out a set of ports.
+ * This is an abstract base class that will be subclassed by specific
+ * types of notifications.
+ *
+ */
+public abstract class PacketOutNotification implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+	
+	protected final byte[] packet;
+
+	public PacketOutNotification(byte[] packet) {
+		this.packet = packet;
+	}
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
index 289e0e2..f5fee45 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -37,6 +37,7 @@
 import net.onrc.onos.ofcontroller.core.config.IConfigInfoService;
 import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
 import net.onrc.onos.ofcontroller.core.internal.TopoSwitchServiceImpl;
+import net.onrc.onos.ofcontroller.flowprogrammer.IFlowPusherService;
 import net.onrc.onos.ofcontroller.util.Dpid;
 import net.onrc.onos.ofcontroller.util.Port;
 import net.onrc.onos.ofcontroller.util.SwitchPort;
@@ -58,7 +59,8 @@
 import com.google.common.net.InetAddresses;
 
 public class ProxyArpManager implements IProxyArpService, IOFMessageListener,
-										IArpEventHandler, IFloodlightModule {
+										IPacketOutEventHandler, IArpReplyEventHandler, 
+										IFloodlightModule {
 	private final static Logger log = LoggerFactory.getLogger(ProxyArpManager.class);
 	
 	private final long ARP_TIMER_PERIOD = 100; //ms  
@@ -70,6 +72,7 @@
 	private IDatagridService datagrid;
 	private IConfigInfoService configService;
 	private IRestApiService restApi;
+	private IFlowPusherService flowPusher;
 	
 	private IDeviceStorage deviceStorage;
 	private volatile ITopoSwitchService topoSwitchService;
@@ -153,6 +156,7 @@
 		dependencies.add(IRestApiService.class);
 		dependencies.add(IDatagridService.class);
 		dependencies.add(IConfigInfoService.class);
+		dependencies.add(IFlowPusherService.class);
 		return dependencies;
 	}
 	
@@ -164,6 +168,7 @@
 		this.datagrid = context.getServiceImpl(IDatagridService.class);
 		this.configService = context.getServiceImpl(IConfigInfoService.class);
 		this.restApi = context.getServiceImpl(IRestApiService.class);
+		this.flowPusher = context.getServiceImpl(IFlowPusherService.class);
 		
 		//arpCache = new ArpCache();
 
@@ -181,10 +186,11 @@
 		restApi.addRestletRoutable(new ArpWebRoutable());
 		floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
 		
-		datagrid.registerArpEventHandler(this);
+		datagrid.registerPacketOutEventHandler(this);
+		datagrid.registerArpReplyEventHandler(this);
 		
 		deviceStorage = new DeviceStorageImpl();
-		deviceStorage.init("");
+		deviceStorage.init("","");
 		
 		Timer arpTimer = new Timer("arp-processing");
 		arpTimer.scheduleAtFixedRate(new TimerTask() {
@@ -290,8 +296,10 @@
 				handleArpRequest(sw, pi, arp, eth);
 			}
 			else if (arp.getOpCode() == ARP.OP_REPLY) {
-				handleArpReply(sw, pi, arp);
-				sendToOtherNodesReply(eth, pi);
+				// For replies we simply send a notification via Hazelcast
+				sendArpReplyNotification(eth, pi);
+				
+				//handleArpReply(sw, pi, arp);
 			}
 			
 			// Stop ARP packets here
@@ -345,7 +353,9 @@
 			}
 			
 			// We don't know the device so broadcast the request out
-			sendToOtherNodes(eth, sw.getId(), pi);
+			datagrid.sendPacketOutNotification(
+					new BroadcastPacketOutNotification(eth.serialize(), 
+							sw.getId(), pi.getInPort()));
 		}
 		else {
 			// Even if the device exists in our database, we do not reply to
@@ -362,7 +372,6 @@
 
 			// sendArpReply(arp, sw.getId(), pi.getInPort(), macAddress);
 
-			log.trace("Checking the device info from DB is still valid or not");
 			Iterable<IPortObject> outPorts = targetDevice.getAttachedPorts();	
 
 			if (!outPorts.iterator().hasNext()){
@@ -371,19 +380,26 @@
 							" - broadcasting", macAddress);
 				}
 				
-				sendToOtherNodes(eth, sw.getId(), pi);
+				datagrid.sendPacketOutNotification(
+						new BroadcastPacketOutNotification(eth.serialize(), 
+								sw.getId(), pi.getInPort()));
 			} 
 			else {
 				for (IPortObject portObject : outPorts) {
-					long outSwitch = 0;
-					short outPort = 0;
+					//long outSwitch = 0;
+					//short outPort = 0;
 
+					/*
 					if (!portObject.getLinkedPorts().iterator().hasNext()) {
 						outPort = portObject.getNumber();					
+					}*/
+					if (portObject.getLinkedPorts().iterator().hasNext()) {
+						continue;
 					}
 
+					short outPort = portObject.getNumber();
 					ISwitchObject outSwitchObject = portObject.getSwitch();
-					outSwitch = HexString.toLong(outSwitchObject.getDPID());
+					long outSwitch = HexString.toLong(outSwitchObject.getDPID());
 
 					if (log.isTraceEnabled()) {
 						log.trace("Probing device {} on port {}/{}", 
@@ -391,7 +407,9 @@
 								HexString.toHexString(outSwitch), outPort});
 					}
 					
-					sendToOtherNodes(eth, pi, outSwitch, outPort);
+					datagrid.sendPacketOutNotification(
+							new SinglePacketOutNotification(eth.serialize(), 
+									outSwitch, outPort));
 				}
 			}
 		}
@@ -517,50 +535,7 @@
 		}
 	}
 	
-	private void sendToOtherNodes(Ethernet eth, long inSwitchId, OFPacketIn pi) {
-		ARP arp = (ARP) eth.getPayload();
-		
-		if (log.isTraceEnabled()) {
-			log.trace("Sending ARP request for {} to other ONOS instances",
-					inetAddressToString(arp.getTargetProtocolAddress()));
-		}
-		
-		InetAddress targetAddress;
-		try {
-			targetAddress = InetAddress.getByAddress(arp.getTargetProtocolAddress());
-		} catch (UnknownHostException e) {
-			log.error("Unknown host", e);
-			return;
-		}
-		
-		datagrid.sendArpRequest(ArpMessage.newRequest(targetAddress, eth.serialize(),
-				-1L, (short)-1, inSwitchId, pi.getInPort()));
-	}
-	
-	//hazelcast to other ONOS instances to send the ARP packet out on outPort of outSwitch
-	private void sendToOtherNodes(Ethernet eth, OFPacketIn pi, long outSwitch, short outPort) {
-		ARP arp = (ARP) eth.getPayload();
-		
-		if (log.isTraceEnabled()) {
-			log.trace("Sending ARP request for {} to other ONOS instances with outSwitch {} ",
-					inetAddressToString(arp.getTargetProtocolAddress()), String.valueOf(outSwitch));
-		}
-		
-		InetAddress targetAddress;
-		try {
-			targetAddress = InetAddress.getByAddress(arp.getTargetProtocolAddress());
-		} catch (UnknownHostException e) {
-			log.error("Unknown host", e);
-			return;
-		}
-		
-		datagrid.sendArpRequest(ArpMessage.newRequest(targetAddress, eth.serialize(), outSwitch, outPort)); 
-		//datagrid.sendArpRequest(ArpMessage.newRequest(targetAddress, eth.serialize()));
-		
-		
-	}
-	
-	private void sendToOtherNodesReply(Ethernet eth, OFPacketIn pi) {
+	private void sendArpReplyNotification(Ethernet eth, OFPacketIn pi) {
 		ARP arp = (ARP) eth.getPayload();
 		
 		if (log.isTraceEnabled()) {
@@ -577,12 +552,14 @@
 			log.error("Unknown host", e);
 			return;
 		}
-		
-		datagrid.sendArpRequest(ArpMessage.newReply(targetAddress, mac));
-		//datagrid.sendArpReply(ArpMessage.newRequest(targetAddress, eth.serialize()));
-	
+
+		datagrid.sendArpReplyNotification(new ArpReplyNotification(targetAddress, mac));
 	}
 	
+	// This remains from the older single-instance ARP code. It used Floodlight
+	// APIs to find the edge of the network, but only worked on a single instance.
+	// We now do this using ONOS network graph APIs.
+	@Deprecated
 	private void broadcastArpRequestOutEdge(byte[] arpRequest, long inSwitch, short inPort) {
 		for (IOFSwitch sw : floodlightProvider.getSwitches().values()){
 			Collection<Short> enabledPorts = sw.getEnabledPortNumbers();
@@ -673,12 +650,7 @@
 			po.setLengthU(OFPacketOut.MINIMUM_LENGTH + actionsLength 
 					+ arpRequest.length);
 			
-			try {
-				sw.write(po, null);
-				sw.flush();
-			} catch (IOException e) {
-				log.error("Failure writing packet out to switch", e);
-			}
+			flowPusher.add(sw, po);
 		}
 		
 		if (log.isTraceEnabled()) {
@@ -712,12 +684,7 @@
 			return;
 		}
 		
-		try {
-			sw.write(po, null);
-			sw.flush();
-		} catch (IOException e) {
-			log.error("Failure writing packet out to switch", e);
-		}
+		flowPusher.add(sw, po);
 	}
 	
 	private void sendArpReply(ARP arpRequest, long dpid, short port, MACAddress targetMac) {
@@ -740,7 +707,6 @@
 			.setTargetProtocolAddress(arpRequest.getSenderProtocolAddress());
 		
 
-		
 		Ethernet eth = new Ethernet();
 		eth.setDestinationMACAddress(arpRequest.getSenderHardwareAddress())
 			.setSourceMACAddress(targetMac.toBytes())
@@ -775,12 +741,7 @@
 			return;
 		}
 		
-		try {
-			sw.write(msgList, null);
-			sw.flush();
-		} catch (IOException e) {
-			log.error("Failure writing packet out to switch", e);
-		}
+		flowPusher.add(sw, po);
 	}
 	
 	private String inetAddressToString(byte[] bytes) {
@@ -820,9 +781,6 @@
 	}
 
 	/*
-	 * IArpEventHandler methods
-	 */
-	
 	@Override
 	public void arpRequestNotification(ArpMessage arpMessage) {
 		log.debug("Received ARP notification from other instances");
@@ -844,6 +802,7 @@
 			break;
 		}
 	}
+	*/
 	
 	private void sendArpReplyToWaitingRequesters(InetAddress address, MACAddress mac) {
 		log.debug("Sending ARP reply for {} to requesters", 
@@ -876,4 +835,33 @@
 			request.dispatchReply(address, mac);
 		}
 	}
+
+	@Override
+	public void arpReplyEvent(ArpReplyNotification arpReply) {
+		log.debug("Received ARP reply notification for {}",
+				arpReply.getTargetAddress());
+		sendArpReplyToWaitingRequesters(arpReply.getTargetAddress(), 
+				arpReply.getTargetMacAddress());
+	}
+
+	@Override
+	public void packetOutNotification(
+			PacketOutNotification packetOutNotification) {
+		
+		if (packetOutNotification instanceof SinglePacketOutNotification) {
+			SinglePacketOutNotification notification = 
+					(SinglePacketOutNotification) packetOutNotification;
+			sendArpRequestOutPort(notification.packet, notification.getOutSwitch(), 
+					notification.getOutPort());
+		}
+		else if (packetOutNotification instanceof BroadcastPacketOutNotification) {
+			BroadcastPacketOutNotification notification = 
+					(BroadcastPacketOutNotification) packetOutNotification;
+			broadcastArpRequestOutMyEdge(notification.packet, 
+					notification.getInSwitch(), notification.getInPort());
+		}
+		else {
+			log.warn("Unknown packet out notification received");
+		}
+	}
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/SinglePacketOutNotification.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/SinglePacketOutNotification.java
new file mode 100644
index 0000000..1919d87
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/SinglePacketOutNotification.java
@@ -0,0 +1,30 @@
+package net.onrc.onos.ofcontroller.proxyarp;
+
+/**
+ * Notification to another ONOS instance to send a packet out a single port.
+ *
+ */
+public class SinglePacketOutNotification extends PacketOutNotification {
+
+	private static final long serialVersionUID = 1L;
+	
+	private final long outSwitch;
+	private final short outPort;
+	
+	public SinglePacketOutNotification(byte[] packet, long outSwitch, 
+			short outPort) {
+		super(packet);
+		
+		this.outSwitch = outSwitch;
+		this.outPort = outPort;
+	}
+
+	public long getOutSwitch() {
+		return outSwitch;
+	}
+
+	public short getOutPort() {
+		return outPort;
+	}
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/ShortestPath.java b/src/main/java/net/onrc/onos/ofcontroller/topology/ShortestPath.java
index 9a8345c..d9e1314 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/ShortestPath.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/ShortestPath.java
@@ -9,7 +9,7 @@
 import java.util.Queue;
 import java.util.Set;
 
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
 import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
 import net.onrc.onos.ofcontroller.util.DataPath;
@@ -163,7 +163,7 @@
      * @return the data path with the computed shortest path if
      * found, otherwise null.
      */
-    public static DataPath getDatabaseShortestPath(GraphDBOperation dbHandler,
+    public static DataPath getDatabaseShortestPath(DBOperation dbHandler,
 					     SwitchPort src, SwitchPort dest) {
 	DataPath result_data_path = new DataPath();
 
@@ -326,4 +326,4 @@
 
 	return null;
     }
-}
\ No newline at end of file
+}
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 2785e7d..2d4f590 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
@@ -5,7 +5,7 @@
 import java.util.Map;
 import java.util.TreeMap;
 
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
 import net.onrc.onos.graph.IDBOperation;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
@@ -28,7 +28,7 @@
      * paths.
      */
     class Link {
-    	public Node me;                        // The node this link originates from
+        public Node me;                        // The node this link originates from
         public Node neighbor;                // The neighbor node on the other side
         public int myPort;                // Local port ID for the link
         public int neighborPort;        // Neighbor port ID for the link
@@ -392,7 +392,7 @@
      *
      * @param dbHandler the Graph Database handler to use.
      */
-    public void readFromDatabase(GraphDBOperation dbHandler) {
+    public void readFromDatabase(DBOperation dbHandler) {
     	if (enableOptimizedRead) {
     		readFromDatabaseBodyOptimized(dbHandler);
     	} else {
@@ -400,8 +400,8 @@
     	}
 
     }
-    
-    private void readFromDatabaseBody(GraphDBOperation dbHandler) {
+
+    private void readFromDatabaseBody(DBOperation dbHandler) {
     	//
     	// Fetch the relevant info from the Switch and Port vertices
     	// from the Titan Graph.
@@ -472,8 +472,8 @@
     	}
     	dbHandler.commit();
     }
-    
-    private void readFromDatabaseBodyOptimized(GraphDBOperation dbHandler) {
+
+    private void readFromDatabaseBodyOptimized(DBOperation dbHandler) {
 	    nodesMap.clear();
 		    
 		// Load all switches into Map
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 4feaa8e..f326f4c 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
@@ -12,7 +12,8 @@
 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.graph.DBOperation;
+import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.ofcontroller.floodlightlistener.INetworkGraphService;
 import net.onrc.onos.ofcontroller.topology.web.OnosTopologyWebRoutable;
 import net.onrc.onos.ofcontroller.util.DataPath;
@@ -35,7 +36,10 @@
     private final static Logger log = LoggerFactory.getLogger(TopologyManager.class);
     protected IFloodlightProviderService floodlightProvider;
 
-    protected GraphDBOperation dbHandler;
+    protected static final String DBConfigFile = "dbconf";
+    protected static final String GraphDBStore = "graph_db_store";
+
+    protected DBOperation dbHandler;
     protected IRestApiService restApi;
 
 
@@ -51,8 +55,11 @@
      * @param config the database configuration file to use for
      * the initialization.
      */
-    public TopologyManager(String config) {
-	this.init(config);
+    public TopologyManager(FloodlightModuleContext context) {
+	Map<String, String> configMap = context.getConfigParams(this);
+	String conf = configMap.get(DBConfigFile);
+        String dbStore = configMap.get(GraphDBStore);
+	this.init(dbStore,conf);
     }
 
     /**
@@ -61,7 +68,7 @@
      * @param dbHandler the database operation handler to use for the
      * initialization.
      */
-    public TopologyManager(GraphDBOperation dbHandler) {
+    public TopologyManager(DBOperation dbHandler) {
 	this.dbHandler = dbHandler;
     }
 
@@ -71,9 +78,9 @@
      * @param config the database configuration file to use for
      * the initialization.
      */
-    public void init(String config) {
+    public void init(final String dbStore, String config) {
 	try {
-	    dbHandler = new GraphDBOperation(config);
+	    dbHandler = GraphDBManager.getDBOperation("ramcloud", "/tmp/ramcloud.conf");
 	} catch (Exception e) {
 	    log.error(e.getMessage());
 	}
@@ -149,9 +156,10 @@
 	throws FloodlightModuleException {
 	floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
 	restApi = context.getServiceImpl(IRestApiService.class);
-
-	String conf = "";
-	this.init(conf);
+	Map<String, String> configMap = context.getConfigParams(this);
+	String conf = configMap.get(DBConfigFile);
+        String dbStore = configMap.get(GraphDBStore);
+	this.init(dbStore, conf);
     }
 
     /**
@@ -211,7 +219,7 @@
      */
     @Override
     public void dropTopology(Topology topology) {
-	topology = null;
+    // nothing to do
     }
 
     /**
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/CallerId.java b/src/main/java/net/onrc/onos/ofcontroller/util/CallerId.java
index 0607533..a0217d4 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/CallerId.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/CallerId.java
@@ -12,6 +12,15 @@
      * Default constructor.
      */
     public CallerId() {}
+    
+    /**
+     * Copy constructor
+     * @param otherCallerId
+     */
+    public CallerId(CallerId otherCallerId) {
+    // Note: make a full copy if we change value to a mutable type
+    value = otherCallerId.value;
+    }
 
     /**
      * Constructor from a string value.
@@ -49,4 +58,20 @@
     public String toString() {
 	return value;
     }
+    
+    @Override
+    public boolean equals(Object other) {
+    if (!(other instanceof CallerId)) {
+        return false;
+    }
+    
+    CallerId otherCallerId = (CallerId) other;
+    
+    return value.equals(otherCallerId.value);
+    }
+    
+    @Override
+    public int hashCode() {
+    return value.hashCode();
+    }
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/Dpid.java b/src/main/java/net/onrc/onos/ofcontroller/util/Dpid.java
index bd91daa..81223d2 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/Dpid.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/Dpid.java
@@ -13,7 +13,7 @@
 @JsonDeserialize(using=DpidDeserializer.class)
 @JsonSerialize(using=DpidSerializer.class)
 public class Dpid {
-    static public long UNKNOWN = 0;
+    static public final long UNKNOWN = 0;
 
     private long value;
 
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/serializers/KryoFactory.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/KryoFactory.java
index 1355fe0..5998dcd 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/serializers/KryoFactory.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/KryoFactory.java
@@ -4,7 +4,6 @@
 import java.util.TreeMap;
 
 import net.floodlightcontroller.util.MACAddress;
-import net.onrc.onos.ofcontroller.proxyarp.ArpMessage;
 import net.onrc.onos.ofcontroller.topology.TopologyElement;
 import net.onrc.onos.ofcontroller.util.CallerId;
 import net.onrc.onos.ofcontroller.util.DataPath;
@@ -31,7 +30,7 @@
 import net.onrc.onos.ofcontroller.util.Switch;
 import net.onrc.onos.ofcontroller.util.SwitchPort;
 
-import com.esotericsoftware.kryo2.Kryo;
+import com.esotericsoftware.kryo.Kryo;
 
 /**
  * Class factory for allocating Kryo instances for
@@ -152,9 +151,6 @@
 	kryo.register(TopologyElement.class);
 	kryo.register(TopologyElement.Type.class);
 	kryo.register(TreeMap.class);
-	
-	//ARP message
-	kryo.register(ArpMessage.class);
 
 	return kryo;
     }
diff --git a/src/main/protobuf/ramcloudgraph.proto b/src/main/protobuf/ramcloudgraph.proto
new file mode 100644
index 0000000..abd270d
--- /dev/null
+++ b/src/main/protobuf/ramcloudgraph.proto
@@ -0,0 +1,37 @@
+package RamCloudGraph;
+
+option java_package = "com.tinkerpop.blueprints.impls.ramcloud";
+option java_outer_classname = "RamCloudGraphProtos";
+
+message EdgeListProtoBuf {
+  repeated EdgeProtoBuf edge = 1;
+}
+
+message EdgeProtoBuf {
+  required uint64 neighborId = 1;
+  required bool outgoing = 2;
+  required string label = 3;
+}
+
+message PropertyListProtoBuf {
+  repeated PropertyProtoBuf property = 1;
+}
+
+message PropertyProtoBuf {
+  enum Type { STRING = 1; INT32 = 2; INT64 = 3; DOUBLE = 4; FLOAT = 5; BOOL = 6; }
+
+  required string key = 1;
+  
+  required Type value_type = 2;
+
+  optional string string_value = 3;
+  optional int32 int32_value = 4;
+  optional int64 int64_value = 5;
+  optional double double_value = 6;
+  optional float float_value = 7;
+  optional bool bool_value = 8;
+}
+
+message IndexBlob {
+  repeated int64 vertexId = 1;
+}
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 8034d44..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("/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 6f4f850..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java
+++ /dev/null
@@ -1,786 +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;
-    private GraphDBConnection mockConn = null;
-    private GraphDBOperation mockOpe = null;
-    ISwitchStorage swSt = null;
-    
-	@Before
-	public void setUp() throws Exception {
-		
-		swSt = new SwitchStorageImpl();
-		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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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(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 7edc1c5..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTestBB.java
+++ /dev/null
@@ -1,347 +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;
-    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";
-		
-		// 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(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/core/internal/TestableLinkStorageImpl.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableLinkStorageImpl.java
index ecba546..8411b22 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableLinkStorageImpl.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableLinkStorageImpl.java
@@ -2,7 +2,6 @@
 
 import java.util.Set;
 
-import net.onrc.onos.ofcontroller.core.internal.LinkStorageImpl;
 
 import com.thinkaurelius.titan.core.TitanGraph;
 import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
@@ -27,7 +26,7 @@
 	}
 	
 	@Override
-	public void init(String conf){
+	public void init(final String dbStore, final String conf){
         Set<String> s = graph.getIndexedKeys(Vertex.class);
         if (!s.contains("dpid")) {
            graph.createKeyIndex("dpid", Vertex.class);
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableSwitchStorageImpl.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableSwitchStorageImpl.java
index e0b34e1..82d1faf 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableSwitchStorageImpl.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableSwitchStorageImpl.java
@@ -18,9 +18,9 @@
 	}
 	
 	@Override
-	public void init(String conf){
+	public void init(final String dbStore, final String conf){
         
-		super.init(conf);
+		super.init(dbStore, conf);
 		
 	}
 }
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 44573bc..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTest.java
+++ /dev/null
@@ -1,519 +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;
-	DeviceStorageImpl deviceImpl;
-    private GraphDBConnection mockConn;
-    private GraphDBOperation mockOpe;
-    
-	@Before
-	public void setUp() throws Exception {
-	    deviceImpl = new DeviceStorageImpl();	
-		conf = "/dummy/path/to/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.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(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 9964ec3..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/devicemanager/internal/DeviceStorageImplTestBB.java
+++ /dev/null
@@ -1,672 +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;
-    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";
-		
-		// 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(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 b43ce1c..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/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 e054e05..0000000
--- a/src/test/java/net/onrc/onos/ofcontroller/topology/TopologyManagerTest.java
+++ /dev/null
@@ -1,241 +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.GraphDBConnection;
-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;
-    private GraphDBConnection conn = null;
-    private GraphDBOperation oper = null;
-    private TitanGraph titanGraph = null;
-    private TopologyManager topologyManager = null;
-
-    /**
-     * Setup the tests.
-     */
-    @Before
-    public void setUp() throws Exception {
-	conf = "/dummy/path/to/db";
-
-	//
-	// Make mock database.
-	// Replace TitanFactory.open() to return the mock database.
-	//
-	titanGraph = TestDatabaseManager.getTestDatabase();
-	PowerMock.mockStatic(TitanFactory.class);
-	EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
-	PowerMock.replay(TitanFactory.class);
-
-	// Create the connection to the database
-	conn = GraphDBConnection.getInstance(conf);
-	oper = new GraphDBOperation(conn);
-
-	// Populate the database
-	TestDatabaseManager.populateTestData(titanGraph);
-
-	// Prepare the 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);
-	}
-
-}
diff --git a/start-cassandra.sh b/start-cassandra.sh
index 426fa60..3e9a8d2 100755
--- a/start-cassandra.sh
+++ b/start-cassandra.sh
@@ -3,7 +3,7 @@
 # Set paths
 ONOS_HOME=`dirname $0`
 CASSANDRA_DIR=${HOME}/apache-cassandra-1.2.4
-LOGDIR=${ONOS_HOME}/ONOS/onos-logs
+LOGDIR=${ONOS_HOME}/onos-logs
 CASSANDRA_LOG=${LOGDIR}/cassandara.`hostname`.log
 
 function lotate {
diff --git a/start-onos-embedded.sh b/start-onos-embedded.sh
index 5202daf..7bd0b97 100755
--- a/start-onos-embedded.sh
+++ b/start-onos-embedded.sh
@@ -91,6 +91,7 @@
 <logger name="org" level="WARN"/>
 <logger name="LogService" level="WARN"/> <!-- Restlet access logging -->
 <logger name="net.floodlightcontroller.logging" level="WARN"/>
+<logger name="com.thinkaurelius.titan" level="INFO"/>
 
 <root level="DEBUG">
 <appender-ref ref="FILE" />
diff --git a/start-onos-jacoco.sh b/start-onos-jacoco.sh
index 2d1adf4..b721e9e 100755
--- a/start-onos-jacoco.sh
+++ b/start-onos-jacoco.sh
@@ -97,6 +97,7 @@
 <logger name="org" level="WARN"/>
 <logger name="LogService" level="WARN"/> <!-- Restlet access logging -->
 <logger name="net.floodlightcontroller.logging" level="WARN"/>
+<logger name="com.thinkaurelius.titan" level="INFO"/>
 
 <root level="DEBUG">
 <appender-ref ref="FILE" />
diff --git a/start-onos.sh b/start-onos.sh
index d8df237..f369cf2 100755
--- a/start-onos.sh
+++ b/start-onos.sh
@@ -1,4 +1,6 @@
 #!/bin/bash
+ulimit -c unlimited
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${HOME}/ramcloud/bindings/java/edu/stanford/ramcloud:${HOME}/ramcloud/obj.blueprint-java
 
 # Set paths
 ONOS_HOME="${ONOS_HOME:-`dirname $0`}"
@@ -19,8 +21,10 @@
 ## If you want JaCoCo Code Coverage reports... uncomment line below
 #JVM_OPTS="$JVM_OPTS -javaagent:${ONOS_HOME}/lib/jacocoagent.jar=dumponexit=true,output=file,destfile=${LOGDIR}/jacoco.exec"
 JVM_OPTS="$JVM_OPTS -server -d64"
+#JVM_OPTS="$JVM_OPTS -XX:+TieredCompilation -XX:InitialCodeCacheSize=512m -XX:ReservedCodeCacheSize=512m"
+JVM_OPTS="$JVM_OPTS -Xmx4g -Xms4g -Xmn800m"
 #JVM_OPTS="$JVM_OPTS -Xmx2g -Xms2g -Xmn800m"
-JVM_OPTS="$JVM_OPTS -Xmx1g -Xms1g -Xmn800m"
+#JVM_OPTS="$JVM_OPTS -Xmx1g -Xms1g -Xmn800m"
 #JVM_OPTS="$JVM_OPTS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
 JVM_OPTS="$JVM_OPTS -XX:+UseConcMarkSweepGC -XX:+UseAdaptiveSizePolicy -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
 JVM_OPTS="$JVM_OPTS -XX:MaxInlineSize=8192 -XX:FreqInlineSize=8192"
@@ -33,6 +37,9 @@
 		-XX:+UseCompressedOops \
 		-Dcom.sun.management.jmxremote.port=$JMX_PORT \
 		-Dcom.sun.management.jmxremote.ssl=false \
+                -Dbenchmark.measureBP=0 \
+                -Dbenchmark.measureRc=0 \
+                -Dbenchmark.measureONOS=0 \
 		-Dcom.sun.management.jmxremote.authenticate=false"
 JVM_OPTS="$JVM_OPTS -Dhazelcast.logging.type=slf4j"
 
@@ -96,6 +103,7 @@
 <logger name="org" level="WARN"/>
 <logger name="LogService" level="WARN"/> <!-- Restlet access logging -->
 <logger name="net.floodlightcontroller.logging" level="WARN"/>
+<logger name="com.thinkaurelius.titan" level="INFO"/>
 
 <root level="DEBUG">
 <appender-ref ref="FILE" />
@@ -163,7 +171,7 @@
 case "$1" in
   start)
     stop
-    check_db
+#    check_db
     start
     ;;
   startnokill)
diff --git a/start-ramcloud-coordinator.sh b/start-ramcloud-coordinator.sh
new file mode 100755
index 0000000..6a4232e
--- /dev/null
+++ b/start-ramcloud-coordinator.sh
@@ -0,0 +1,81 @@
+#!/bin/bash
+
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${HOME}/ramcloud/bindings/java/edu/stanford/ramcloud:${HOME}/ramcloud/obj.blueprint-java
+
+# Set paths
+ONOS_HOME=`dirname $0`
+RAMCLOUD_DIR=${HOME}/ramcloud
+LOGDIR=${ONOS_HOME}/onos-logs
+RAMCLOUD_LOG=${LOGDIR}/ramcloud.coordinator.`hostname`.log
+coordinatorip=`grep coordinatorIp ${ONOS_HOME}/conf/ramcloud.conf | cut -d "=" -f 2,3`
+coordinatorport=`grep coordinatorPort ${ONOS_HOME}/conf/ramcloud.conf | cut -d "=" -f 2,3`
+RAMCLOUD_COORDINATOR=`echo $coordinatorip","$coordinatorport`
+
+function lotate {
+    logfile=$1
+    nr_max=${2:-10}
+    if [ -f $logfile ]; then
+	for i in `seq $(expr $nr_max - 1) -1 1`; do
+	    if [ -f ${logfile}.${i} ]; then
+		mv -f ${logfile}.${i} ${logfile}.`expr $i + 1`
+	    fi
+	done
+	mv $logfile $logfile.1
+    fi
+}
+
+function start {
+  if [ ! -d ${LOGDIR} ]; then
+    mkdir -p ${LOGDIR}
+  fi
+  echo "rotate log: $log"
+  if [ -f $RAMCLOUD_LOG ]; then
+    lotate $RAMCLOUD_LOG
+  fi
+
+  # Run ramcloud 
+  echo "Starting ramcloud coordinator"
+  $RAMCLOUD_DIR/obj.blueprint-java/coordinator  -L $RAMCLOUD_COORDINATOR > $RAMCLOUD_LOG 2>&1 &
+}
+
+function stop {
+  # Kill the existing processes
+  capid=`pgrep coordinator | awk '{print $1}'`
+  pids="$capid"
+  for p in ${pids}; do
+    if [ x$p != "x" ]; then
+      kill -KILL $p
+      echo "Killed existing prosess (pid: $p)"
+    fi
+  done
+}
+
+function deldb {
+#   # Delete the berkeley db database
+   if [ -d "/tmp/ramcloud.conf" ]; then
+      echo "deleting berkeley db dir"
+      sudo rm -rf /tmp/ramcloud.conf
+   fi
+}
+
+case "$1" in
+  start)
+    deldb
+    cp $ONOS_HOME/conf/ramcloud.conf /tmp
+    stop
+    start 
+    ;;
+  stop)
+    stop
+    ;;
+#  deldb)
+#    deldb
+#    ;;
+  status)
+    n=`pgrep -f obj.blueprint-java/coordinator | wc -l`
+    echo "$n ramcloud coordinator is running"
+    ;;
+  *)
+    echo "Usage: $0 {start|stop|restart|status}"
+    exit 1
+esac
diff --git a/start-ramcloud-server.sh b/start-ramcloud-server.sh
new file mode 100755
index 0000000..a644837
--- /dev/null
+++ b/start-ramcloud-server.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+
+ulimit -c unlimited
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${HOME}/ramcloud/bindings/java/edu/stanford/ramcloud:${HOME}/ramcloud/obj.blueprint-java
+
+# Set paths
+ONOS_HOME=`dirname $0`
+RAMCLOUD_DIR=${HOME}/ramcloud
+LOGDIR=${ONOS_HOME}/onos-logs
+RAMCLOUD_LOG=${LOGDIR}/ramcloud.server.`hostname`.log
+coordinatorip=`grep coordinatorIp ${ONOS_HOME}/conf/ramcloud.conf | cut -d "=" -f 2,3`
+coordinatorport=`grep coordinatorPort ${ONOS_HOME}/conf/ramcloud.conf | cut -d "=" -f 2,3`
+RAMCLOUD_COORDINATOR=`echo $coordinatorip","$coordinatorport`
+serverip=`grep serverIp ${ONOS_HOME}/conf/ramcloud.conf | cut -d "=" -f 2,3`
+serverport=`grep serverPort ${ONOS_HOME}/conf/ramcloud.conf | cut -d "=" -f 2,3`
+RAMCLOUD_SERVER=`echo $serverip","$serverport`
+
+function lotate {
+    logfile=$1
+    nr_max=${2:-10}
+    if [ -f $logfile ]; then
+	for i in `seq $(expr $nr_max - 1) -1 1`; do
+	    if [ -f ${logfile}.${i} ]; then
+		mv -f ${logfile}.${i} ${logfile}.`expr $i + 1`
+	    fi
+	done
+	mv $logfile $logfile.1
+    fi
+}
+
+function start {
+  if [ ! -d ${LOGDIR} ]; then
+    mkdir -p ${LOGDIR}
+  fi
+  echo "rotate log: $log"
+  if [ -f $RAMCLOUD_LOG ]; then
+    lotate $RAMCLOUD_LOG
+  fi
+
+  # Run ramcloud 
+  echo "Starting ramcloud"
+  $RAMCLOUD_DIR/obj.blueprint-java/server -M -L $RAMCLOUD_SERVER -C $RAMCLOUD_COORDINATOR --detectFailures 0 > $RAMCLOUD_LOG 2>&1 &
+}
+
+function stop {
+  # Kill the existing processes
+  capid=`pgrep -f obj.blueprint-java/server | awk '{print $1}'`
+  pids="$capid"
+  for p in ${pids}; do
+    if [ x$p != "x" ]; then
+      kill -KILL $p
+      echo "Killed existing prosess (pid: $p)"
+    fi
+  done
+}
+
+function deldb {
+#   # Delete the berkeley db database
+   if [ -d "/tmp/ramcloud.conf" ]; then
+      echo "deleting berkeley db dir"
+      sudo rm -rf /tmp/ramcloud.conf
+   fi
+}
+
+case "$1" in
+  start)
+    deldb
+    cp $ONOS_HOME/conf/ramcloud.conf /tmp
+    stop
+    start 
+    ;;
+  stop)
+    stop
+    ;;
+#  deldb)
+#    deldb
+#    ;;
+  status)
+    n=`pgrep -f obj.blueprint-java/server | wc -l`
+    echo "$n ramcloud server running"
+    ;;
+  *)
+    echo "Usage: $0 {start|stop|restart|status}"
+    exit 1
+esac
diff --git a/start-rest.sh b/start-rest.sh
index 910eb41..94bbd46 100755
--- a/start-rest.sh
+++ b/start-rest.sh
@@ -57,6 +57,10 @@
 function start {
     lotate $REST_LOG 10 
     cd $WEBDIR
+    # Make log dir for iperf log files
+    if [ ! -d  log ]; then
+      mkdir log
+    fi
     $restscript > $REST_LOG 2>&1 &
 }
 
diff --git a/test-network/mininet/dev_network_edge.py b/test-network/mininet/dev_network_edge.py
index 29be6ad..acc5d0d 100755
--- a/test-network/mininet/dev_network_edge.py
+++ b/test-network/mininet/dev_network_edge.py
@@ -113,7 +113,6 @@
     #  controllers.append(rc)
 
     #net.controllers=controllers
-    net.build()
 
     host = []
     for i in range (NR_NODES):
diff --git a/test-network/mininet/dev_network_edge_2.py b/test-network/mininet/dev_network_edge_2.py
index 50dc00c..553b376 100755
--- a/test-network/mininet/dev_network_edge_2.py
+++ b/test-network/mininet/dev_network_edge_2.py
@@ -113,7 +113,6 @@
     #  controllers.append(rc)
 
     #net.controllers=controllers
-    net.build()
 
     host = []
     for i in range (NR_NODES):
diff --git a/web/js/onos-topology.js b/web/js/onos-topology.js
index 3772127..d086f6a 100644
--- a/web/js/onos-topology.js
+++ b/web/js/onos-topology.js
@@ -222,8 +222,23 @@
 	return changed
     }
 
+    function nr_active_sw(){
+        var n=0; 
+        var nodes = force.nodes();
+        for(var i=0;i<nodes.length;i++){
+          if(nodes[i].group!=0)
+            n++;
+        }; 
+        return n;
+    }
+
     function draw(force, path, circle, text){
 	force.stop();
+        svg.append("svg:text")
+	    .attr("x", 50)
+	    .attr("y", 20)
+            .text(function(){return "Switch: " + force.nodes().length + " (Active: " + nr_active_sw()  + ")/ Link: " + force.links().length});
+
         path.enter().append("svg:path")
 	    .attr("class", function(d) { return "link"; })
 	    .attr("marker-end", function(d) {
diff --git a/web/onos-topology.html b/web/onos-topology.html
index 5834521..b4e5097 100644
--- a/web/onos-topology.html
+++ b/web/onos-topology.html
@@ -43,7 +43,7 @@
       <path d="M0,-5L10,0L0,5" fill="red" stroke="red"/>
     </marker>
   </defs>
-<h1>ONOS Sprint 4 Demo GUI</h1>
+<h1>ONOS Simple Topology GUI</h1>
 <h2>Controller Status</h2>
 <div id="servers"></div>
 <div id="onos-status"></div>
diff --git a/web/topology_rest.py b/web/topology_rest.py
index 38dba5d..0b0ab01 100755
--- a/web/topology_rest.py
+++ b/web/topology_rest.py
@@ -8,8 +8,8 @@
 import io
 import time
 import random
-
 import re
+from urllib2 import Request, urlopen, URLError, HTTPError
 
 from flask import Flask, json, Response, render_template, make_response, request
 
@@ -114,132 +114,131 @@
 ## Proxy ##
 @app.route("/proxy/gui/link/<cmd>/<src_dpid>/<src_port>/<dst_dpid>/<dst_port>")
 def proxy_link_change(cmd, src_dpid, src_port, dst_dpid, dst_port):
+  url = "%s/gui/link/%s/%s/%s/%s/%s" % (ONOS_GUI3_CONTROL_HOST, cmd, src_dpid, src_port, dst_dpid, dst_port)
   try:
-    command = "curl -s %s/gui/link/%s/%s/%s/%s/%s" % (ONOS_GUI3_CONTROL_HOST, cmd, src_dpid, src_port, dst_dpid, dst_port)
-    print command
-    result = os.popen(command).read()
+    response = urlopen(url)
+    result = response.read()
   except:
-    print "REST IF has issue"
-    exit
+    result = ""
+    print "REST IF has issue %s" % url
 
   resp = Response(result, status=200, mimetype='application/json')
   return resp
 
 @app.route("/proxy/gui/switchctrl/<cmd>")
 def proxy_switch_controller_setting(cmd):
+  url = "%s/gui/switchctrl/%s" % (ONOS_GUI3_CONTROL_HOST, cmd)
   try:
-    command = "curl -s %s/gui/switchctrl/%s" % (ONOS_GUI3_CONTROL_HOST, cmd)
-    print command
-    result = os.popen(command).read()
+    response = urlopen(url)
+    result = response.read()
   except:
-    print "REST IF has issue"
-    exit
+    result = ""
+    print "REST IF has issue %s" % url
 
   resp = Response(result, status=200, mimetype='application/json')
   return resp
 
 @app.route("/proxy/gui/switch/<cmd>/<dpid>")
 def proxy_switch_status_change(cmd, dpid):
+  url = "%s/gui/switch/%s/%s" % (ONOS_GUI3_CONTROL_HOST, cmd, dpid)
   try:
-    command = "curl -s %s/gui/switch/%s/%s" % (ONOS_GUI3_CONTROL_HOST, cmd, dpid)
-    print command
-    result = os.popen(command).read()
+    response = urlopen(url)
+    result = response.read()
   except:
-    print "REST IF has issue"
-    exit
+    result = ""
+    print "REST IF has issue %s" % url
 
   resp = Response(result, status=200, mimetype='application/json')
   return resp
 
 @app.route("/proxy/gui/controller/<cmd>/<controller_name>")
 def proxy_controller_status_change(cmd, controller_name):
+  url = "%s/gui/controller/%s/%s" % (ONOS_GUI3_CONTROL_HOST, cmd, controller_name)
   try:
-    command = "curl -s %s/gui/controller/%s/%s" % (ONOS_GUI3_CONTROL_HOST, cmd, controller_name)
-    print command
-    result = os.popen(command).read()
+    response = urlopen(url)
+    result = response.read()
   except:
-    print "REST IF has issue"
-    exit
-
+    result = ""
+    print "REST IF has issue %s" % url
+ 
   resp = Response(result, status=200, mimetype='application/json')
   return resp
 
 @app.route("/proxy/gui/addflow/<src_dpid>/<src_port>/<dst_dpid>/<dst_port>/<srcMAC>/<dstMAC>")
 def proxy_add_flow(src_dpid, src_port, dst_dpid, dst_port, srcMAC, dstMAC):
   try:
-    command = "curl -s %s/gui/addflow/%s/%s/%s/%s/%s/%s" % (ONOS_GUI3_CONTROL_HOST, src_dpid, src_port, dst_dpid, dst_port, srcMAC, dstMAC)
-    print command
-    result = os.popen(command).read()
+    url = "%s/gui/addflow/%s/%s/%s/%s/%s/%s" % (ONOS_GUI3_CONTROL_HOST, src_dpid, src_port, dst_dpid, dst_port, srcMAC, dstMAC)
+    #print "proxy gui addflow " + url
+    (code, result) = get_json(url)
   except:
-    print "REST IF has issue"
-    exit
+    print "REST IF has issue %s" % url
+    print "Result %s" % result
+    exit()
 
   resp = Response(result, status=200, mimetype='application/json')
   return resp
 
 @app.route("/proxy/gui/delflow/<flow_id>")
 def proxy_del_flow(flow_id):
+  url = "%s/gui/delflow/%s" % (ONOS_GUI3_CONTROL_HOST, flow_id)
   try:
-    command = "curl -s %s/gui/delflow/%s" % (ONOS_GUI3_CONTROL_HOST, flow_id)
-    print command
-    result = os.popen(command).read()
+    response = urlopen(url)
+    result = response.read()
   except:
-    print "REST IF has issue"
-    exit
+    result = ""
+    print "REST IF has issue %s" % url
 
   resp = Response(result, status=200, mimetype='application/json')
   return resp
 
 @app.route("/proxy/gui/iperf/start/<flow_id>/<duration>/<samples>")
 def proxy_iperf_start(flow_id,duration,samples):
+  url = "%s/gui/iperf/start/%s/%s/%s" % (ONOS_GUI3_CONTROL_HOST, flow_id, duration, samples)
   try:
-    command = "curl -m 40 -s %s/gui/iperf/start/%s/%s/%s" % (ONOS_GUI3_CONTROL_HOST, flow_id, duration, samples)
-    print command
-    result = os.popen(command).read()
+    response = urlopen(url)
+    result = response.read()
   except:
-    print "REST IF has issue"
-    exit
+    result = ""
+    print "REST IF has issue %s" % url
 
   resp = Response(result, status=200, mimetype='application/json')
   return resp
 
 @app.route("/proxy/gui/iperf/rate/<flow_id>")
 def proxy_iperf_rate(flow_id):
+  url = "%s/gui/iperf/rate/%s" % (ONOS_GUI3_CONTROL_HOST, flow_id)
   try:
-    command = "curl -s %s/gui/iperf/rate/%s" % (ONOS_GUI3_CONTROL_HOST, flow_id)
-    print command
-    result = os.popen(command).read()
+    response = urlopen(url)
+    result = response.read()
   except:
-    print "REST IF has issue"
-    exit
+    result = ""
+    print "REST IF has issue %s" % url
 
   resp = Response(result, status=200, mimetype='application/json')
   return resp
 
 @app.route("/proxy/gui/reset")
 def proxy_gui_reset():
-  result = ""
+  url = "%s/gui/reset" % (ONOS_GUI3_CONTROL_HOST)
   try:
-    command = "curl -m 300 -s %s/gui/reset" % (ONOS_GUI3_CONTROL_HOST)
-    print command
-    result = os.popen(command).read()
+    response = urlopen(url)
+    result = response.read()
   except:
-    print "REST IF has issue"
-    exit
+    result = ""
+    print "REST IF has issue %s" % url
 
   resp = Response(result, status=200, mimetype='application/json')
   return resp
 
 @app.route("/proxy/gui/scale")
 def proxy_gui_scale():
-  result = ""
+  url = "%s/gui/scale" % (ONOS_GUI3_CONTROL_HOST)
   try:
-    command = "curl -m 300 -s %s/gui/scale" % (ONOS_GUI3_CONTROL_HOST)
-    print command
-    result = os.popen(command).read()
+    response = urlopen(url)
+    result = response.read()
   except:
-    print "REST IF has issue"
-    exit
+    result = ""
+    print "REST IF has issue %s" % url
 
   resp = Response(result, status=200, mimetype='application/json')
   return resp
@@ -247,19 +246,20 @@
 ###### ONOS REST API ##############################
 ## Worker Func ###
 def get_json(url):
-  code = 200
+  code = 200;
   try:
-    command = "curl -m 60 -s %s" % (url)
-    result = os.popen(command).read()
-    parsedResult = json.loads(result)
-    if type(parsedResult) == 'dict' and parsedResult.has_key('code'):
-      print "REST %s returned code %s" % (command, parsedResult['code'])
-      code=500
-  except:
-    print "REST IF %s has issue" % command
+    response = urlopen(url)
+  except URLError, e:
+    print "get_json: REST IF %s has issue. Reason: %s" % (url, e.reason)
     result = ""
-    code = 500
+    return (500, result)
+  except HTTPError, e:
+    print "get_json: REST IF %s has issue. Code %s" % (url, e.code)
+    result = ""
+    return (e.code, result)
 
+  result = response.read()
+#  parsedResult = json.loads(result)
   return (code, result)
 
 def pick_host():
@@ -354,14 +354,13 @@
 @app.route('/topology', methods=['GET'])
 def topology_for_gui():
   try:
-    command = "curl -s \'http://%s:%s/wm/onos/topology/switches/all/json\'" % (RestIP, RestPort)
-    result = os.popen(command).read()
+    url="http://%s:%s/wm/onos/topology/switches/all/json" % (RestIP, RestPort)
+    (code, result) = get_json(url)
     parsedResult = json.loads(result)
   except:
-    log_error("REST IF has issue: %s" % command)
+    log_error("REST IF has issue: %s" % url)
     log_error("%s" % result)
     return
-#    sys.exit(0)
 
   topo = {}
   switches = []
@@ -382,11 +381,11 @@
       switches.append(sw)
 
   try:
-    command = "curl -s \'http://%s:%s/wm/onos/registry/switches/json\'" % (RestIP, RestPort)
-    result = os.popen(command).read()
+    url="http://%s:%s/wm/onos/registry/switches/json" % (RestIP, RestPort)
+    (code, result) = get_json(url)
     parsedResult = json.loads(result)
   except:
-    log_error("REST IF has issue: %s" % command)
+    log_error("REST IF has issue: %s" % url)
     log_error("%s" % result)
 
   for key in parsedResult:
@@ -397,35 +396,12 @@
       if switches[sw_id]['group'] != 0:
         switches[sw_id]['group'] = controllers.index(ctrl) + 1
 
-#  try:
-#    v1 = "00:00:00:00:00:0a:0d:00"
-#    v1 = "00:00:00:00:00:0d:00:d1"
-#    p1=1
-#    v2 = "00:00:00:00:00:0b:0d:03"
-#    v2 = "00:00:00:00:00:0d:00:d3"
-#    p2=1
-#    command = "curl -s http://%s:%s/wm/onos/topology/route/%s/%s/%s/%s/json" % (RestIP, RestPort, v1, p1, v2, p2)
-#    result = os.popen(command).read()
-#    parsedResult = json.loads(result)
-#  except:
-#    log_error("No route")
-#    parsedResult = {}
-
-  #path = []
-  #if parsedResult.has_key('flowEntries'):
-  #  flowEntries= parsedResult['flowEntries']
-  #  for i, v in enumerate(flowEntries):
-  #    if i < len(flowEntries) - 1:
-  #      sdpid= flowEntries[i]['dpid']['value']
-  #      ddpid = flowEntries[i+1]['dpid']['value']
-  #      path.append( (sdpid, ddpid))
-
   try:
-    command = "curl -s \'http://%s:%s/wm/onos/topology/links/json\'" % (RestIP, RestPort)
-    result = os.popen(command).read()
+    url = "http://%s:%s/wm/onos/topology/links/json" % (RestIP, RestPort)
+    (code, result) = get_json(url)
     parsedResult = json.loads(result)
   except:
-    log_error("REST IF has issue: %s" % command)
+    log_error("REST IF has issue: %s" % url)
     log_error("%s" % result)
     return
 #    sys.exit(0)
@@ -457,19 +433,16 @@
   resp = Response(js, status=200, mimetype='application/json')
   return resp
 
-#@app.route("/wm/floodlight/topology/toporoute/00:00:00:00:00:a1/2/00:00:00:00:00:c1/3/json")
-#@app.route("/wm/floodlight/topology/toporoute/<srcdpid>/<srcport>/<destdpid>/<destport>/json")
 @app.route("/wm/floodlight/topology/toporoute/<v1>/<p1>/<v2>/<p2>/json")
 def shortest_path(v1, p1, v2, p2):
   try:
-    command = "curl -s \'http://%s:%s/wm/onos/topology/switches/all/json\'" % (RestIP, RestPort)
-    result = os.popen(command).read()
+    url = "http://%s:%s/wm/onos/topology/switches/all/json" % (RestIP, RestPort)
+    (code, result) = get_json(url)
     parsedResult = json.loads(result)
   except:
     log_error("REST IF has issue: %s" % command)
     log_error("%s" % result)
     return
-#    sys.exit(0)
 
   topo = {}
   switches = []
@@ -494,30 +467,28 @@
       switches.append(sw)
 
   try:
-    command = "curl -s http://%s:%s/wm/onos/topology/route/%s/%s/%s/%s/json" % (RestIP, RestPort, v1, p1, v2, p2)
-    result = os.popen(command).read()
+    url = "http://%s:%s/wm/onos/topology/route/%s/%s/%s/%s/json" % (RestIP, RestPort, v1, p1, v2, p2)
+    (code, result) = get_json(url)
     parsedResult = json.loads(result)
   except:
     log_error("No route")
     parsedResult = []
-#    exit(1)
 
   path = [];
   for i, v in enumerate(parsedResult):
     if i < len(parsedResult) - 1:
-      sdpid= parsedResult[i]['switch']
-      ddpid = parsedResult[i+1]['switch']
+      sdpid= parsedResult['flowEntries'][i]['dpid']['value']
+      ddpid= parsedResult['flowEntries'][i+1]['dpid']['value']
       path.append( (sdpid, ddpid))
 
   try:
-    command = "curl -s \'http://%s:%s/wm/onos/topology/links/json\'" % (RestIP, RestPort)
-    result = os.popen(command).read()
+    url = "http://%s:%s/wm/onos/topology/links/json" % (RestIP, RestPort)
+    (code, result) = get_json(url)
     parsedResult = json.loads(result)
   except:
     log_error("REST IF has issue: %s" % command)
     log_error("%s" % result)
     return
-#    sys.exit(0)
 
   for v in parsedResult:
     link = {}
@@ -548,13 +519,11 @@
 @app.route("/wm/floodlight/core/controller/switches/json")
 def query_switch():
   try:
-    command = "curl -s \'http://%s:%s/wm/onos/topology/switches/all/json\'" % (RestIP, RestPort)
-#    http://localhost:8080/wm/onos/topology/switches/active/json
-    print command
-    result = os.popen(command).read()
+    url = "http://%s:%s/wm/onos/topology/switches/all/json" % (RestIP, RestPort)
+    (code, result) = get_json(url)
     parsedResult = json.loads(result)
   except:
-    log_error("REST IF has issue: %s" % command)
+    log_error("REST IF has issue: %s" % url)
     log_error("%s" % result)
     return
 #    sys.exit(0)
@@ -577,49 +546,6 @@
   resp = Response(js, status=200, mimetype='application/json')
   return resp
 
-@app.route("/wm/floodlight/device/")
-def devices():
-  try:
-    command = "curl -s http://%s:%s/graphs/%s/vertices\?key=type\&value=device" % (RestIP, RestPort, DBName)
-    result = os.popen(command).read()
-    parsedResult = json.loads(result)['results']
-  except:
-    log_error("REST IF has issue: %s" % command)
-    log_error("%s" % result)
-    return
-#    sys.exit(0)
-
-  devices = []
-  for v in parsedResult:
-    dl_addr = v['dl_addr']
-    nw_addr = v['nw_addr']
-    vertex = v['_id']
-    mac = []
-    mac.append(dl_addr)
-    ip = []
-    ip.append(nw_addr)
-    device = {}
-    device['entryClass']="DefaultEntryClass"
-    device['mac']=mac
-    device['ipv4']=ip
-    device['vlan']=[]
-    device['lastSeen']=0
-    attachpoints =[]
-
-    port, dpid = deviceV_to_attachpoint(vertex)
-    attachpoint = {}
-    attachpoint['port']=port
-    attachpoint['switchDPID']=dpid
-    attachpoints.append(attachpoint)
-    device['attachmentPoint']=attachpoints
-    devices.append(device)
-
-  js = json.dumps(devices)
-  resp = Response(js, status=200, mimetype='application/json')
-  return resp
-
-#{"entityClass":"DefaultEntityClass","mac":["7c:d1:c3:e0:8c:a3"],"ipv4":["192.168.2.102","10.1.10.35"],"vlan":[],"attachmentPoint":[{"port":13,"switchDPID":"00:01:00:12:e2:78:32:44","errorStatus":null}],"lastSeen":1357333593496}
-
 ## return fake stat for now
 @app.route("/wm/floodlight/core/switch/<switchId>/<statType>/json")
 def switch_stat(switchId, statType):
@@ -638,68 +564,19 @@
     resp = Response(js, status=200, mimetype='application/json')
     return resp
 
-
-@app.route("/wm/onos/linkdiscovery/links/json")
-def query_links():
-  try:
-    command = 'curl -s http://%s:%s/graphs/%s/vertices?key=type\&value=port' % (RestIP, RestPort, DBName)
-    print command
-    result = os.popen(command).read()
-    parsedResult = json.loads(result)['results']
-  except:
-    log_error("REST IF has issue: %s" % command)
-    log_error("%s" % result)
-    return
-#    sys.exit(0)
-
-  debug("query_links %s" % command)
-#  pp.pprint(parsedResult)
-  sport = []
-  links = []
-  for v in parsedResult:
-    srcport = v['_id']
-    try:
-      command = "curl -s http://%s:%s/graphs/%s/vertices/%d/out?_label=link" % (RestIP, RestPort, DBName, srcport)
-      print command
-      result = os.popen(command).read()
-      linkResults = json.loads(result)['results']
-    except:
-      log_error("REST IF has issue: %s" % command)
-      log_error("%s" % result)
-      return
-#      sys.exit(0)
-
-    for p in linkResults:
-      if p.has_key('type') and p['type'] == "port":
-        dstport = p['_id']
-        (sport, sdpid) = portV_to_port_dpid(srcport)
-        (dport, ddpid) = portV_to_port_dpid(dstport)
-        link = {}
-        link["src-switch"]=sdpid
-        link["src-port"]=sport
-        link["src-port-state"]=0
-        link["dst-switch"]=ddpid
-        link["dst-port"]=dport
-        link["dst-port-state"]=0
-        link["type"]="internal"
-        links.append(link)
-
-#  pp.pprint(links)
-  js = json.dumps(links)
-  resp = Response(js, status=200, mimetype='application/json')
-  return resp
-
 @app.route("/controller_status")
 def controller_status():
-#  onos_check="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-onos.sh status | awk '{print $1}'"
-  onos_check="cd; onos status | grep %s | awk '{print $2}'"
-  #cassandra_check="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-cassandra.sh status"
+  url= "http://%s:%d/wm/onos/registry/controllers/json" % (RestIP, RestPort)
+  (code, result) = get_json(url)
+  parsedResult = json.loads(result)
 
   cont_status=[]
   for i in controllers:
     status={}
-    onos=os.popen(onos_check % i).read()[:-1]
-#    onos=os.popen(onos_check % (i, i.lower())).read()[:-1]
+    if i in parsedResult:
+      onos=1
+    else:
+      onos=0
     status["name"]=i
     status["onos"]=onos
     status["cassandra"]=0
@@ -709,6 +586,7 @@
   resp = Response(js, status=200, mimetype='application/json')
   return resp
 
+
 ### Command ###
 @app.route("/gui/controller/<cmd>/<controller_name>")
 def controller_status_change(cmd, controller_name):
@@ -989,17 +867,16 @@
 #http://localhost:9000/gui/iperf/start/<flow_id>/<duration>
 @app.route("/gui/iperf/start/<flow_id>/<duration>/<samples>")
 def iperf_start(flow_id,duration,samples):
+  url = "http://%s:%s/wm/onos/flows/get/%s/json" % (RestIP, RestPort, flow_id)
   try:
-    command = "curl -s \'http://%s:%s/wm/onos/flows/get/%s/json\'" % (RestIP, RestPort, flow_id)
-    print command
-    result = os.popen(command).read()
+    response = urlopen(url)
+    result = response.read()
     if len(result) == 0:
       print "No Flow found"
       return "Flow %s not found" % (flow_id);
   except:
-    print "REST IF has issue"
-    return "REST IF has issue"
-    exit
+    print "REST IF has issue %s" % url
+    return "REST IF has issue %s" % url
 
   parsedResult = json.loads(result)
 
@@ -1054,15 +931,14 @@
 #http://localhost:9000/gui/iperf/rate/<flow_id>
 @app.route("/gui/iperf/rate/<flow_id>")
 def iperf_rate(flow_id):
+  url = "http://%s:%s/wm/onos/flows/get/%s/json" % (RestIP, RestPort, flow_id)
   try:
-    command = "curl -s \'http://%s:%s/wm/onos/flows/get/%s/json\'" % (RestIP, RestPort, flow_id)
-    print command
-    result = os.popen(command).read()
+    response = urlopen(url)
+    result = response.read()
     if len(result) == 0:
-      resp = Response(result, status=400, mimetype='text/html')
-      return "no such iperf flow (flowid %s)" % flow_id;
+      return "no such iperf flow (flowid %s)" % flow_id
   except:
-    print "REST IF has issue"
+    print "REST IF has issue %s" % url
     exit
 
   parsedResult = json.loads(result)
@@ -1082,12 +958,13 @@
     else:
       host = controllers[hostid-1]
 
+  url="http://%s:%s/log/iperfsvr_%s.out" % (host, 9000, flow_id)
   try:
-    command = "curl -s http://%s:%s/log/iperfsvr_%s.out" % (host, 9000, flow_id)
-    print command
-    result = os.popen(command).read()
+    response = urlopen(url)
+    result = response.read()
   except:
-    exit
+    print "REST IF has issue %s" % url
+    return 
 
   if re.match("Cannot", result):
     resp = Response(result, status=400, mimetype='text/html')
@@ -1101,25 +978,24 @@
   read_config()
   read_link_def()
   if len(sys.argv) > 1 and sys.argv[1] == "-d":
-#      add_flow("00:00:00:00:00:00:02:02", 1, "00:00:00:00:00:00:03:02", 1, "00:00:00:00:02:02", "00:00:00:00:03:0c")
-#     link_change("up", "00:00:00:00:ba:5e:ba:11", 1, "00:00:00:00:00:00:00:00", 1)
-#     link_change("down", "00:00:20:4e:7f:51:8a:35", 1, "00:00:00:00:00:00:00:00", 1)
-#     link_change("up", "00:00:00:00:00:00:02:03", 1, "00:00:00:00:00:00:00:00", 1)
-#     link_change("down", "00:00:00:00:00:00:07:12", 1, "00:00:00:00:00:00:00:00", 1)
-#    print "-- query all switches --"
-#    query_switch()
-#    print "-- query topo --"
-#    topology_for_gui()
-#    link_change(1,2,3,4)
-    print "-- query all links --"
-#    query_links()
-#    print "-- query all devices --"
-#    devices()
-#    iperf_start(1,10,15)
-#    iperf_rate(1)
-#    switches()
-#    add_flow(1,2,3,4,5,6)
-    reset_demo()
+    # for debugging
+    #add_flow("00:00:00:00:00:00:02:02", 1, "00:00:00:00:00:00:03:02", 1, "00:00:00:00:02:02", "00:00:00:00:03:0c")
+    #proxy_link_change("up", "00:00:00:00:ba:5e:ba:11", 1, "00:00:00:00:00:00:00:00", 1)
+    #proxy_link_change("down", "00:00:20:4e:7f:51:8a:35", 1, "00:00:00:00:00:00:00:00", 1)
+    #proxy_link_change("up", "00:00:00:00:00:00:02:03", 1, "00:00:00:00:00:00:00:00", 1)
+    #proxy_link_change("down", "00:00:00:00:00:00:07:12", 1, "00:00:00:00:00:00:00:00", 1)
+    #print "-- query all switches --"
+    #query_switch()
+    #print "-- query topo --"
+    #topology_for_gui()
+    ##print "-- query all links --"
+    ##query_links()
+    #print "-- query all devices --"
+    #devices()
+    #links()
+    #switches()
+    #reset_demo()
+    pass
   else:
     app.debug = True
     app.run(threaded=True, host="0.0.0.0", port=9000)