Merge blueprints-ramcloud-graph into ONOS code
diff --git a/.gitignore b/.gitignore
index 88f7bb1..86be6a7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,4 @@
 repo
 logback.*.xml
 
+/.m2/
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index ce582d0..c1fa36b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -312,6 +312,21 @@
       <version>2.4.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>
@@ -476,11 +491,11 @@
       <artifactId>packetstreamer-thrift</artifactId>
       <version>0.1.0</version>
     </dependency>
-    -->
     <dependency>
       <groupId>com.tinkerpop.blueprints.impls.ramcloud</groupId>
       <artifactId>blueprints-ramcloud-graph</artifactId>
       <version>2.5.0</version>
     </dependency>
+    -->
   </dependencies>
 </project>
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..66cf8ea
--- /dev/null
+++ b/src/apps/java/com/tinkerpop/blueprints/impls/ramcloud/FurnaceExamples.java
@@ -0,0 +1,57 @@
+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..86631b1
--- /dev/null
+++ b/src/apps/java/com/tinkerpop/blueprints/impls/ramcloud/JUNGExamples.java
@@ -0,0 +1,89 @@
+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..d61c2a4
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudEdge.java
@@ -0,0 +1,222 @@
+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..15ec580
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudElement.java
@@ -0,0 +1,300 @@
+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.kryo2.Kryo;
+import com.esotericsoftware.kryo2.io.ByteBufferInput;
+import com.esotericsoftware.kryo2.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..8247bc8
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudGraph.java
@@ -0,0 +1,710 @@
+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..075c749
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudIndex.java
@@ -0,0 +1,535 @@
+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..d19b7e5
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudKeyIndex.java
@@ -0,0 +1,52 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+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..9597f7e
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudVertex.java
@@ -0,0 +1,498 @@
+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..270ad5c
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/Versioned.java
@@ -0,0 +1,26 @@
+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..08fe9f2
--- /dev/null
+++ b/src/main/java/com/tinkerpop/rexster/config/RamCloudGraphConfiguration.java
@@ -0,0 +1,15 @@
+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/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/start-ramcloud-coordinator.sh b/start-ramcloud-coordinator.sh
new file mode 100755
index 0000000..bba962a
--- /dev/null
+++ b/start-ramcloud-coordinator.sh
@@ -0,0 +1,86 @@
+#!/bin/bash
+
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${HOME}/ramcloud/bindings/java/edu/stanford/ramcloud:${HOME}/ramcloud/obj.blueprint-java
+
+function host2ip (){
+   ip=`egrep "$1\$" /etc/hosts |grep -v "ip6"|  awk '{print $1}'`
+   echo $ip
+}
+
+# Set paths
+ONOS_HOME=`dirname $0`
+RAMCLOUD_DIR=${HOME}/ramcloud
+LOGDIR=${ONOS_HOME}/onos-logs
+RAMCLOUD_LOG=${LOGDIR}/ramcloudcoordinator.`hostname`.log
+thishost=`hostname`
+thisip=`host2ip $thishost`
+RAMCLOUD_COORDINATOR="fast+udp:host=$thisip,port=12242"
+
+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