Merge "Minor fix" into dev/ramcloud-new-datamodel
diff --git a/src/main/cpp/edu_stanford_ramcloud_JRamCloud.cc b/src/main/cpp/edu_stanford_ramcloud_JRamCloud.cc
index fe61007..4694c4e 100644
--- a/src/main/cpp/edu_stanford_ramcloud_JRamCloud.cc
+++ b/src/main/cpp/edu_stanford_ramcloud_JRamCloud.cc
@@ -340,12 +340,11 @@
 
     const static jmethodID methodId = env->GetMethodID(cls,
                                           "<init>",
-                                          "(L" PACKAGE_PATH "JRamCloud;[B[BJ)V");
+                                          "([B[BJ)V");
     check_null(methodId, "GetMethodID failed");
 
     return env->NewObject(cls,
                           methodId,
-                          jRamCloud,
                           jKey,
                           jValue,
                           static_cast<jlong>(version));
@@ -377,7 +376,7 @@
                                                         jobject jRamCloud,
 							jlongArray jTableId,
 							jobjectArray jKeyData,
-							jshortArray jKeyDataSize,
+							jshortArray jKeyLength,
 							jint jrequestNum){
 
     RamCloud* ramcloud = getRamCloud(env, jRamCloud);
@@ -386,22 +385,22 @@
     jbyteArray jKey[jrequestNum];
     MultiReadObject* requests[jrequestNum];
 
-    jlong TableId;
-    jshort KeyDataSize;
-    jbyte* data[jrequestNum];
+    jlong tableId;
+    jshort keyLength;
+    jbyte* keyData[jrequestNum];
 
     for (int i = 0 ; i < jrequestNum ; i++){
         jKey[i] = (jbyteArray)env->GetObjectArrayElement(jKeyData, i); 
 
-        env->GetShortArrayRegion(jKeyDataSize, i, 1, &KeyDataSize);
+        env->GetShortArrayRegion(jKeyLength, i, 1, &keyLength);
 
-        data[i] = (jbyte *) malloc(KeyDataSize);
-        env->GetByteArrayRegion(jKey[i], 0, KeyDataSize, data[i]);
+        keyData[i] = (jbyte *) malloc(keyLength);
+        env->GetByteArrayRegion(jKey[i], 0, keyLength, keyData[i]);
 
-        env->GetLongArrayRegion(jTableId, i, 1, &TableId);
-        objects[i].tableId = TableId;
-        objects[i].key = data[i];
-	objects[i].keyLength = KeyDataSize;
+        env->GetLongArrayRegion(jTableId, i, 1, &tableId);
+        objects[i].tableId = tableId;
+        objects[i].key = keyData[i];
+	objects[i].keyLength = keyLength;
         objects[i].value = &values[i];
         requests[i] = &objects[i];
     }
@@ -414,7 +413,7 @@
     check_null(jc_RcObject, "FindClass failed");
     const static jmethodID jm_init = env->GetMethodID(jc_RcObject,
                                         "<init>",
-                                        "(L" PACKAGE_PATH "JRamCloud;[B[BJ)V");
+                                        "([B[BJ)V");
 
     jobjectArray outJNIArray = env->NewObjectArray(jrequestNum, jc_RcObject , NULL);
     check_null(outJNIArray, "NewObjectArray failed");
@@ -425,11 +424,11 @@
 	    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);
+	    jobject obj = env->NewObject(jc_RcObject, jm_init, jKey[i], jValue);
 	    check_null(obj, "NewObject failed");
 	    env->SetObjectArrayElement(outJNIArray, i, obj);
 	}
-	free(data[i]);
+	free(keyData[i]);
     }
     return outJNIArray;
 }
@@ -672,11 +671,10 @@
         check_null(cls, "FindClass failed");
         const static jmethodID methodId = env->GetMethodID(cls,
                                           "<init>",
-                                          "(L" PACKAGE_PATH "JRamCloud;[B[BJ)V");
+                                          "([B[BJ)V");
         check_null(methodId, "GetMethodID failed");
         return env->NewObject(cls,
                               methodId,
-                              jTableEnumerator,
                               jKey,
                               jValue,
                               static_cast<jlong>(version));        
@@ -686,24 +684,123 @@
 
 /*
  * Class:     edu_stanford_ramcloud_JRamCloud
+ * Method:    getTableObjects
+ * Signature: (JJ)Ledu/stanford/ramcloud/JRamCloud/TableEnumeratorObject;
+ */
+JNIEXPORT jobject JNICALL Java_edu_stanford_ramcloud_JRamCloud_getTableObjects(JNIEnv *env,
+                                                                               jobject jRamCloud,
+                                                                               jlong jTableId,
+                                                                               jlong jTabletNextHash){
+
+    RamCloud* ramcloud = getRamCloud(env, jRamCloud);
+
+    Buffer state;
+    Buffer objects;
+    bool done = false;
+    uint64_t version = 0;
+
+    uint32_t nextOffset = 0;
+
+    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>",
+                                        "([B[BJ)V");
+    check_null(jm_init, "GetMethodID failed");
+    
+    const static jclass jc_RcTableObject = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$TableEnumeratorObject"));
+    check_null(jc_RcTableObject, "FindClass failed");
+    const static jmethodID jm_TableEnumeratorObject_init = env->GetMethodID(jc_RcTableObject,
+                                        "<init>",
+                                        "([Ledu/stanford/ramcloud/JRamCloud$Object;J)V");
+    check_null(jm_TableEnumeratorObject_init, "GetMethodID failed");
+
+    
+    while (true) {
+        jTabletNextHash = ramcloud->enumerateTable(jTableId, jTabletNextHash, state, objects);
+        if (objects.getTotalLength() > 0) {
+            break;
+        }
+        if (objects.getTotalLength() == 0 && jTabletNextHash == 0) {
+            done = true;
+            break;
+        }    
+    }
+    
+    if (done) {
+        return env->NewObject(jc_RcTableObject, jm_TableEnumeratorObject_init, env->NewObjectArray(0, jc_RcObject , NULL), 0);
+    }
+    
+    int numOfTable;
+    for (numOfTable = 0; nextOffset < objects.getTotalLength() ; numOfTable++) {
+        uint32_t objectSize = *objects.getOffset<uint32_t>(nextOffset);
+        nextOffset += downCast<uint32_t>(sizeof(uint32_t));
+        nextOffset += objectSize;
+    }
+    
+    jobjectArray outJNIArray = env->NewObjectArray(numOfTable, jc_RcObject , NULL);
+    check_null(outJNIArray, "NewObjectArray failed");
+
+    nextOffset = 0;
+    for (int i = 0; nextOffset < objects.getTotalLength() ;i++) {
+        uint32_t objectSize = *objects.getOffset<uint32_t>(nextOffset);
+        nextOffset += downCast<uint32_t>(sizeof(uint32_t));
+
+        const void* blob = objects.getRange(nextOffset, objectSize);
+        nextOffset += objectSize;
+
+        Object object(blob, objectSize);
+
+        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();
+
+        jobject obj = env->NewObject(jc_RcObject, jm_init, jKey, jValue, static_cast<jlong>(version));
+        check_null(obj, "NewObject failed");
+
+        env->SetObjectArrayElement(outJNIArray, i, obj);
+    }
+
+    return env->NewObject(jc_RcTableObject, jm_TableEnumeratorObject_init, outJNIArray, jTabletNextHash);
+
+}
+
+/*
+ * 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];
+JNIEXPORT jobjectArray JNICALL Java_edu_stanford_ramcloud_JRamCloud_multiWrite(JNIEnv *env, 
+	                                                                       jobject jRamCloud,
+	                                                                       jlongArray jTableId,
+	                                                                       jobjectArray jKeyData,
+	                                                                       jshortArray jKeyLength,
+	                                                                       jobjectArray jValueData,
+	                                                                       jshortArray jValueLength,
+	                                                                       jint jrequestNum,
+	                                                                       jobjectArray jRules ) {
     
-    const static jclass jc_multiWriteObject = (jclass)env->NewGlobalRef(env->FindClass(PACKAGE_PATH "JRamCloud$MultiWriteObject"));
+    RamCloud* ramcloud = getRamCloud(env, jRamCloud);
+    Tub<MultiWriteObject> objects[jrequestNum];
+    MultiWriteObject *requests[jrequestNum];
+    RejectRules rules[jrequestNum];
+    jbyteArray jKey[jrequestNum];
+    jbyteArray jValue[jrequestNum];
+    
+    jlong tableId;
+    jshort keyLength;
+    jshort valueLength;
+    jbyte* keyData[jrequestNum];
+    jbyte* valueData[jrequestNum];
+    
     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");
@@ -716,21 +813,20 @@
     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");
+    for (int i = 0; i < jrequestNum; i++) {
+	env->GetLongArrayRegion(jTableId, i, 1, &tableId);
 
-        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);
+	env->GetShortArrayRegion(jKeyLength, i, 1, &keyLength);
+	jKey[i] = (jbyteArray)env->GetObjectArrayElement(jKeyData, i);
+	keyData[i] = (jbyte *) malloc(keyLength);
+	env->GetByteArrayRegion(jKey[i], 0, keyLength, keyData[i]);
+	
+	env->GetShortArrayRegion(jValueLength, i, 1, &valueLength);
+        jValue[i] = (jbyteArray)env->GetObjectArrayElement(jValueData, i);
+	valueData[i] = (jbyte *) malloc(valueLength);
+	env->GetByteArrayRegion(jValue[i], 0, valueLength, valueData[i]);
+	
+	jobject jRejectRules = (jbyteArray)env->GetObjectArrayElement(jRules, i);
         rules[i] = {};
 
         if (jRejectRules != NULL) {
@@ -750,28 +846,28 @@
             ruleBool = env->GetBooleanField(jRejectRules, jf_versionNeGiven);
             rules[i].versionNeGiven = ruleBool ? 1 : 0;
         }
-        objects[i].construct(tableId, keyData, keyLength, valueData, valueLength, &rules[i]);
+        objects[i].construct(tableId, keyData[i], keyLength, valueData[i], valueLength, &rules[i]);
         requests[i] = objects[i].get();
     }
     try {
-        ramcloud->multiWrite(requests, requestNum);
+        ramcloud->multiWrite(requests, jrequestNum);
     } 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");
+                                        "(IJ)V");
 
-    jobjectArray outJNIArray = env->NewObjectArray(requestNum, jc_RcObject , NULL);
+    jobjectArray outJNIArray = env->NewObjectArray(jrequestNum, 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);
+    for (int i = 0 ; i < jrequestNum ; i++) {
+        jobject obj = env->NewObject(jc_RcObject, jm_init, 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);
+	free(keyData[i]);
+	free(valueData[i]);
         objects[i].destroy();
     }
     return outJNIArray;
diff --git a/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudGraph.java b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudGraph.java
index 26f1418..ad519c8 100644
--- a/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudGraph.java
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudGraph.java
@@ -247,16 +247,18 @@
 	    }
 	    vertices.add(v);
 	}
-	MultiWriteObject multiWriteObjects[] = new MultiWriteObject[vertices.size() * 2];
+	
+	MultiWriteObject mwo = 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);
+	    mwo.setObject(i*2, vertTableId, v.rcKey, ByteBuffer.allocate(0).array(), null);
+	    mwo.setObject(i*2+1, vertTableId, v.rcKey, ByteBuffer.allocate(0).array(), null);
 	}
 	try {
 		PerfMon pm = PerfMon.getInstance();
 		pm.multiwrite_start("RamCloudVertex create()");
-	    getRcClient().multiWrite(multiWriteObjects);
+		getRcClient().multiWrite(mwo.tableId, mwo.key, mwo.keyLength, mwo.value, mwo.valueLength, vertices.size()*2, mwo.rules);
 		pm.multiwrite_end("RamCloudVertex create()");
 	    log.info("ramcloud vertices are created");
 	} catch (Exception e) {
diff --git a/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudVertex.java b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudVertex.java
index b41dca8..03c4ba3 100644
--- a/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudVertex.java
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudVertex.java
@@ -490,12 +490,12 @@
 		// 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);
+			JRamCloud vertTable = graph.getRcClient();			
+			MultiWriteObject mwo = new MultiWriteObject(2);
+			mwo.setObject(1, graph.vertTableId, rcKey, ByteBuffer.allocate(0).array(), null);
+			mwo.setObject(2, graph.vertPropTableId, rcKey, ByteBuffer.allocate(0).array(), null);
 			pm.multiwrite_start("RamCloudVertex create()");
-			vertTable.multiWrite(mwo);
+			vertTable.multiWrite(mwo.tableId, mwo.key, mwo.keyLength, mwo.value, mwo.valueLength, 2, mwo.rules);
 			pm.multiwrite_end("RamCloudVertex create()");
 		} else {
 			throw ExceptionFactory.vertexWithIdAlreadyExists(id);
diff --git a/src/main/java/edu/stanford/ramcloud/JRamCloud.java b/src/main/java/edu/stanford/ramcloud/JRamCloud.java
index dfb4b6a..63b0748 100644
--- a/src/main/java/edu/stanford/ramcloud/JRamCloud.java
+++ b/src/main/java/edu/stanford/ramcloud/JRamCloud.java
@@ -14,9 +14,8 @@
  */
 
 package edu.stanford.ramcloud;
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.lang.Integer;
+import java.util.LinkedList;
 
 /*
  * This class provides Java bindings for RAMCloud. Right now it is a rather
@@ -78,31 +77,53 @@
         }	
     }
     
-    public static class multiReadObject {
-        long tableId;
-        byte[] key;
+    public static class MultiReadObject {
+        public long[] tableId;
+        public byte[] key[];
+	public short[] keyLength;
         
-        public multiReadObject(long _tableId, byte[] _key){
-            tableId = _tableId;
-            key = _key;
+        public MultiReadObject(int size){
+            this.tableId = new long[size];
+            this.key = new byte[size][];
+	    this.keyLength = new short[size];
         }
+	
+	public void setObject(int num, long tableId, byte key[]){
+            this.tableId[num] = tableId;
+            this.key[num] = key;
+	    this.keyLength[num] = (short) this.key[num].length;
+	}
     }
     
     public static class MultiWriteObject {
-        long tableId;
-        byte[] key;
-        byte[] value;
-        RejectRules rules;
+        public long[] tableId;
+        public byte[] key[];
+	public short[] keyLength;
+        public byte[] value[];
+	public short[] valueLength;
+        public 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 MultiWriteObject(int size) {
+            this.tableId = new long[size];
+            this.key = new byte[size][];
+	    this.keyLength = new short[size];
+            this.value = new byte[size][];
+	    this.valueLength = new short[size];
+            this.rules = new RejectRules[size];
         }
+	
+	public void setObject(int num, long tableId, byte key[], byte value[], RejectRules rules){
+	    this.tableId[num] = tableId;
+	    this.key[num] = key;
+	    this.keyLength[num] = (short) key.length;
+	    this.value[num] = value;
+	    this.valueLength[num] = (short) value.length;
+	    this.rules[num] = rules;
+	}
+	
     }
 
-    public class MultiWriteRspObject {
+    public static class MultiWriteRspObject {
         private int status;
         private long version;
 
@@ -127,7 +148,7 @@
      * 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 {
+    public static class Object {
         Object(byte[] _key, byte[] _value, long _version)
         {
             key = _key;
@@ -151,6 +172,17 @@
         final public byte[] value;
         final public long version;
     }
+    
+    public static class TableEnumeratorObject {
+	TableEnumeratorObject(Object[] _object, long _nextHash)
+        {
+	    object = _object;
+	    nextHash = _nextHash;
+	}
+	
+	final public Object[] object;
+	final public long nextHash;
+    }
 
     public class TableEnumerator {
         private long tableEnumeratorObjectPointer = 0;
@@ -167,6 +199,43 @@
         public native Object next();
     }
 
+    public class TableEnumerator2 {
+        
+	protected long tableId;
+	protected LinkedList<JRamCloud.Object> rcobjs = null;
+	protected long nextHash = 0;
+	protected boolean done = false;
+	
+        public TableEnumerator2(long tableId)
+        {
+	    this.tableId = tableId;
+	    rcobjs = new LinkedList<>();
+        }
+        public boolean hasNext() {
+	    if (rcobjs.isEmpty()) 
+	    {
+		if (done) {
+		    return false;
+		}
+		JRamCloud.TableEnumeratorObject o = getTableObjects(this.tableId, this.nextHash);
+		if (o.nextHash == 0L) {
+		    done = true;
+		}
+		this.nextHash = o.nextHash;
+		rcobjs.addAll(Arrays.asList(o.object));
+		if (rcobjs.isEmpty()) {
+		    return false;
+		}
+	    }
+	    return true;
+	}
+	
+	public Object next() 
+	{
+	    return rcobjs.pop();
+	}
+    }
+    
     /**
      * Connect to the RAMCloud cluster specified by the given coordinator's
      * service locator string. This causes the JNI code to instantiate the
@@ -294,7 +363,8 @@
     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);
+    public native MultiWriteRspObject[] multiWrite(long[] tableId, byte[] key[], short[] keyDataSize, byte[] value[], short[] valueDataSize, int requestNum, RejectRules[] rules);
+    public native TableEnumeratorObject getTableObjects(long tableId, long nextHash);
 
     /*
      * The following exceptions may be thrown by the JNI functions:
@@ -339,7 +409,60 @@
             super(message);
         }
     }
+    
+    public static void tableEnumeratorTest(JRamCloud ramcloud) {
+        long startTime = 0;
+        for (int x = 0 ; x < 2 ; x ++){
+        for(int N = 1000; N < 10000; N += 1000) {
+            long EnumerateTesttable = ramcloud.createTable("EnumerateTest");
+            for(int i = 0 ; i < N ; ++i) {
+                String key = new Integer(i).toString();
+                ramcloud.write(EnumerateTesttable, key.getBytes(), "Hello, World!".getBytes());
+            }
 
+            MultiReadObject mread[] = new MultiReadObject[N];
+            long tableIdList[] = new long[N];
+            byte[] keydata[] = new byte[N][];
+            short keydataSize[] = new short[N];
+	    startTime = System.nanoTime();
+            for (int j = 0 ; j < N ; ++j) {
+                tableIdList[j] = EnumerateTesttable;
+                String key = new Integer(j).toString();
+                keydata[j] = key.getBytes();
+                keydataSize[j] = (short) keydata[j].length;
+            }
+            JRamCloud.Object out[] = ramcloud.multiRead(tableIdList, keydata, keydataSize, N);
+            for (int i = 0; i < N; ++i) {
+                if(out[i].version == 0) {
+                        System.out.println("Verify fail " + out[i].getKey() + " V:" + out[i].getValue());
+                }
+            }
+
+            System.out.println("multiRead           : " + N + " Time : " + (System.nanoTime()-startTime));
+
+            startTime = System.nanoTime();
+            JRamCloud.TableEnumerator tableEnum = ramcloud.new TableEnumerator(EnumerateTesttable);
+            while (tableEnum.hasNext()) {
+                Object tableEntry = tableEnum.next();
+                if (tableEntry != null) {
+                    System.out.println("tableEnumerator object: key = [" + tableEntry.getKey() + "], value = [" + tableEntry.getValue() + "]");
+                }
+            }
+	    System.out.println("old TableEnumerator : " + N + " Time : " + (System.nanoTime()-startTime));
+
+            startTime = System.nanoTime();
+            JRamCloud.TableEnumerator2 tableEnum2 = ramcloud.new TableEnumerator2(EnumerateTesttable);
+	    while (tableEnum2.hasNext()) {
+		Object tableEntry2 = tableEnum2.next();
+		if (tableEntry2 != null) {
+                    System.out.println("tableEnumerator2 object: key = [" + tableEntry2.getKey() + "], value = [" + tableEntry2.getValue() + "]");
+                }
+            }
+            System.out.println("new TableEnumerator : " + N + " Time : " + (System.nanoTime()-startTime));
+            ramcloud.dropTable("EnumerateTest");
+        }
+        }
+    }
     /**
      * A simple end-to-end test of the java bindings.
      */
@@ -391,30 +514,26 @@
         ramcloud.write(tableId6, "object3-1", "value:3-1");
         ramcloud.write(tableId6, "object3-2", "value:3-2");
 
-	long tableIdList[] = new long[2];
-        byte[] keydata[] = new byte[2][];
-        short keydataSize[] = new short[2];
-        tableIdList[0] = tableId4;
-        keydata[0] = "object1-1".getBytes();
-        keydataSize[0] = (short) keydata[0].length;
-        tableIdList[1] = tableId5;
-        keydata[1] = "object2-1".getBytes();
-	keydataSize[1] = (short) keydata[1].length;
+	MultiReadObject mr = new MultiReadObject(2);
+	MultiWriteObject mw = new MultiWriteObject(2);
+	
+	mr.setObject(0, tableId4, "object1-1".getBytes());
+	mr.setObject(1, tableId5, "object2-1".getBytes());
 
-        JRamCloud.Object out[] = ramcloud.multiRead(tableIdList, keydata, keydataSize, 2);
+        JRamCloud.Object out[] = ramcloud.multiRead(mr.tableId, mr.key, mr.keyLength, 2);
         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);
+	    
+	    mw.setObject(0, tableId4, key1.getBytes(), "v0-value".getBytes(), null);
+	    mw.setObject(1, tableId5, key2.getBytes(), "v1".getBytes(), null);
+      	    
+            MultiWriteRspObject[] rsp = ramcloud.multiWrite(mw.tableId, mw.key, mw.keyLength, mw.value, mw.valueLength, 2, mw.rules);
             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());
@@ -424,19 +543,18 @@
         for (int i = 0; i < 1000; i++) {
             String key1 = "key1" + new Integer(i).toString();
             String key2 = "key2" + new Integer(i).toString();
-            tableIdList[0] = tableId4;
-            keydata[0] = key1.getBytes();
-            keydataSize[0] = (short) keydata[0].length;
-            tableIdList[1] = tableId5;
-            keydata[1] = key2.getBytes();
-            keydataSize[1] = (short) keydata[1].length;
 
-            out = ramcloud.multiRead(tableIdList, keydata, keydataSize, 2);
+	    mr.setObject(0, tableId4, key1.getBytes());
+	    mr.setObject(1, tableId5, key2.getBytes());
+	    
+            out = ramcloud.multiRead(mr.tableId, mr.key, mr.keyLength, 2);
             for (int j = 0; j < 2; j++) {
                 System.out.println("multi read object: key = [" + out[j].getKey() + "], value = [" + out[j].getValue() + "]");
             }
         }
 
+	tableEnumeratorTest(ramcloud);
+	
         ramcloud.dropTable("table4");
         ramcloud.dropTable("table5");
         ramcloud.dropTable("table6");
diff --git a/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java b/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java
index 99f79fc..28399c8 100755
--- a/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java
+++ b/src/main/java/net/onrc/onos/datagrid/web/DatagridWebRoutable.java
@@ -19,6 +19,7 @@
         router.attach("/get/map/{map-name}/json", GetMapResource.class);
         router.attach("/add/intents/json", IntentResource.class);
         router.attach("/get/intents/json", IntentResource.class);
+        router.attach("/get/intent/{intent_id}/json", IntentResource.class);
         return router;
     }
 
diff --git a/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java b/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java
index daf786f..2fc78f0 100755
--- a/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java
+++ b/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java
@@ -36,6 +36,8 @@
  */
 public class IntentResource extends ServerResource {
     private final static Logger log = LoggerFactory.getLogger(IntentResource.class);
+    // TODO need to assign proper application id.
+    private final String APPLN_ID = "1";
 
     private class IntentStatus {
         String intentId;
@@ -76,8 +78,7 @@
         IPathCalcRuntimeService pathRuntime = (IPathCalcRuntimeService)getContext()
                 .getAttributes().get(IPathCalcRuntimeService.class.getCanonicalName());
         if (pathRuntime == null) {
-            log.debug("Failed to get path calc runtime");
-            System.out.println("Failed to get path calc runtime");
+            log.warn("Failed to get path calc runtime");
             return "";
         }
         String reply = "";
@@ -105,17 +106,32 @@
                 getAttributes().get(IPathCalcRuntimeService.class.getCanonicalName());
         ObjectMapper mapper = new ObjectMapper();
         String restStr = "";
+
+        String intentId = (String) getRequestAttributes().get("intent_id");
         ArrayNode arrayNode = mapper.createArrayNode();
         IntentMap intentMap = pathRuntime.getHighLevelIntents();
         Collection<Intent> intents = intentMap.getAllIntents();
         if (!intents.isEmpty()) {
-            for (Intent intent : intents) {
-                ObjectNode node = mapper.createObjectNode();
-                node.put("intent_id", intent.getId());
-                node.put("status", intent.getState().toString());
-                arrayNode.add(node);
-                restStr = mapper.writeValueAsString(arrayNode);
+            if ((intentId != null )) {
+                String applnIntentId = APPLN_ID + ":" + intentId;
+                Intent intent = intentMap.getIntent(applnIntentId);
+                if (intent != null) {
+                    ObjectNode node = mapper.createObjectNode();
+                    node.put("intent_id", intentId);
+                    node.put("status", intent.getState().toString());
+                    arrayNode.add(node);
+                }
+            } else {
+                for (Intent intent : intents) {
+                    ObjectNode node = mapper.createObjectNode();
+                    String applnIntentId = intent.getId();
+                    intentId = applnIntentId.split(":")[1];
+                    node.put("intent_id", intentId);
+                    node.put("status", intent.getState().toString());
+                    arrayNode.add(node);
+                }
             }
+            restStr = mapper.writeValueAsString(arrayNode);
         }
         return restStr;
     }
@@ -144,9 +160,8 @@
         return mapper.writeValueAsString(arrayNode);
     }
 
-    private void appendIntentStatus(String status, final String applnIntentId, 
+    private void appendIntentStatus(String status, final String intentId, 
             ObjectMapper mapper, ArrayNode arrayNode) throws IOException {
-        String intentId = applnIntentId.split(":")[1];
         ObjectNode node = mapper.createObjectNode();
         node.put("intent_id", intentId);
         node.put("status", status);
@@ -157,13 +172,14 @@
         String intentType = (String)fields.get("intent_type");
         String intentOp = (String)fields.get("intent_op");
         String status = null;
+        String applnIntentId = APPLN_ID + ":" + (String)fields.get("intent_id");
         
         IntentOperation.Operator operation = IntentOperation.Operator.ADD;
         if ((intentOp.equals("remove"))) {
             operation = IntentOperation.Operator.REMOVE;
         }
         if (intentType.equals("shortest_intent_type")) {
-            ShortestPathIntent spi = new ShortestPathIntent((String) fields.get("intent_id"),
+            ShortestPathIntent spi = new ShortestPathIntent(applnIntentId,
                     Long.decode((String) fields.get("srcSwitch")),
                     (long) fields.get("srcPort"),
                     MACAddress.valueOf((String) fields.get("srcMac")).toLong(),
@@ -173,7 +189,7 @@
             operations.add(new IntentOperation(operation, spi));
             status = (spi.getState()).toString();
         } else {
-            ConstrainedShortestPathIntent cspi = new ConstrainedShortestPathIntent((String) fields.get("intent_id"),
+            ConstrainedShortestPathIntent cspi = new ConstrainedShortestPathIntent(applnIntentId,
                     Long.decode((String) fields.get("srcSwitch")),
                     (long) fields.get("srcPort"),
                     MACAddress.valueOf((String) fields.get("srcMac")).toLong(),
diff --git a/src/main/java/net/onrc/onos/datastore/RCObject.java b/src/main/java/net/onrc/onos/datastore/RCObject.java
index a990978..77f5d15 100644
--- a/src/main/java/net/onrc/onos/datastore/RCObject.java
+++ b/src/main/java/net/onrc/onos/datastore/RCObject.java
@@ -18,12 +18,14 @@
 import com.esotericsoftware.kryo.io.Output;
 
 import edu.stanford.ramcloud.JRamCloud;
+import edu.stanford.ramcloud.JRamCloud.MultiReadObject;
 import edu.stanford.ramcloud.JRamCloud.MultiWriteObject;
 import edu.stanford.ramcloud.JRamCloud.MultiWriteRspObject;
 import edu.stanford.ramcloud.JRamCloud.ObjectDoesntExistException;
 import edu.stanford.ramcloud.JRamCloud.ObjectExistsException;
 import edu.stanford.ramcloud.JRamCloud.RejectRules;
 import edu.stanford.ramcloud.JRamCloud.TableEnumerator;
+import edu.stanford.ramcloud.JRamCloud.TableEnumerator2;
 import edu.stanford.ramcloud.JRamCloud.WrongVersionException;
 
 /**
@@ -54,7 +56,7 @@
 
     private final RCTable table;
     private final byte[] key;
-    private byte[] value;
+    protected byte[] value; //FIXME should not be exposed
     private long version;
 
     private Map<Object, Object> propertyMap;
@@ -148,6 +150,7 @@
 
     protected void serializeAndSetValue(Kryo kryo,
 	    Map<Object, Object> javaObject) {
+	
 
 	// value
 	byte[] rcTemp = new byte[1024 * 1024];
@@ -173,7 +176,7 @@
 	    Class<T> type) {
 	if (this.value == null)
 	    return null;
-
+	
 	Input input = new Input(this.value);
 	T map = kryo.readObject(input, type);
 	this.propertyMap = map;
@@ -304,21 +307,17 @@
 	JRamCloud rcClient = RCClient.getClient();
 
 	final int reqs = req.size();
-
-        long tableId[] = new long[reqs];
-        byte[] key[] = new byte[reqs][];
-        short keySize[] = new short[reqs];
+	
+	MultiReadObject multiReadObjects = new MultiReadObject(req.size());
 
 	// setup multi-read operation
 	for (int i = 0; i < reqs; ++i) {
 	    RCObject obj = req.get(i);
-            tableId[i] = obj.getTableId();
-            key[i] = obj.getKey();
-            keySize[i] = (short) key[i].length;
+            multiReadObjects.setObject(i, obj.getTableId(), obj.getKey());
 	}
 
 	// execute
-	JRamCloud.Object results[] = rcClient.multiRead(tableId, key, keySize, reqs);
+	JRamCloud.Object results[] = rcClient.multiRead(multiReadObjects.tableId, multiReadObjects.key, multiReadObjects.keyLength, reqs);
 	assert (results.length <= req.size());
 
 	// reflect changes to RCObject
@@ -420,10 +419,10 @@
     private static boolean multiWriteInternal(ArrayList<WriteOp> ops) {
 
 	boolean fail_exists = false;
-	MultiWriteObject multiWriteObjects[] = new MultiWriteObject[ops.size()];
+	MultiWriteObject multiWriteObjects = new MultiWriteObject(ops.size());
 	JRamCloud rcClient = RCClient.getClient();
 
-	for (int i = 0; i < multiWriteObjects.length; ++i) {
+	for (int i = 0; i < ops.size(); ++i) {
 	    WriteOp op = ops.get(i);
 	    RCObject obj = op.getObject();
 
@@ -442,12 +441,11 @@
 		rules.setNeVersion(obj.getVersion());
 		break;
 	    }
-	    multiWriteObjects[i] = new MultiWriteObject(obj.getTableId(),
-		    obj.getKey(), obj.getValue(), rules);
+	    multiWriteObjects.setObject(i, obj.getTableId(), obj.getKey(), obj.getValue(), rules);
 	}
 
-	MultiWriteRspObject[] results = rcClient.multiWrite(multiWriteObjects);
-	assert (results.length == multiWriteObjects.length);
+	MultiWriteRspObject[] results = rcClient.multiWrite(multiWriteObjects.tableId, multiWriteObjects.key, multiWriteObjects.keyLength, multiWriteObjects.value, multiWriteObjects.valueLength, ops.size(), multiWriteObjects.rules);
+	assert (results.length == ops.size());
 
 	for (int i = 0; i < results.length; ++i) {
 	    WriteOp op = ops.get(i);
@@ -467,17 +465,17 @@
 
 	return fail_exists;
     }
-
+   
     public static abstract class ObjectIterator<E extends RCObject> implements
 	    Iterator<E> {
 
-	protected TableEnumerator enumerator;
+	protected TableEnumerator2 enumerator;
 
 	public ObjectIterator(RCTable table) {
 	    // FIXME workaround for JRamCloud bug. It should have been declared
 	    // as static class
 	    JRamCloud c = RCClient.getClient();
-	    this.enumerator = c.new TableEnumerator(table.getTableId());
+	    this.enumerator = c.new TableEnumerator2(table.getTableId());
 	}
 
 	@Override
@@ -493,7 +491,7 @@
 //	    obj.setValueAndDeserialize(o.value, o.version);
 //	    return obj;
 //	}
-
+	
 	@Deprecated
 	@Override
 	public void remove() {
diff --git a/src/main/java/net/onrc/onos/datastore/RCProtos.java b/src/main/java/net/onrc/onos/datastore/RCProtos.java
new file mode 100644
index 0000000..a451b05
--- /dev/null
+++ b/src/main/java/net/onrc/onos/datastore/RCProtos.java
@@ -0,0 +1,2177 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: protobuf/ramcloud.proto
+
+package net.onrc.onos.datastore;
+
+public final class RCProtos {
+  private RCProtos() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface SwitchPropertyOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required int64 dpid = 1;
+    /**
+     * <code>required int64 dpid = 1;</code>
+     */
+    boolean hasDpid();
+    /**
+     * <code>required int64 dpid = 1;</code>
+     */
+    long getDpid();
+
+    // required int32 status = 2;
+    /**
+     * <code>required int32 status = 2;</code>
+     */
+    boolean hasStatus();
+    /**
+     * <code>required int32 status = 2;</code>
+     */
+    int getStatus();
+
+    // optional bytes value = 3;
+    /**
+     * <code>optional bytes value = 3;</code>
+     */
+    boolean hasValue();
+    /**
+     * <code>optional bytes value = 3;</code>
+     */
+    com.google.protobuf.ByteString getValue();
+  }
+  /**
+   * Protobuf type {@code RCProtos.SwitchProperty}
+   */
+  public static final class SwitchProperty extends
+      com.google.protobuf.GeneratedMessage
+      implements SwitchPropertyOrBuilder {
+    // Use SwitchProperty.newBuilder() to construct.
+    private SwitchProperty(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private SwitchProperty(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final SwitchProperty defaultInstance;
+    public static SwitchProperty getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public SwitchProperty getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private SwitchProperty(
+        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;
+              dpid_ = input.readInt64();
+              break;
+            }
+            case 16: {
+              bitField0_ |= 0x00000002;
+              status_ = input.readInt32();
+              break;
+            }
+            case 26: {
+              bitField0_ |= 0x00000004;
+              value_ = 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 net.onrc.onos.datastore.RCProtos.internal_static_ProtoBuffer_SwitchProperty_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return net.onrc.onos.datastore.RCProtos.internal_static_ProtoBuffer_SwitchProperty_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              net.onrc.onos.datastore.RCProtos.SwitchProperty.class, net.onrc.onos.datastore.RCProtos.SwitchProperty.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<SwitchProperty> PARSER =
+        new com.google.protobuf.AbstractParser<SwitchProperty>() {
+      public SwitchProperty parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new SwitchProperty(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<SwitchProperty> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required int64 dpid = 1;
+    public static final int DPID_FIELD_NUMBER = 1;
+    private long dpid_;
+    /**
+     * <code>required int64 dpid = 1;</code>
+     */
+    public boolean hasDpid() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required int64 dpid = 1;</code>
+     */
+    public long getDpid() {
+      return dpid_;
+    }
+
+    // required int32 status = 2;
+    public static final int STATUS_FIELD_NUMBER = 2;
+    private int status_;
+    /**
+     * <code>required int32 status = 2;</code>
+     */
+    public boolean hasStatus() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required int32 status = 2;</code>
+     */
+    public int getStatus() {
+      return status_;
+    }
+
+    // optional bytes value = 3;
+    public static final int VALUE_FIELD_NUMBER = 3;
+    private com.google.protobuf.ByteString value_;
+    /**
+     * <code>optional bytes value = 3;</code>
+     */
+    public boolean hasValue() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>optional bytes value = 3;</code>
+     */
+    public com.google.protobuf.ByteString getValue() {
+      return value_;
+    }
+
+    private void initFields() {
+      dpid_ = 0L;
+      status_ = 0;
+      value_ = com.google.protobuf.ByteString.EMPTY;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasDpid()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasStatus()) {
+        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.writeInt64(1, dpid_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeInt32(2, status_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeBytes(3, value_);
+      }
+      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
+          .computeInt64Size(1, dpid_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(2, status_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(3, value_);
+      }
+      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 net.onrc.onos.datastore.RCProtos.SwitchProperty parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static net.onrc.onos.datastore.RCProtos.SwitchProperty parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static net.onrc.onos.datastore.RCProtos.SwitchProperty parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static net.onrc.onos.datastore.RCProtos.SwitchProperty parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static net.onrc.onos.datastore.RCProtos.SwitchProperty parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static net.onrc.onos.datastore.RCProtos.SwitchProperty parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static net.onrc.onos.datastore.RCProtos.SwitchProperty parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static net.onrc.onos.datastore.RCProtos.SwitchProperty parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static net.onrc.onos.datastore.RCProtos.SwitchProperty parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static net.onrc.onos.datastore.RCProtos.SwitchProperty 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(net.onrc.onos.datastore.RCProtos.SwitchProperty 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 RCProtos.SwitchProperty}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements net.onrc.onos.datastore.RCProtos.SwitchPropertyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return net.onrc.onos.datastore.RCProtos.internal_static_ProtoBuffer_SwitchProperty_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return net.onrc.onos.datastore.RCProtos.internal_static_ProtoBuffer_SwitchProperty_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                net.onrc.onos.datastore.RCProtos.SwitchProperty.class, net.onrc.onos.datastore.RCProtos.SwitchProperty.Builder.class);
+      }
+
+      // Construct using net.onrc.onos.datastore.RCProtos.SwitchProperty.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();
+        dpid_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        status_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        value_ = com.google.protobuf.ByteString.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000004);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return net.onrc.onos.datastore.RCProtos.internal_static_ProtoBuffer_SwitchProperty_descriptor;
+      }
+
+      public net.onrc.onos.datastore.RCProtos.SwitchProperty getDefaultInstanceForType() {
+        return net.onrc.onos.datastore.RCProtos.SwitchProperty.getDefaultInstance();
+      }
+
+      public net.onrc.onos.datastore.RCProtos.SwitchProperty build() {
+        net.onrc.onos.datastore.RCProtos.SwitchProperty result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public net.onrc.onos.datastore.RCProtos.SwitchProperty buildPartial() {
+        net.onrc.onos.datastore.RCProtos.SwitchProperty result = new net.onrc.onos.datastore.RCProtos.SwitchProperty(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.dpid_ = dpid_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.status_ = status_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.value_ = value_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof net.onrc.onos.datastore.RCProtos.SwitchProperty) {
+          return mergeFrom((net.onrc.onos.datastore.RCProtos.SwitchProperty)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(net.onrc.onos.datastore.RCProtos.SwitchProperty other) {
+        if (other == net.onrc.onos.datastore.RCProtos.SwitchProperty.getDefaultInstance()) return this;
+        if (other.hasDpid()) {
+          setDpid(other.getDpid());
+        }
+        if (other.hasStatus()) {
+          setStatus(other.getStatus());
+        }
+        if (other.hasValue()) {
+          setValue(other.getValue());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasDpid()) {
+          
+          return false;
+        }
+        if (!hasStatus()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        net.onrc.onos.datastore.RCProtos.SwitchProperty parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (net.onrc.onos.datastore.RCProtos.SwitchProperty) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required int64 dpid = 1;
+      private long dpid_ ;
+      /**
+       * <code>required int64 dpid = 1;</code>
+       */
+      public boolean hasDpid() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required int64 dpid = 1;</code>
+       */
+      public long getDpid() {
+        return dpid_;
+      }
+      /**
+       * <code>required int64 dpid = 1;</code>
+       */
+      public Builder setDpid(long value) {
+        bitField0_ |= 0x00000001;
+        dpid_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int64 dpid = 1;</code>
+       */
+      public Builder clearDpid() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        dpid_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // required int32 status = 2;
+      private int status_ ;
+      /**
+       * <code>required int32 status = 2;</code>
+       */
+      public boolean hasStatus() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required int32 status = 2;</code>
+       */
+      public int getStatus() {
+        return status_;
+      }
+      /**
+       * <code>required int32 status = 2;</code>
+       */
+      public Builder setStatus(int value) {
+        bitField0_ |= 0x00000002;
+        status_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 status = 2;</code>
+       */
+      public Builder clearStatus() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        status_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // optional bytes value = 3;
+      private com.google.protobuf.ByteString value_ = com.google.protobuf.ByteString.EMPTY;
+      /**
+       * <code>optional bytes value = 3;</code>
+       */
+      public boolean hasValue() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>optional bytes value = 3;</code>
+       */
+      public com.google.protobuf.ByteString getValue() {
+        return value_;
+      }
+      /**
+       * <code>optional bytes value = 3;</code>
+       */
+      public Builder setValue(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000004;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bytes value = 3;</code>
+       */
+      public Builder clearValue() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        value_ = getDefaultInstance().getValue();
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:RCProtos.SwitchProperty)
+    }
+
+    static {
+      defaultInstance = new SwitchProperty(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:RCProtos.SwitchProperty)
+  }
+
+  public interface PortPropertyOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required int64 dpid = 1;
+    /**
+     * <code>required int64 dpid = 1;</code>
+     */
+    boolean hasDpid();
+    /**
+     * <code>required int64 dpid = 1;</code>
+     */
+    long getDpid();
+
+    // required int64 number = 2;
+    /**
+     * <code>required int64 number = 2;</code>
+     */
+    boolean hasNumber();
+    /**
+     * <code>required int64 number = 2;</code>
+     */
+    long getNumber();
+
+    // required int32 status = 3;
+    /**
+     * <code>required int32 status = 3;</code>
+     */
+    boolean hasStatus();
+    /**
+     * <code>required int32 status = 3;</code>
+     */
+    int getStatus();
+
+    // optional bytes value = 4;
+    /**
+     * <code>optional bytes value = 4;</code>
+     */
+    boolean hasValue();
+    /**
+     * <code>optional bytes value = 4;</code>
+     */
+    com.google.protobuf.ByteString getValue();
+  }
+  /**
+   * Protobuf type {@code RCProtos.PortProperty}
+   */
+  public static final class PortProperty extends
+      com.google.protobuf.GeneratedMessage
+      implements PortPropertyOrBuilder {
+    // Use PortProperty.newBuilder() to construct.
+    private PortProperty(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private PortProperty(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final PortProperty defaultInstance;
+    public static PortProperty getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public PortProperty getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private PortProperty(
+        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;
+              dpid_ = input.readInt64();
+              break;
+            }
+            case 16: {
+              bitField0_ |= 0x00000002;
+              number_ = input.readInt64();
+              break;
+            }
+            case 24: {
+              bitField0_ |= 0x00000004;
+              status_ = input.readInt32();
+              break;
+            }
+            case 34: {
+              bitField0_ |= 0x00000008;
+              value_ = 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 net.onrc.onos.datastore.RCProtos.internal_static_ProtoBuffer_PortProperty_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return net.onrc.onos.datastore.RCProtos.internal_static_ProtoBuffer_PortProperty_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              net.onrc.onos.datastore.RCProtos.PortProperty.class, net.onrc.onos.datastore.RCProtos.PortProperty.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<PortProperty> PARSER =
+        new com.google.protobuf.AbstractParser<PortProperty>() {
+      public PortProperty parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new PortProperty(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<PortProperty> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required int64 dpid = 1;
+    public static final int DPID_FIELD_NUMBER = 1;
+    private long dpid_;
+    /**
+     * <code>required int64 dpid = 1;</code>
+     */
+    public boolean hasDpid() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required int64 dpid = 1;</code>
+     */
+    public long getDpid() {
+      return dpid_;
+    }
+
+    // required int64 number = 2;
+    public static final int NUMBER_FIELD_NUMBER = 2;
+    private long number_;
+    /**
+     * <code>required int64 number = 2;</code>
+     */
+    public boolean hasNumber() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required int64 number = 2;</code>
+     */
+    public long getNumber() {
+      return number_;
+    }
+
+    // required int32 status = 3;
+    public static final int STATUS_FIELD_NUMBER = 3;
+    private int status_;
+    /**
+     * <code>required int32 status = 3;</code>
+     */
+    public boolean hasStatus() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>required int32 status = 3;</code>
+     */
+    public int getStatus() {
+      return status_;
+    }
+
+    // optional bytes value = 4;
+    public static final int VALUE_FIELD_NUMBER = 4;
+    private com.google.protobuf.ByteString value_;
+    /**
+     * <code>optional bytes value = 4;</code>
+     */
+    public boolean hasValue() {
+      return ((bitField0_ & 0x00000008) == 0x00000008);
+    }
+    /**
+     * <code>optional bytes value = 4;</code>
+     */
+    public com.google.protobuf.ByteString getValue() {
+      return value_;
+    }
+
+    private void initFields() {
+      dpid_ = 0L;
+      number_ = 0L;
+      status_ = 0;
+      value_ = com.google.protobuf.ByteString.EMPTY;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasDpid()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasNumber()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasStatus()) {
+        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.writeInt64(1, dpid_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeInt64(2, number_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeInt32(3, status_);
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        output.writeBytes(4, value_);
+      }
+      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
+          .computeInt64Size(1, dpid_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(2, number_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(3, status_);
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(4, value_);
+      }
+      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 net.onrc.onos.datastore.RCProtos.PortProperty parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static net.onrc.onos.datastore.RCProtos.PortProperty parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static net.onrc.onos.datastore.RCProtos.PortProperty parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static net.onrc.onos.datastore.RCProtos.PortProperty parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static net.onrc.onos.datastore.RCProtos.PortProperty parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static net.onrc.onos.datastore.RCProtos.PortProperty parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static net.onrc.onos.datastore.RCProtos.PortProperty parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static net.onrc.onos.datastore.RCProtos.PortProperty parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static net.onrc.onos.datastore.RCProtos.PortProperty parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static net.onrc.onos.datastore.RCProtos.PortProperty 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(net.onrc.onos.datastore.RCProtos.PortProperty 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 RCProtos.PortProperty}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements net.onrc.onos.datastore.RCProtos.PortPropertyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return net.onrc.onos.datastore.RCProtos.internal_static_ProtoBuffer_PortProperty_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return net.onrc.onos.datastore.RCProtos.internal_static_ProtoBuffer_PortProperty_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                net.onrc.onos.datastore.RCProtos.PortProperty.class, net.onrc.onos.datastore.RCProtos.PortProperty.Builder.class);
+      }
+
+      // Construct using net.onrc.onos.datastore.RCProtos.PortProperty.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();
+        dpid_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        number_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        status_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000004);
+        value_ = com.google.protobuf.ByteString.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000008);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return net.onrc.onos.datastore.RCProtos.internal_static_ProtoBuffer_PortProperty_descriptor;
+      }
+
+      public net.onrc.onos.datastore.RCProtos.PortProperty getDefaultInstanceForType() {
+        return net.onrc.onos.datastore.RCProtos.PortProperty.getDefaultInstance();
+      }
+
+      public net.onrc.onos.datastore.RCProtos.PortProperty build() {
+        net.onrc.onos.datastore.RCProtos.PortProperty result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public net.onrc.onos.datastore.RCProtos.PortProperty buildPartial() {
+        net.onrc.onos.datastore.RCProtos.PortProperty result = new net.onrc.onos.datastore.RCProtos.PortProperty(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.dpid_ = dpid_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.number_ = number_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.status_ = status_;
+        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+          to_bitField0_ |= 0x00000008;
+        }
+        result.value_ = value_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof net.onrc.onos.datastore.RCProtos.PortProperty) {
+          return mergeFrom((net.onrc.onos.datastore.RCProtos.PortProperty)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(net.onrc.onos.datastore.RCProtos.PortProperty other) {
+        if (other == net.onrc.onos.datastore.RCProtos.PortProperty.getDefaultInstance()) return this;
+        if (other.hasDpid()) {
+          setDpid(other.getDpid());
+        }
+        if (other.hasNumber()) {
+          setNumber(other.getNumber());
+        }
+        if (other.hasStatus()) {
+          setStatus(other.getStatus());
+        }
+        if (other.hasValue()) {
+          setValue(other.getValue());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasDpid()) {
+          
+          return false;
+        }
+        if (!hasNumber()) {
+          
+          return false;
+        }
+        if (!hasStatus()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        net.onrc.onos.datastore.RCProtos.PortProperty parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (net.onrc.onos.datastore.RCProtos.PortProperty) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required int64 dpid = 1;
+      private long dpid_ ;
+      /**
+       * <code>required int64 dpid = 1;</code>
+       */
+      public boolean hasDpid() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required int64 dpid = 1;</code>
+       */
+      public long getDpid() {
+        return dpid_;
+      }
+      /**
+       * <code>required int64 dpid = 1;</code>
+       */
+      public Builder setDpid(long value) {
+        bitField0_ |= 0x00000001;
+        dpid_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int64 dpid = 1;</code>
+       */
+      public Builder clearDpid() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        dpid_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // required int64 number = 2;
+      private long number_ ;
+      /**
+       * <code>required int64 number = 2;</code>
+       */
+      public boolean hasNumber() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required int64 number = 2;</code>
+       */
+      public long getNumber() {
+        return number_;
+      }
+      /**
+       * <code>required int64 number = 2;</code>
+       */
+      public Builder setNumber(long value) {
+        bitField0_ |= 0x00000002;
+        number_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int64 number = 2;</code>
+       */
+      public Builder clearNumber() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        number_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // required int32 status = 3;
+      private int status_ ;
+      /**
+       * <code>required int32 status = 3;</code>
+       */
+      public boolean hasStatus() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>required int32 status = 3;</code>
+       */
+      public int getStatus() {
+        return status_;
+      }
+      /**
+       * <code>required int32 status = 3;</code>
+       */
+      public Builder setStatus(int value) {
+        bitField0_ |= 0x00000004;
+        status_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 status = 3;</code>
+       */
+      public Builder clearStatus() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        status_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // optional bytes value = 4;
+      private com.google.protobuf.ByteString value_ = com.google.protobuf.ByteString.EMPTY;
+      /**
+       * <code>optional bytes value = 4;</code>
+       */
+      public boolean hasValue() {
+        return ((bitField0_ & 0x00000008) == 0x00000008);
+      }
+      /**
+       * <code>optional bytes value = 4;</code>
+       */
+      public com.google.protobuf.ByteString getValue() {
+        return value_;
+      }
+      /**
+       * <code>optional bytes value = 4;</code>
+       */
+      public Builder setValue(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000008;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bytes value = 4;</code>
+       */
+      public Builder clearValue() {
+        bitField0_ = (bitField0_ & ~0x00000008);
+        value_ = getDefaultInstance().getValue();
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:RCProtos.PortProperty)
+    }
+
+    static {
+      defaultInstance = new PortProperty(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:RCProtos.PortProperty)
+  }
+
+  public interface LinkPropertyOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required bytes srcSwId = 1;
+    /**
+     * <code>required bytes srcSwId = 1;</code>
+     */
+    boolean hasSrcSwId();
+    /**
+     * <code>required bytes srcSwId = 1;</code>
+     */
+    com.google.protobuf.ByteString getSrcSwId();
+
+    // required bytes srcPortId = 2;
+    /**
+     * <code>required bytes srcPortId = 2;</code>
+     */
+    boolean hasSrcPortId();
+    /**
+     * <code>required bytes srcPortId = 2;</code>
+     */
+    com.google.protobuf.ByteString getSrcPortId();
+
+    // required bytes dstSwId = 3;
+    /**
+     * <code>required bytes dstSwId = 3;</code>
+     */
+    boolean hasDstSwId();
+    /**
+     * <code>required bytes dstSwId = 3;</code>
+     */
+    com.google.protobuf.ByteString getDstSwId();
+
+    // required bytes dstPortId = 4;
+    /**
+     * <code>required bytes dstPortId = 4;</code>
+     */
+    boolean hasDstPortId();
+    /**
+     * <code>required bytes dstPortId = 4;</code>
+     */
+    com.google.protobuf.ByteString getDstPortId();
+
+    // required int32 status = 5;
+    /**
+     * <code>required int32 status = 5;</code>
+     */
+    boolean hasStatus();
+    /**
+     * <code>required int32 status = 5;</code>
+     */
+    int getStatus();
+
+    // optional bytes value = 6;
+    /**
+     * <code>optional bytes value = 6;</code>
+     */
+    boolean hasValue();
+    /**
+     * <code>optional bytes value = 6;</code>
+     */
+    com.google.protobuf.ByteString getValue();
+  }
+  /**
+   * Protobuf type {@code RCProtos.LinkProperty}
+   */
+  public static final class LinkProperty extends
+      com.google.protobuf.GeneratedMessage
+      implements LinkPropertyOrBuilder {
+    // Use LinkProperty.newBuilder() to construct.
+    private LinkProperty(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private LinkProperty(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final LinkProperty defaultInstance;
+    public static LinkProperty getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public LinkProperty getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private LinkProperty(
+        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;
+              srcSwId_ = input.readBytes();
+              break;
+            }
+            case 18: {
+              bitField0_ |= 0x00000002;
+              srcPortId_ = input.readBytes();
+              break;
+            }
+            case 26: {
+              bitField0_ |= 0x00000004;
+              dstSwId_ = input.readBytes();
+              break;
+            }
+            case 34: {
+              bitField0_ |= 0x00000008;
+              dstPortId_ = input.readBytes();
+              break;
+            }
+            case 40: {
+              bitField0_ |= 0x00000010;
+              status_ = input.readInt32();
+              break;
+            }
+            case 50: {
+              bitField0_ |= 0x00000020;
+              value_ = 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 net.onrc.onos.datastore.RCProtos.internal_static_ProtoBuffer_LinkProperty_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return net.onrc.onos.datastore.RCProtos.internal_static_ProtoBuffer_LinkProperty_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              net.onrc.onos.datastore.RCProtos.LinkProperty.class, net.onrc.onos.datastore.RCProtos.LinkProperty.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<LinkProperty> PARSER =
+        new com.google.protobuf.AbstractParser<LinkProperty>() {
+      public LinkProperty parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new LinkProperty(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<LinkProperty> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required bytes srcSwId = 1;
+    public static final int SRCSWID_FIELD_NUMBER = 1;
+    private com.google.protobuf.ByteString srcSwId_;
+    /**
+     * <code>required bytes srcSwId = 1;</code>
+     */
+    public boolean hasSrcSwId() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required bytes srcSwId = 1;</code>
+     */
+    public com.google.protobuf.ByteString getSrcSwId() {
+      return srcSwId_;
+    }
+
+    // required bytes srcPortId = 2;
+    public static final int SRCPORTID_FIELD_NUMBER = 2;
+    private com.google.protobuf.ByteString srcPortId_;
+    /**
+     * <code>required bytes srcPortId = 2;</code>
+     */
+    public boolean hasSrcPortId() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required bytes srcPortId = 2;</code>
+     */
+    public com.google.protobuf.ByteString getSrcPortId() {
+      return srcPortId_;
+    }
+
+    // required bytes dstSwId = 3;
+    public static final int DSTSWID_FIELD_NUMBER = 3;
+    private com.google.protobuf.ByteString dstSwId_;
+    /**
+     * <code>required bytes dstSwId = 3;</code>
+     */
+    public boolean hasDstSwId() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>required bytes dstSwId = 3;</code>
+     */
+    public com.google.protobuf.ByteString getDstSwId() {
+      return dstSwId_;
+    }
+
+    // required bytes dstPortId = 4;
+    public static final int DSTPORTID_FIELD_NUMBER = 4;
+    private com.google.protobuf.ByteString dstPortId_;
+    /**
+     * <code>required bytes dstPortId = 4;</code>
+     */
+    public boolean hasDstPortId() {
+      return ((bitField0_ & 0x00000008) == 0x00000008);
+    }
+    /**
+     * <code>required bytes dstPortId = 4;</code>
+     */
+    public com.google.protobuf.ByteString getDstPortId() {
+      return dstPortId_;
+    }
+
+    // required int32 status = 5;
+    public static final int STATUS_FIELD_NUMBER = 5;
+    private int status_;
+    /**
+     * <code>required int32 status = 5;</code>
+     */
+    public boolean hasStatus() {
+      return ((bitField0_ & 0x00000010) == 0x00000010);
+    }
+    /**
+     * <code>required int32 status = 5;</code>
+     */
+    public int getStatus() {
+      return status_;
+    }
+
+    // optional bytes value = 6;
+    public static final int VALUE_FIELD_NUMBER = 6;
+    private com.google.protobuf.ByteString value_;
+    /**
+     * <code>optional bytes value = 6;</code>
+     */
+    public boolean hasValue() {
+      return ((bitField0_ & 0x00000020) == 0x00000020);
+    }
+    /**
+     * <code>optional bytes value = 6;</code>
+     */
+    public com.google.protobuf.ByteString getValue() {
+      return value_;
+    }
+
+    private void initFields() {
+      srcSwId_ = com.google.protobuf.ByteString.EMPTY;
+      srcPortId_ = com.google.protobuf.ByteString.EMPTY;
+      dstSwId_ = com.google.protobuf.ByteString.EMPTY;
+      dstPortId_ = com.google.protobuf.ByteString.EMPTY;
+      status_ = 0;
+      value_ = com.google.protobuf.ByteString.EMPTY;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasSrcSwId()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasSrcPortId()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasDstSwId()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasDstPortId()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasStatus()) {
+        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, srcSwId_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeBytes(2, srcPortId_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeBytes(3, dstSwId_);
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        output.writeBytes(4, dstPortId_);
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        output.writeInt32(5, status_);
+      }
+      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+        output.writeBytes(6, value_);
+      }
+      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, srcSwId_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(2, srcPortId_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(3, dstSwId_);
+      }
+      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(4, dstPortId_);
+      }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(5, status_);
+      }
+      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(6, value_);
+      }
+      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 net.onrc.onos.datastore.RCProtos.LinkProperty parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static net.onrc.onos.datastore.RCProtos.LinkProperty parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static net.onrc.onos.datastore.RCProtos.LinkProperty parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static net.onrc.onos.datastore.RCProtos.LinkProperty parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static net.onrc.onos.datastore.RCProtos.LinkProperty parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static net.onrc.onos.datastore.RCProtos.LinkProperty parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static net.onrc.onos.datastore.RCProtos.LinkProperty parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static net.onrc.onos.datastore.RCProtos.LinkProperty parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static net.onrc.onos.datastore.RCProtos.LinkProperty parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static net.onrc.onos.datastore.RCProtos.LinkProperty 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(net.onrc.onos.datastore.RCProtos.LinkProperty 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 RCProtos.LinkProperty}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements net.onrc.onos.datastore.RCProtos.LinkPropertyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return net.onrc.onos.datastore.RCProtos.internal_static_ProtoBuffer_LinkProperty_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return net.onrc.onos.datastore.RCProtos.internal_static_ProtoBuffer_LinkProperty_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                net.onrc.onos.datastore.RCProtos.LinkProperty.class, net.onrc.onos.datastore.RCProtos.LinkProperty.Builder.class);
+      }
+
+      // Construct using net.onrc.onos.datastore.RCProtos.LinkProperty.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();
+        srcSwId_ = com.google.protobuf.ByteString.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        srcPortId_ = com.google.protobuf.ByteString.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        dstSwId_ = com.google.protobuf.ByteString.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000004);
+        dstPortId_ = com.google.protobuf.ByteString.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000008);
+        status_ = 0;
+        bitField0_ = (bitField0_ & ~0x00000010);
+        value_ = com.google.protobuf.ByteString.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000020);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return net.onrc.onos.datastore.RCProtos.internal_static_ProtoBuffer_LinkProperty_descriptor;
+      }
+
+      public net.onrc.onos.datastore.RCProtos.LinkProperty getDefaultInstanceForType() {
+        return net.onrc.onos.datastore.RCProtos.LinkProperty.getDefaultInstance();
+      }
+
+      public net.onrc.onos.datastore.RCProtos.LinkProperty build() {
+        net.onrc.onos.datastore.RCProtos.LinkProperty result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public net.onrc.onos.datastore.RCProtos.LinkProperty buildPartial() {
+        net.onrc.onos.datastore.RCProtos.LinkProperty result = new net.onrc.onos.datastore.RCProtos.LinkProperty(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.srcSwId_ = srcSwId_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.srcPortId_ = srcPortId_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.dstSwId_ = dstSwId_;
+        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+          to_bitField0_ |= 0x00000008;
+        }
+        result.dstPortId_ = dstPortId_;
+        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+          to_bitField0_ |= 0x00000010;
+        }
+        result.status_ = status_;
+        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
+          to_bitField0_ |= 0x00000020;
+        }
+        result.value_ = value_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof net.onrc.onos.datastore.RCProtos.LinkProperty) {
+          return mergeFrom((net.onrc.onos.datastore.RCProtos.LinkProperty)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(net.onrc.onos.datastore.RCProtos.LinkProperty other) {
+        if (other == net.onrc.onos.datastore.RCProtos.LinkProperty.getDefaultInstance()) return this;
+        if (other.hasSrcSwId()) {
+          setSrcSwId(other.getSrcSwId());
+        }
+        if (other.hasSrcPortId()) {
+          setSrcPortId(other.getSrcPortId());
+        }
+        if (other.hasDstSwId()) {
+          setDstSwId(other.getDstSwId());
+        }
+        if (other.hasDstPortId()) {
+          setDstPortId(other.getDstPortId());
+        }
+        if (other.hasStatus()) {
+          setStatus(other.getStatus());
+        }
+        if (other.hasValue()) {
+          setValue(other.getValue());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasSrcSwId()) {
+          
+          return false;
+        }
+        if (!hasSrcPortId()) {
+          
+          return false;
+        }
+        if (!hasDstSwId()) {
+          
+          return false;
+        }
+        if (!hasDstPortId()) {
+          
+          return false;
+        }
+        if (!hasStatus()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        net.onrc.onos.datastore.RCProtos.LinkProperty parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (net.onrc.onos.datastore.RCProtos.LinkProperty) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required bytes srcSwId = 1;
+      private com.google.protobuf.ByteString srcSwId_ = com.google.protobuf.ByteString.EMPTY;
+      /**
+       * <code>required bytes srcSwId = 1;</code>
+       */
+      public boolean hasSrcSwId() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required bytes srcSwId = 1;</code>
+       */
+      public com.google.protobuf.ByteString getSrcSwId() {
+        return srcSwId_;
+      }
+      /**
+       * <code>required bytes srcSwId = 1;</code>
+       */
+      public Builder setSrcSwId(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000001;
+        srcSwId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required bytes srcSwId = 1;</code>
+       */
+      public Builder clearSrcSwId() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        srcSwId_ = getDefaultInstance().getSrcSwId();
+        onChanged();
+        return this;
+      }
+
+      // required bytes srcPortId = 2;
+      private com.google.protobuf.ByteString srcPortId_ = com.google.protobuf.ByteString.EMPTY;
+      /**
+       * <code>required bytes srcPortId = 2;</code>
+       */
+      public boolean hasSrcPortId() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required bytes srcPortId = 2;</code>
+       */
+      public com.google.protobuf.ByteString getSrcPortId() {
+        return srcPortId_;
+      }
+      /**
+       * <code>required bytes srcPortId = 2;</code>
+       */
+      public Builder setSrcPortId(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000002;
+        srcPortId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required bytes srcPortId = 2;</code>
+       */
+      public Builder clearSrcPortId() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        srcPortId_ = getDefaultInstance().getSrcPortId();
+        onChanged();
+        return this;
+      }
+
+      // required bytes dstSwId = 3;
+      private com.google.protobuf.ByteString dstSwId_ = com.google.protobuf.ByteString.EMPTY;
+      /**
+       * <code>required bytes dstSwId = 3;</code>
+       */
+      public boolean hasDstSwId() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>required bytes dstSwId = 3;</code>
+       */
+      public com.google.protobuf.ByteString getDstSwId() {
+        return dstSwId_;
+      }
+      /**
+       * <code>required bytes dstSwId = 3;</code>
+       */
+      public Builder setDstSwId(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000004;
+        dstSwId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required bytes dstSwId = 3;</code>
+       */
+      public Builder clearDstSwId() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        dstSwId_ = getDefaultInstance().getDstSwId();
+        onChanged();
+        return this;
+      }
+
+      // required bytes dstPortId = 4;
+      private com.google.protobuf.ByteString dstPortId_ = com.google.protobuf.ByteString.EMPTY;
+      /**
+       * <code>required bytes dstPortId = 4;</code>
+       */
+      public boolean hasDstPortId() {
+        return ((bitField0_ & 0x00000008) == 0x00000008);
+      }
+      /**
+       * <code>required bytes dstPortId = 4;</code>
+       */
+      public com.google.protobuf.ByteString getDstPortId() {
+        return dstPortId_;
+      }
+      /**
+       * <code>required bytes dstPortId = 4;</code>
+       */
+      public Builder setDstPortId(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000008;
+        dstPortId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required bytes dstPortId = 4;</code>
+       */
+      public Builder clearDstPortId() {
+        bitField0_ = (bitField0_ & ~0x00000008);
+        dstPortId_ = getDefaultInstance().getDstPortId();
+        onChanged();
+        return this;
+      }
+
+      // required int32 status = 5;
+      private int status_ ;
+      /**
+       * <code>required int32 status = 5;</code>
+       */
+      public boolean hasStatus() {
+        return ((bitField0_ & 0x00000010) == 0x00000010);
+      }
+      /**
+       * <code>required int32 status = 5;</code>
+       */
+      public int getStatus() {
+        return status_;
+      }
+      /**
+       * <code>required int32 status = 5;</code>
+       */
+      public Builder setStatus(int value) {
+        bitField0_ |= 0x00000010;
+        status_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required int32 status = 5;</code>
+       */
+      public Builder clearStatus() {
+        bitField0_ = (bitField0_ & ~0x00000010);
+        status_ = 0;
+        onChanged();
+        return this;
+      }
+
+      // optional bytes value = 6;
+      private com.google.protobuf.ByteString value_ = com.google.protobuf.ByteString.EMPTY;
+      /**
+       * <code>optional bytes value = 6;</code>
+       */
+      public boolean hasValue() {
+        return ((bitField0_ & 0x00000020) == 0x00000020);
+      }
+      /**
+       * <code>optional bytes value = 6;</code>
+       */
+      public com.google.protobuf.ByteString getValue() {
+        return value_;
+      }
+      /**
+       * <code>optional bytes value = 6;</code>
+       */
+      public Builder setValue(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000020;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional bytes value = 6;</code>
+       */
+      public Builder clearValue() {
+        bitField0_ = (bitField0_ & ~0x00000020);
+        value_ = getDefaultInstance().getValue();
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:RCProtos.LinkProperty)
+    }
+
+    static {
+      defaultInstance = new LinkProperty(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:RCProtos.LinkProperty)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_ProtoBuffer_SwitchProperty_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_ProtoBuffer_SwitchProperty_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_ProtoBuffer_PortProperty_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_ProtoBuffer_PortProperty_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_ProtoBuffer_LinkProperty_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_ProtoBuffer_LinkProperty_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\027protobuf/ramcloud.proto\022\013ProtoBuffer\"=" +
+      "\n\016SwitchProperty\022\014\n\004dpid\030\001 \002(\003\022\016\n\006status" +
+      "\030\002 \002(\005\022\r\n\005value\030\003 \001(\014\"K\n\014PortProperty\022\014\n" +
+      "\004dpid\030\001 \002(\003\022\016\n\006number\030\002 \002(\003\022\016\n\006status\030\003 " +
+      "\002(\005\022\r\n\005value\030\004 \001(\014\"u\n\014LinkProperty\022\017\n\007sr" +
+      "cSwId\030\001 \002(\014\022\021\n\tsrcPortId\030\002 \002(\014\022\017\n\007dstSwI" +
+      "d\030\003 \002(\014\022\021\n\tdstPortId\030\004 \002(\014\022\016\n\006status\030\005 \002" +
+      "(\005\022\r\n\005value\030\006 \001(\014B&\n\027net.onrc.onos.datas" +
+      "toreB\013ProtoBuffer"
+    };
+    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_ProtoBuffer_SwitchProperty_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_ProtoBuffer_SwitchProperty_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_ProtoBuffer_SwitchProperty_descriptor,
+              new java.lang.String[] { "Dpid", "Status", "Value", });
+          internal_static_ProtoBuffer_PortProperty_descriptor =
+            getDescriptor().getMessageTypes().get(1);
+          internal_static_ProtoBuffer_PortProperty_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_ProtoBuffer_PortProperty_descriptor,
+              new java.lang.String[] { "Dpid", "Number", "Status", "Value", });
+          internal_static_ProtoBuffer_LinkProperty_descriptor =
+            getDescriptor().getMessageTypes().get(2);
+          internal_static_ProtoBuffer_LinkProperty_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_ProtoBuffer_LinkProperty_descriptor,
+              new java.lang.String[] { "SrcSwId", "SrcPortId", "DstSwId", "DstPortId", "Status", "Value", });
+          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/net/onrc/onos/datastore/topology/RCLink.java b/src/main/java/net/onrc/onos/datastore/topology/RCLink.java
index 9ce8857..79daa66 100644
--- a/src/main/java/net/onrc/onos/datastore/topology/RCLink.java
+++ b/src/main/java/net/onrc/onos/datastore/topology/RCLink.java
@@ -11,8 +11,11 @@
 import org.slf4j.LoggerFactory;
 
 import com.esotericsoftware.kryo.Kryo;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
 
 import edu.stanford.ramcloud.JRamCloud;
+import net.onrc.onos.datastore.RCProtos.LinkProperty;
 import net.onrc.onos.datastore.RCObject;
 import net.onrc.onos.datastore.RCTable;
 import net.onrc.onos.ofcontroller.networkgraph.LinkEvent;
@@ -186,7 +189,6 @@
 
     public void setStatus(STATUS status) {
 	this.status = status;
-	getObjectMap().put(PROP_STATUS, status);
     }
 
     public SwitchPort getSrc() {
@@ -205,20 +207,39 @@
     public void serializeAndSetValue() {
 	Map<Object, Object> map = getObjectMap();
 
-	map.put(PROP_SRC_SW_ID, src.getSwitchID());
-	map.put(PROP_SRC_PORT_ID, src.getPortID());
-	map.put(PROP_DST_SW_ID, dst.getSwitchID());
-	map.put(PROP_DST_PORT_ID, dst.getPortID());
-
-	serializeAndSetValue(linkKryo.get(), map);
+	LinkProperty.Builder link = LinkProperty.newBuilder();
+	link.setSrcSwId(ByteString.copyFrom(src.getSwitchID()));
+	link.setSrcPortId(ByteString.copyFrom(src.getPortID()));
+	link.setDstSwId(ByteString.copyFrom(dst.getSwitchID()));
+	link.setDstPortId(ByteString.copyFrom(dst.getPortID()));
+	link.setStatus(status.ordinal());
+	
+	if (!map.isEmpty()) {
+	    serializeAndSetValue(linkKryo.get(), map);
+	    link.setValue(ByteString.copyFrom(this.getSerializedValue()));
+	}
+	
+	this.value = link.build().toByteArray();
     }
 
     @Override
     public Map<Object, Object> deserializeObjectFromValue() {
-	Map<Object, Object> map = deserializeObjectFromValue(linkKryo.get());
-
-	this.status = (STATUS) map.get(PROP_STATUS);
-	return map;
+	LinkProperty link = null;
+	Map<Object, Object> map = null;
+	try {
+	    link = LinkProperty.parseFrom(this.value);
+	    this.value = link.getValue().toByteArray();
+	    if (this.value.length >= 1) {
+		map = deserializeObjectFromValue(linkKryo.get());
+	    } else {
+		map = new HashMap<>();
+	    }
+	    this.status = STATUS.values()[link.getStatus()];
+	    return map;
+	} catch (InvalidProtocolBufferException e) {
+	    log.error("{" + toString() + "}: Read Link: ", e);
+	    return null;
+	}	
     }
 
     @Override
diff --git a/src/main/java/net/onrc/onos/datastore/topology/RCPort.java b/src/main/java/net/onrc/onos/datastore/topology/RCPort.java
index c3cdf86..5fa5d42 100644
--- a/src/main/java/net/onrc/onos/datastore/topology/RCPort.java
+++ b/src/main/java/net/onrc/onos/datastore/topology/RCPort.java
@@ -15,8 +15,11 @@
 import org.slf4j.LoggerFactory;
 
 import com.esotericsoftware.kryo.Kryo;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
 
 import edu.stanford.ramcloud.JRamCloud;
+import net.onrc.onos.datastore.RCProtos.PortProperty;
 import net.onrc.onos.datastore.RCObject;
 import net.onrc.onos.datastore.RCTable;
 import net.onrc.onos.datastore.utils.ByteArrayComparator;
@@ -189,7 +192,6 @@
 
     public void setStatus(STATUS status) {
 	this.status = status;
-	getObjectMap().put(PROP_STATUS, status);
     }
 
     public Long getDpid() {
@@ -265,69 +267,40 @@
     }
 
     @Override
-    public void serializeAndSetValue() {
+    public void serializeAndSetValue() {	
 	Map<Object, Object> map = getObjectMap();
-
-	map.put(PROP_DPID, this.dpid);
-	map.put(PROP_NUMBER, this.number);
-	if (isLinkIdsModified) {
-	    byte[] linkIdArray[] = new byte[linkIds.size()][];
-	    map.put(PROP_LINK_IDS, linkIds.toArray(linkIdArray));
-	    isLinkIdsModified = false;
+	
+	PortProperty.Builder port = PortProperty.newBuilder();
+	port.setDpid(dpid);
+	port.setNumber(number);
+	port.setStatus(status.ordinal());
+	
+	if (!map.isEmpty()) {
+	    serializeAndSetValue(portKryo.get(), map);
+	    port.setValue(ByteString.copyFrom(this.getSerializedValue()));
 	}
-	if (isDeviceIdsModified) {
-	    byte[] deviceIdArray[] = new byte[deviceIds.size()][];
-	    map.put(PROP_DEVICE_IDS, deviceIds.toArray(deviceIdArray));
-	    isDeviceIdsModified = false;
-	}
-	if (log.isWarnEnabled() && (linkIds.size() * deviceIds.size()) != 0) {
-	    log.warn("Either #LinkIds:{} or #DeviceIds:{} is expected to be 0",
-		    linkIds.size(), deviceIds.size());
-	}
-
-	serializeAndSetValue(portKryo.get(), map);
+	
+	this.value = port.build().toByteArray();
     }
 
     @Override
     public Map<Object, Object> deserializeObjectFromValue() {
-	Map<Object, Object> map = deserializeObjectFromValue(portKryo.get());
-
-	this.status = (STATUS) map.get(PROP_STATUS);
-
-	if (this.linkIds == null) {
-	    this.linkIds = new TreeSet<>(
-		    ByteArrayComparator.BYTEARRAY_COMPARATOR);
-	}
-	byte[] linkIdArray[] = (byte[][]) map.get(PROP_LINK_IDS);
-	if (linkIdArray != null) {
-	    this.linkIds.clear();
-	    this.linkIds.addAll(Arrays.asList(linkIdArray));
-	    isLinkIdsModified = false;
-	} else {
-	    // trigger write on next serialize
-	    isLinkIdsModified = true;
-	}
-
-	if (this.deviceIds == null) {
-	    this.deviceIds = new TreeSet<>(
-		    ByteArrayComparator.BYTEARRAY_COMPARATOR);
-	}
-	byte[] deviceIdArray[] = (byte[][]) map.get(PROP_DEVICE_IDS);
-	if (deviceIdArray != null) {
-	    this.deviceIds.clear();
-	    this.deviceIds.addAll(Arrays.asList(deviceIdArray));
-	    isDeviceIdsModified = false;
-	} else {
-	    // trigger write on next serialize
-	    isDeviceIdsModified = true;
-	}
-
-	if (log.isWarnEnabled() && (linkIds.size() * deviceIds.size()) != 0) {
-	    log.warn("Either #LinkIds:{} or #DeviceIds:{} is expected to be 0",
-		    linkIds.size(), deviceIds.size());
-	}
-
-	return map;
+	PortProperty port = null;
+	Map<Object, Object> map = null;
+	try {
+	    port = PortProperty.parseFrom(this.value);
+	    this.value = port.getValue().toByteArray();
+	    if (this.value.length >= 1) {
+		map = deserializeObjectFromValue(portKryo.get());
+	    } else {
+		map = new HashMap<>();
+	    }
+	    this.status = STATUS.values()[port.getStatus()];
+	    return map;
+	} catch (InvalidProtocolBufferException e) {
+	    log.error("{" + toString() + "}: Read Port: ", e);
+	    return null;
+	}	
     }
 
     @Override
diff --git a/src/main/java/net/onrc/onos/datastore/topology/RCSwitch.java b/src/main/java/net/onrc/onos/datastore/topology/RCSwitch.java
index a0dd037..7670adf 100644
--- a/src/main/java/net/onrc/onos/datastore/topology/RCSwitch.java
+++ b/src/main/java/net/onrc/onos/datastore/topology/RCSwitch.java
@@ -21,11 +21,14 @@
 import org.slf4j.LoggerFactory;
 
 import com.esotericsoftware.kryo.Kryo;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
 
 import edu.stanford.ramcloud.JRamCloud;
 import edu.stanford.ramcloud.JRamCloud.ObjectDoesntExistException;
 import edu.stanford.ramcloud.JRamCloud.ObjectExistsException;
 import edu.stanford.ramcloud.JRamCloud.WrongVersionException;
+import net.onrc.onos.datastore.RCProtos.SwitchProperty;
 
 /**
  * Switch Object in RC.
@@ -163,7 +166,6 @@
 
     public void setStatus(STATUS status) {
 	this.status = status;
-	getObjectMap().put(PROP_STATUS, status);
     }
 
     public Long getDpid() {
@@ -210,36 +212,36 @@
     public void serializeAndSetValue() {
 	Map<Object, Object> map = getObjectMap();
 
-	map.put(PROP_DPID, this.dpid);
-	if (isPortIdsModified) {
-	    byte[] portIdArray[] = new byte[portIds.size()][];
-	    map.put(PROP_PORT_IDS, portIds.toArray(portIdArray));
-	    isPortIdsModified = false;
+	SwitchProperty.Builder sw = SwitchProperty.newBuilder();
+	sw.setDpid(dpid);
+	sw.setStatus(status.ordinal());
+	
+	if (!map.isEmpty()) {
+	    serializeAndSetValue(switchKryo.get(), map);
+	    sw.setValue(ByteString.copyFrom(this.getSerializedValue()));
 	}
-
-	serializeAndSetValue(switchKryo.get(), map);
+	
+	this.value = sw.build().toByteArray();
     }
 
     @Override
     public Map<Object, Object> deserializeObjectFromValue() {
-	Map<Object, Object> map = deserializeObjectFromValue(switchKryo.get());
-
-	this.status = (STATUS) map.get(PROP_STATUS);
-
-	if (this.portIds == null) {
-	    this.portIds = new TreeSet<>(
-		    ByteArrayComparator.BYTEARRAY_COMPARATOR);
+	SwitchProperty sw = null;
+	Map<Object, Object> map = null;
+	try {
+	    sw = SwitchProperty.parseFrom(this.value);
+	    this.value = sw.getValue().toByteArray();
+	    if (this.value.length >= 1) {
+		map = deserializeObjectFromValue(switchKryo.get());
+	    } else {
+		map = new HashMap<>();
+	    }
+	    this.status = STATUS.values()[sw.getStatus()];
+	    return map;
+	} catch (InvalidProtocolBufferException e) {
+	    log.error("{" + toString() + "}: Read Switch: ", e);
+	    return null;
 	}
-	byte[] portIdArray[] = (byte[][]) map.get(PROP_PORT_IDS);
-	if (portIdArray != null) {
-	    this.portIds.clear();
-	    this.portIds.addAll(Arrays.asList(portIdArray));
-	    isPortIdsModified = false;
-	} else {
-	    // trigger write on next serialize
-	    isPortIdsModified = true;
-	}
-	return map;
     }
 
     @Override
diff --git a/src/main/java/net/onrc/onos/intent/IntentMap.java b/src/main/java/net/onrc/onos/intent/IntentMap.java
index 53667ad..8e2e125 100644
--- a/src/main/java/net/onrc/onos/intent/IntentMap.java
+++ b/src/main/java/net/onrc/onos/intent/IntentMap.java
@@ -5,10 +5,10 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
-import java.util.Map;
 import java.util.Map.Entry;
 
 import net.onrc.onos.intent.Intent.IntentState;
+import net.onrc.onos.intent.runtime.IntentStateList;
 
 /**
  * @author Toshio Koide (t-koide@onlab.us)
@@ -88,7 +88,7 @@
 		notifyEvents();
 	}
 
-	public void changeStates(Map<String, IntentState> states) {
+	public void changeStates(IntentStateList states) {
 		for (Entry<String, IntentState> state: states.entrySet()) {
 			setState(state.getKey(), state.getValue());
 		}
@@ -167,6 +167,7 @@
 		case CREATED:
 		case INST_REQ:
 		case INST_ACK:
+		case REROUTE_REQ:
 			setState(targetIntent.getId(), IntentState.INST_NACK);
 			break;
 		case DEL_REQ:
diff --git a/src/main/java/net/onrc/onos/intent/persist/PersistIntent.java b/src/main/java/net/onrc/onos/intent/persist/PersistIntent.java
index 860b6dd..691a656 100755
--- a/src/main/java/net/onrc/onos/intent/persist/PersistIntent.java
+++ b/src/main/java/net/onrc/onos/intent/persist/PersistIntent.java
@@ -5,21 +5,19 @@
 package net.onrc.onos.intent.persist;
 
 import com.esotericsoftware.kryo.Kryo;
-import com.esotericsoftware.kryo.Serializer;
-import com.esotericsoftware.kryo.io.Input;
 import com.esotericsoftware.kryo.io.Output;
 import edu.stanford.ramcloud.JRamCloud;
 import java.io.ByteArrayOutputStream;
 import java.util.concurrent.atomic.AtomicLong;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 import net.onrc.onos.datagrid.web.IntentResource;
 import net.onrc.onos.datastore.RCTable;
 import net.onrc.onos.intent.IntentOperationList;
 import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
 import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
+import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
 import net.onrc.onos.registry.controller.IControllerRegistryService;
 import net.onrc.onos.registry.controller.IdBlock;
+import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
@@ -27,7 +25,7 @@
  * @author nickkaranatsios
  */
 public class PersistIntent {
-    private final static org.slf4j.Logger log = LoggerFactory.getLogger(IntentResource.class);
+    private final static Logger log = LoggerFactory.getLogger(IntentResource.class);
     private final static long range = 10000;
     private final IControllerRegistryService controllerRegistry;
     NetworkGraph graph = null;
@@ -45,7 +43,7 @@
         this.controllerRegistry = controllerRegistry;
         this.graph = ng.getNetworkGraph();
         table = RCTable.getTable(intentJournal);
-        stream = new ByteArrayOutputStream();
+        stream = new ByteArrayOutputStream(1024);
         output = new Output(stream);
     }
     
@@ -75,12 +73,12 @@
         // TODO call controllerRegistry.isClusterLeader()
         if (leader) {
             try {
-                System.out.println("persist operations to ramcloud");
+                System.out.println("persist operations to ramcloud size of operations: " + operations.size());
                 kryo.writeObject(output, operations);
                 output.close();
                 byte[] buffer = stream.toByteArray();
                 table.create(String.valueOf(key).getBytes(), buffer);
-                System.out.println("key is " + key);
+                System.out.println("key is " + key + " value length is " + buffer.length);
                 ret = true;
             } catch (JRamCloud.ObjectExistsException ex) {
                 log.warn("Failed to store intent journal with key " + key);
diff --git a/src/main/java/net/onrc/onos/intent/runtime/IntentStateList.java b/src/main/java/net/onrc/onos/intent/runtime/IntentStateList.java
new file mode 100644
index 0000000..4d2fc75
--- /dev/null
+++ b/src/main/java/net/onrc/onos/intent/runtime/IntentStateList.java
@@ -0,0 +1,12 @@
+package net.onrc.onos.intent.runtime;
+
+import java.util.HashMap;
+
+import net.onrc.onos.intent.Intent.IntentState;
+
+/**
+ * @author Toshio Koide (t-koide@onlab.us)
+ */
+public class IntentStateList extends HashMap<String, IntentState> {
+	private static final long serialVersionUID = -3674903999581438936L;
+}
diff --git a/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java b/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
index b559028..67902dd 100755
--- a/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
+++ b/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
@@ -6,6 +6,7 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.module.FloodlightModuleException;
@@ -13,6 +14,8 @@
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.onrc.onos.datagrid.IDatagridService;
 import net.onrc.onos.datagrid.IEventChannel;
+import net.onrc.onos.datagrid.IEventChannelListener;
+import net.onrc.onos.intent.Intent;
 import net.onrc.onos.intent.Intent.IntentState;
 import net.onrc.onos.intent.IntentMap;
 import net.onrc.onos.intent.IntentOperation;
@@ -20,6 +23,7 @@
 import net.onrc.onos.intent.IntentOperationList;
 import net.onrc.onos.intent.PathIntent;
 import net.onrc.onos.intent.PathIntentMap;
+import net.onrc.onos.intent.ShortestPathIntent;
 import net.onrc.onos.intent.persist.PersistIntent;
 import net.onrc.onos.ofcontroller.networkgraph.DeviceEvent;
 import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphListener;
@@ -32,7 +36,7 @@
 /**
  * @author Toshio Koide (t-koide@onlab.us)
  */
-public class PathCalcRuntimeModule implements IFloodlightModule, IPathCalcRuntimeService, INetworkGraphListener {
+public class PathCalcRuntimeModule implements IFloodlightModule, IPathCalcRuntimeService, INetworkGraphListener, IEventChannelListener<Long, IntentStateList> {
 	private PathCalcRuntime runtime;
 	private IDatagridService datagridService;
 	private INetworkGraphService networkGraphService;
@@ -41,8 +45,9 @@
 	private IControllerRegistryService controllerRegistry;
 	private PersistIntent persistIntent;
 
-	private IEventChannel<Long, IntentOperationList> eventChannel;
-	private static final String EVENT_CHANNEL_NAME = "onos.pathintent";
+	private IEventChannel<Long, IntentOperationList> opEventChannel;
+	private static final String INTENT_OP_EVENT_CHANNEL_NAME = "onos.pathintent";
+	private static final String INTENT_STATE_EVENT_CHANNEL_NAME = "onos.pathintent_state";
 
 	// ================================================================================
 	// private methods
@@ -105,10 +110,10 @@
 		highLevelIntents = new IntentMap();
 		runtime = new PathCalcRuntime(networkGraphService.getNetworkGraph());
 		pathIntents = new PathIntentMap();
-		eventChannel = datagridService.createChannel(EVENT_CHANNEL_NAME, Long.class, IntentOperationList.class);
+		opEventChannel = datagridService.createChannel(INTENT_OP_EVENT_CHANNEL_NAME, Long.class, IntentOperationList.class);
+		datagridService.addListener(INTENT_STATE_EVENT_CHANNEL_NAME, this, Long.class, IntentStateList.class);
 		networkGraphService.registerNetworkGraphListener(this);
 		persistIntent = new PersistIntent(controllerRegistry, networkGraphService);
-
 	}
 
 	// ================================================================================
@@ -121,7 +126,7 @@
 		highLevelIntents.executeOperations(list);
 
 		// change states of high-level intents
-		HashMap<String, IntentState> states = new HashMap<>();
+		IntentStateList states = new IntentStateList();
 		for (IntentOperation op : list) {
 			String id = op.intent.getId();
 			if (op.intent.getState().equals(IntentState.INST_ACK))
@@ -161,7 +166,7 @@
 				op.intent = pathIntents.getIntent(op.intent.getId());
 			}
 		}
-		eventChannel.addEntry(key, pathIntentOperations);
+		opEventChannel.addEntry(key, pathIntentOperations);
 		return pathIntentOperations;
 	}
 
@@ -194,8 +199,51 @@
 			Collection<LinkEvent> removedLinkEvents,
 			Collection<DeviceEvent> addedDeviceEvents,
 			Collection<DeviceEvent> removedDeviceEvents) {
-		// TODO need optimization.
-		// Only high-level intents that affected by link down are rerouted.
+		// TODO add getIntentsByPort() and getIntentsBySwitch() to PathIntentMap.
 		reroutePaths(removedLinkEvents);
 	}
+
+	// ================================================================================
+	// IEventChannelListener implementations
+	// ================================================================================
+
+	@Override
+	public void entryAdded(IntentStateList value) {
+		entryUpdated(value);
+	}
+
+	@Override
+	public void entryRemoved(IntentStateList value) {
+		// do nothing
+	}
+
+	@Override
+	public void entryUpdated(IntentStateList value) {
+		// reflect state changes of path-level intent into application-level intents
+		IntentStateList parentStates = new IntentStateList();
+		for (Entry<String, IntentState> entry: value.entrySet()) {
+			PathIntent pathIntent = (PathIntent) pathIntents.getIntent(entry.getKey());
+			if (pathIntent == null) continue;
+
+			Intent parentIntent = pathIntent.getParentIntent();
+			if (parentIntent == null ||
+					!(parentIntent instanceof ShortestPathIntent) ||
+					!((ShortestPathIntent) parentIntent).getPathIntentId().equals(pathIntent.getId()))
+				continue;
+
+			IntentState state = entry.getValue();
+			switch (state) {
+			case INST_ACK:
+			case INST_NACK:
+			case DEL_ACK:
+			case DEL_PENDING:
+				parentStates.put(parentIntent.getId(), state);
+				break;
+			default:
+				break;
+			}
+		}
+		highLevelIntents.changeStates(parentStates);
+		pathIntents.changeStates(value);
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/serializers/KryoFactory.java b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/KryoFactory.java
index 07b173d..df93614 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/serializers/KryoFactory.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/serializers/KryoFactory.java
@@ -12,6 +12,7 @@
 import net.onrc.onos.intent.IntentOperationList;
 import net.onrc.onos.intent.PathIntent;
 import net.onrc.onos.intent.ShortestPathIntent;
+import net.onrc.onos.intent.runtime.IntentStateList;
 import net.onrc.onos.ofcontroller.networkgraph.DeviceEvent;
 import net.onrc.onos.ofcontroller.networkgraph.LinkEvent;
 import net.onrc.onos.ofcontroller.networkgraph.Path;
@@ -44,6 +45,7 @@
 import net.onrc.onos.ofcontroller.util.Switch;
 // import net.onrc.onos.ofcontroller.util.SwitchPort;
 
+
 import com.esotericsoftware.kryo.Kryo;
 
 /**
@@ -186,6 +188,7 @@
 	kryo.register(Intent.IntentState.class);
 	kryo.register(Path.class);
 	kryo.register(IntentOperation.Operator.class);
+	kryo.register(IntentStateList.class);
 
 	return kryo;
     }
diff --git a/src/main/protobuf/ramcloud.proto b/src/main/protobuf/ramcloud.proto
new file mode 100644
index 0000000..68a7263
--- /dev/null
+++ b/src/main/protobuf/ramcloud.proto
@@ -0,0 +1,26 @@
+package RCProtos;
+
+option java_package = "net.onrc.onos.datastore";
+option java_outer_classname = "RCProtos";
+
+message SwitchProperty {
+  required int64 dpid = 1;
+  required int32 status = 2;
+  optional bytes value = 3;
+}
+
+message PortProperty {
+  required int64 dpid = 1;
+  required int64 number = 2;
+  required int32 status = 3;
+  optional bytes value = 4;
+}
+
+message LinkProperty {
+  required bytes srcSwId = 1;
+  required bytes srcPortId = 2;
+  required bytes dstSwId = 3;
+  required bytes dstPortId = 4;
+  required int32 status = 5;
+  optional bytes value = 6;
+}
diff --git a/src/test/java/net/onrc/onos/intent/ConstrainedShortestPathIntentTest.java b/src/test/java/net/onrc/onos/intent/ConstrainedShortestPathIntentTest.java
index 354e053..e8759b1 100644
--- a/src/test/java/net/onrc/onos/intent/ConstrainedShortestPathIntentTest.java
+++ b/src/test/java/net/onrc/onos/intent/ConstrainedShortestPathIntentTest.java
@@ -11,6 +11,9 @@
 import com.esotericsoftware.kryo.io.Input;
 import com.esotericsoftware.kryo.io.Output;
 
+/**
+ * @author Toshio Koide (t-koide@onlab.us)
+ */
 public class ConstrainedShortestPathIntentTest {
 	NetworkGraph g;
 
diff --git a/src/test/java/net/onrc/onos/intent/IntentMapTest.java b/src/test/java/net/onrc/onos/intent/IntentMapTest.java
index bad546d..b636167 100644
--- a/src/test/java/net/onrc/onos/intent/IntentMapTest.java
+++ b/src/test/java/net/onrc/onos/intent/IntentMapTest.java
@@ -1,12 +1,21 @@
 package net.onrc.onos.intent;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import net.onrc.onos.intent.ErrorIntent.ErrorType;
 import net.onrc.onos.intent.Intent.IntentState;
+import net.onrc.onos.intent.IntentMap.ChangedEventType;
+import net.onrc.onos.intent.IntentOperation.Operator;
+import net.onrc.onos.intent.runtime.IntentStateList;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
+/**
+ * @author Toshio Koide (t-koide@onlab.us)
+ */
 public class IntentMapTest {
 
 	@Before
@@ -18,55 +27,212 @@
 	}
 
 	@Test
-	public void test() {
+	public void testCreate() {
 		IntentMap intents = new IntentMap();
-		IntentOperationList operations = new IntentOperationList();
+		assertEquals(0, intents.getAllIntents().size());
+	}
 
-		// add three intents
+	@Test
+	public void testChangedEventCreate() {
+		IntentMap intents = new IntentMap();
+		IntentMap.ChangedEvent event = intents.new ChangedEvent(
+				ChangedEventType.ADDED,
+				new Intent("id1"));
+		assertEquals(ChangedEventType.ADDED, event.eventType);
+		assertEquals("id1", event.intent.getId());
+	}
 
-		ShortestPathIntent intent1 =
-				new ShortestPathIntent("1", 11L, 12L, 13L, 14L, 15L, 16L);
+	@Test
+	public void testAddOperations() {
+		IntentMap intents = new IntentMap();
+		assertEquals(0, intents.getAllIntents().size());
+
+		Intent intent1 = new Intent("1");
 		ShortestPathIntent intent2 =
 				new ShortestPathIntent("2", 21L, 22L, 23L, 24L, 25L, 26L);
 		ConstrainedShortestPathIntent intent3 =
 				new ConstrainedShortestPathIntent("3", 31L, 32L, 33L, 34L, 35L, 36L, 1000.0);
 
-		operations.add(new IntentOperation(IntentOperation.Operator.ADD, intent1));
-		operations.add(new IntentOperation(IntentOperation.Operator.ADD, intent2));
-		operations.add(new IntentOperation(IntentOperation.Operator.ADD, intent3));
+		IntentOperationList operations = new IntentOperationList();
+		operations.add(Operator.ADD, intent1);
+		operations.add(Operator.ADD, intent2);
+		operations.add(Operator.ADD, intent3);
+		assertEquals(3, operations.size());
+
 		intents.executeOperations(operations);
-
-		// check
-
 		assertEquals(3, intents.getAllIntents().size());
-		assertEquals(intent1, intents.getIntent("1"));
-		assertEquals(intent2, intents.getIntent("2"));
-		assertEquals(intent3, intents.getIntent("3"));
+		assertSame(intent1, intents.getIntent("1"));
+		assertSame(intent2, intents.getIntent("2"));
+		assertSame(intent3, intents.getIntent("3"));
+	}
 
-		// request removal of an intent
+	@Test
+	public void testAddOperationsOverwrite() {
+		IntentMap intents = new IntentMap();
 
+		Intent intent1 = new Intent("1");
+		Intent intent2 = new Intent("2");
+		Intent intent3 = new Intent("3");
 		Intent intent4 = new Intent("1");
+		Intent intent5 = new Intent("2");
+		Intent intent6 = new Intent("4");
+
+		IntentOperationList operations = new IntentOperationList();
+		operations.add(Operator.ADD, intent1);
+		operations.add(Operator.ADD, intent2);
+		operations.add(Operator.ADD, intent3);
+		assertEquals(3, operations.size());
+
+		intents.executeOperations(operations);
+		assertEquals(3, intents.getAllIntents().size());
+		assertSame(intent1, intents.getIntent("1"));
+		assertSame(intent2, intents.getIntent("2"));
+		assertSame(intent3, intents.getIntent("3"));
+
 		operations.clear();
-		operations.add(new IntentOperation(IntentOperation.Operator.REMOVE, intent4));
+		operations.add(Operator.ADD, intent4);
+		operations.add(Operator.ADD, intent5);
+		operations.add(Operator.ADD, intent6);
+		assertEquals(3, operations.size());
+
+		intents.executeOperations(operations);
+		assertEquals(4, intents.getAllIntents().size());
+		assertSame(intent4, intents.getIntent("1"));
+		assertSame(intent5, intents.getIntent("2"));
+		assertSame(intent3, intents.getIntent("3"));
+		assertSame(intent6, intents.getIntent("4"));
+	}
+
+	@Test
+	public void testRemoveOperation() {
+		IntentMap intents = new IntentMap();
+
+		Intent intent1 = new Intent("1");
+		ShortestPathIntent intent2 =
+				new ShortestPathIntent("2", 21L, 22L, 23L, 24L, 25L, 26L);
+		ConstrainedShortestPathIntent intent3 =
+				new ConstrainedShortestPathIntent("3", 31L, 32L, 33L, 34L, 35L, 36L, 1000.0);
+
+		IntentOperationList operations = new IntentOperationList();
+		operations.add(Operator.ADD, intent1);
+		operations.add(Operator.ADD, intent2);
+		operations.add(Operator.ADD, intent3);
+		intents.executeOperations(operations);
+		assertEquals(3, intents.getAllIntents().size());
+		assertSame(intent1, intents.getIntent("1"));
+		assertSame(intent2, intents.getIntent("2"));
+		assertSame(intent3, intents.getIntent("3"));
+
+		operations.clear();
+		operations.add(Operator.REMOVE, new Intent("1"));
+		operations.add(Operator.REMOVE, new Intent("3"));
+		intents.executeOperations(operations);
+		assertEquals(3, intents.getAllIntents().size());
+		assertSame(intent1, intents.getIntent("1"));
+		assertSame(intent2, intents.getIntent("2"));
+		assertSame(intent3, intents.getIntent("3"));
+		assertEquals(IntentState.DEL_REQ, intents.getIntent("1").getState());
+		assertEquals(IntentState.CREATED, intents.getIntent("2").getState());
+		assertEquals(IntentState.DEL_REQ, intents.getIntent("3").getState());
+	}
+
+	@Test
+	public void testErrorOperation() {
+		IntentMap intents = new IntentMap();
+		IntentOperationList operations = new IntentOperationList();
+		operations.add(Operator.ADD, new Intent("1", IntentState.CREATED));
+		operations.add(Operator.ADD, new Intent("2", IntentState.INST_REQ));
+		operations.add(Operator.ADD, new Intent("3", IntentState.INST_ACK));
+		operations.add(Operator.ADD, new Intent("4", IntentState.INST_NACK));
+		operations.add(Operator.ADD, new Intent("5", IntentState.REROUTE_REQ));
+		operations.add(Operator.ADD, new Intent("6", IntentState.DEL_REQ));
+		operations.add(Operator.ADD, new Intent("7", IntentState.DEL_ACK));
+		operations.add(Operator.ADD, new Intent("8", IntentState.DEL_PENDING));
+		intents.executeOperations(operations);
+		assertEquals(8, intents.getAllIntents().size());
+
+		operations.clear();
+		operations.add(Operator.ERROR, new ErrorIntent(ErrorType.PATH_NOT_FOUND, "", new Intent("1")));
+		operations.add(Operator.ERROR, new ErrorIntent(ErrorType.PATH_NOT_FOUND, "", new Intent("2")));
+		operations.add(Operator.ERROR, new ErrorIntent(ErrorType.PATH_NOT_FOUND, "", new Intent("3")));
+		operations.add(Operator.ERROR, new ErrorIntent(ErrorType.PATH_NOT_FOUND, "", new Intent("4")));
+		operations.add(Operator.ERROR, new ErrorIntent(ErrorType.PATH_NOT_FOUND, "", new Intent("5")));
+		operations.add(Operator.ERROR, new ErrorIntent(ErrorType.PATH_NOT_FOUND, "", new Intent("6")));
+		operations.add(Operator.ERROR, new ErrorIntent(ErrorType.PATH_NOT_FOUND, "", new Intent("7")));
+		operations.add(Operator.ERROR, new ErrorIntent(ErrorType.PATH_NOT_FOUND, "", new Intent("8")));
 		intents.executeOperations(operations);
 
-		// check
+		assertEquals(IntentState.INST_NACK, intents.getIntent("1").getState());
+		assertEquals(IntentState.INST_NACK, intents.getIntent("2").getState());
+		assertEquals(IntentState.INST_NACK, intents.getIntent("3").getState());
+		assertEquals(IntentState.INST_NACK, intents.getIntent("4").getState());
+		assertEquals(IntentState.INST_NACK, intents.getIntent("5").getState());
+		assertEquals(IntentState.DEL_PENDING, intents.getIntent("6").getState());
+		assertEquals(IntentState.DEL_ACK, intents.getIntent("7").getState());
+		assertEquals(IntentState.DEL_PENDING, intents.getIntent("8").getState());
+	}
 
-		assertEquals(3, intents.getAllIntents().size());
-		assertEquals(IntentState.DEL_REQ, intent1.getState());
-
-		// change intents' state which will be purged 
-
-		intent2.setState(IntentState.INST_NACK);
-		intent3.setState(IntentState.DEL_ACK);
-
-		// purge
+	@Test
+	public void testPurge() {
+		IntentMap intents = new IntentMap();
+		IntentOperationList operations = new IntentOperationList();
+		operations.add(Operator.ADD, new Intent("1", IntentState.CREATED));
+		operations.add(Operator.ADD, new Intent("2", IntentState.INST_REQ));
+		operations.add(Operator.ADD, new Intent("3", IntentState.INST_ACK));
+		operations.add(Operator.ADD, new Intent("4", IntentState.INST_NACK));
+		operations.add(Operator.ADD, new Intent("5", IntentState.REROUTE_REQ));
+		operations.add(Operator.ADD, new Intent("6", IntentState.DEL_REQ));
+		operations.add(Operator.ADD, new Intent("7", IntentState.DEL_ACK));
+		operations.add(Operator.ADD, new Intent("8", IntentState.DEL_PENDING));
+		intents.executeOperations(operations);
+		assertEquals(8, intents.getAllIntents().size());
 
 		intents.purge();
 
-		// check
+		assertEquals(6, intents.getAllIntents().size());
+		assertEquals("1", intents.getIntent("1").getId());
+		assertEquals("2", intents.getIntent("2").getId());
+		assertEquals("3", intents.getIntent("3").getId());
+		assertNull(intents.getIntent("4"));
+		assertEquals("5", intents.getIntent("5").getId());
+		assertEquals("6", intents.getIntent("6").getId());
+		assertNull("7", intents.getIntent("7"));
+		assertEquals("8", intents.getIntent("8").getId());
+	}
 
-		assertEquals(1, intents.getAllIntents().size());
-		assertEquals("1", intents.getAllIntents().iterator().next().getId());
+	@Test
+	public void testChangeStates() {
+		IntentMap intents = new IntentMap();
+		IntentOperationList operations = new IntentOperationList();
+		operations.add(Operator.ADD, new Intent("1", IntentState.CREATED));
+		operations.add(Operator.ADD, new Intent("2", IntentState.INST_REQ));
+		operations.add(Operator.ADD, new Intent("3", IntentState.INST_ACK));
+		operations.add(Operator.ADD, new Intent("4", IntentState.INST_NACK));
+		operations.add(Operator.ADD, new Intent("5", IntentState.REROUTE_REQ));
+		operations.add(Operator.ADD, new Intent("6", IntentState.DEL_REQ));
+		operations.add(Operator.ADD, new Intent("7", IntentState.DEL_ACK));
+		operations.add(Operator.ADD, new Intent("8", IntentState.DEL_PENDING));
+		intents.executeOperations(operations);
+		assertEquals(8, intents.getAllIntents().size());
+
+		IntentStateList states = new IntentStateList();
+		states.put("8", IntentState.CREATED);
+		states.put("1", IntentState.INST_REQ);
+		states.put("2", IntentState.INST_ACK);
+		states.put("3", IntentState.INST_NACK);
+		states.put("4", IntentState.REROUTE_REQ);
+		states.put("5", IntentState.DEL_REQ);
+		states.put("6", IntentState.DEL_ACK);
+		states.put("7", IntentState.DEL_PENDING);
+		intents.changeStates(states);
+
+		assertEquals(IntentState.INST_REQ, intents.getIntent("1").getState());
+		assertEquals(IntentState.INST_ACK, intents.getIntent("2").getState());
+		assertEquals(IntentState.INST_NACK, intents.getIntent("3").getState());
+		assertEquals(IntentState.REROUTE_REQ, intents.getIntent("4").getState());
+		assertEquals(IntentState.DEL_REQ, intents.getIntent("5").getState());
+		assertEquals(IntentState.DEL_ACK, intents.getIntent("6").getState());
+		assertEquals(IntentState.DEL_PENDING, intents.getIntent("7").getState());
+		assertEquals(IntentState.CREATED, intents.getIntent("8").getState());
 	}
 }
diff --git a/src/test/java/net/onrc/onos/intent/IntentOperationListTest.java b/src/test/java/net/onrc/onos/intent/IntentOperationListTest.java
index ad5315b..e0e907f 100644
--- a/src/test/java/net/onrc/onos/intent/IntentOperationListTest.java
+++ b/src/test/java/net/onrc/onos/intent/IntentOperationListTest.java
@@ -13,6 +13,9 @@
 import com.esotericsoftware.kryo.io.Input;
 import com.esotericsoftware.kryo.io.Output;
 
+/**
+ * @author Toshio Koide (t-koide@onlab.us)
+ */
 public class IntentOperationListTest {
 
 	@Before
diff --git a/src/test/java/net/onrc/onos/intent/MockNetworkGraph.java b/src/test/java/net/onrc/onos/intent/MockNetworkGraph.java
index a8f928a..5ae7b13 100644
--- a/src/test/java/net/onrc/onos/intent/MockNetworkGraph.java
+++ b/src/test/java/net/onrc/onos/intent/MockNetworkGraph.java
@@ -8,6 +8,9 @@
 import net.onrc.onos.ofcontroller.networkgraph.Switch;
 import net.onrc.onos.ofcontroller.networkgraph.SwitchImpl;
 
+/**
+ * @author Toshio Koide (t-koide@onlab.us)
+ */
 public class MockNetworkGraph extends NetworkGraphImpl {
 	class DetachableLinkImpl extends LinkImpl {
 		public DetachableLinkImpl(NetworkGraph graph, Port srcPort, Port dstPort) {
@@ -16,7 +19,7 @@
 
 		public void detachFromGraph() {
 			unsetFromPorts();
-		}	
+		}
 	}
 	public Switch addSwitch(Long switchId) {
 		SwitchImpl sw = new SwitchImpl(this, switchId);
@@ -39,7 +42,7 @@
 
 		return links;
 	}
-	
+
 	public void createSampleTopology() {
 		// add 10 switches (24 ports switch)
 		for (Long dpid=1L; dpid<10L; dpid++) {
diff --git a/src/test/java/net/onrc/onos/intent/PathIntentTest.java b/src/test/java/net/onrc/onos/intent/PathIntentTest.java
index 3c76f3f..211a68a 100644
--- a/src/test/java/net/onrc/onos/intent/PathIntentTest.java
+++ b/src/test/java/net/onrc/onos/intent/PathIntentTest.java
@@ -14,6 +14,9 @@
 import com.esotericsoftware.kryo.io.Input;
 import com.esotericsoftware.kryo.io.Output;
 
+/**
+ * @author Toshio Koide (t-koide@onlab.us)
+ */
 public class PathIntentTest {
 	NetworkGraph g;
 
diff --git a/src/test/java/net/onrc/onos/intent/ShortestPathIntentTest.java b/src/test/java/net/onrc/onos/intent/ShortestPathIntentTest.java
index e325be8..e118b66 100644
--- a/src/test/java/net/onrc/onos/intent/ShortestPathIntentTest.java
+++ b/src/test/java/net/onrc/onos/intent/ShortestPathIntentTest.java
@@ -11,6 +11,9 @@
 import com.esotericsoftware.kryo.io.Input;
 import com.esotericsoftware.kryo.io.Output;
 
+/**
+ * @author Toshio Koide (t-koide@onlab.us)
+ */
 public class ShortestPathIntentTest {
 	NetworkGraph g;
 
diff --git a/src/test/java/net/onrc/onos/intent/runtime/UseCaseTest.java b/src/test/java/net/onrc/onos/intent/runtime/UseCaseTest.java
index 00da877..cb4ab9e 100755
--- a/src/test/java/net/onrc/onos/intent/runtime/UseCaseTest.java
+++ b/src/test/java/net/onrc/onos/intent/runtime/UseCaseTest.java
@@ -1,6 +1,7 @@
 package net.onrc.onos.intent.runtime;
 
-import java.util.HashMap;
+import static org.easymock.EasyMock.*;
+
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
@@ -9,12 +10,12 @@
 import net.floodlightcontroller.core.module.FloodlightModuleException;
 import net.onrc.onos.datagrid.IDatagridService;
 import net.onrc.onos.datagrid.IEventChannel;
+import net.onrc.onos.datagrid.IEventChannelListener;
 import net.onrc.onos.intent.ConstrainedShortestPathIntent;
 import net.onrc.onos.intent.FlowEntry;
 import net.onrc.onos.intent.Intent;
 import net.onrc.onos.intent.Intent.IntentState;
 import net.onrc.onos.intent.IntentOperation.Operator;
-import net.onrc.onos.intent.IntentOperation;
 import net.onrc.onos.intent.IntentOperationList;
 import net.onrc.onos.intent.MockNetworkGraph;
 import net.onrc.onos.intent.PathIntent;
@@ -30,7 +31,6 @@
 import net.onrc.onos.ofcontroller.networkgraph.SwitchEvent;
 import net.onrc.onos.registry.controller.IControllerRegistryService;
 
-import org.easymock.EasyMock;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -61,47 +61,54 @@
 		graph.createSampleTopology();
 		g = graph;
 
-		datagridService = EasyMock.createMock(IDatagridService.class);
-		networkGraphService = EasyMock.createMock(INetworkGraphService.class);
-		controllerRegistryService = EasyMock.createMock(IControllerRegistryService.class);
-		modContext = EasyMock.createMock(FloodlightModuleContext.class);
-		eventChannel = EasyMock.createMock(IEventChannel.class);
+		datagridService = createMock(IDatagridService.class);
+		networkGraphService = createMock(INetworkGraphService.class);
+		controllerRegistryService = createMock(IControllerRegistryService.class);
+		modContext = createMock(FloodlightModuleContext.class);
+		eventChannel = createMock(IEventChannel.class);
 		persistIntent = PowerMock.createMock(PersistIntent.class);
 
 		PowerMock.expectNew(PersistIntent.class,
-				EasyMock.anyObject(IControllerRegistryService.class),
-				EasyMock.anyObject(INetworkGraphService.class)).andReturn(persistIntent);
+				anyObject(IControllerRegistryService.class),
+				anyObject(INetworkGraphService.class)).andReturn(persistIntent);
 
-		EasyMock.expect(modContext.getServiceImpl(EasyMock.eq(IDatagridService.class)))
+		expect(modContext.getServiceImpl(IDatagridService.class))
 		.andReturn(datagridService).once();
-		EasyMock.expect(modContext.getServiceImpl(EasyMock.eq(INetworkGraphService.class)))
+		expect(modContext.getServiceImpl(INetworkGraphService.class))
 		.andReturn(networkGraphService).once();
-		EasyMock.expect(modContext.getServiceImpl(EasyMock.eq(IControllerRegistryService.class)))
+		expect(modContext.getServiceImpl(IControllerRegistryService.class))
 		.andReturn(controllerRegistryService).once();
-		EasyMock.expect(persistIntent.getKey()).andReturn(1L).anyTimes();
-		EasyMock.expect(persistIntent.persistIfLeader(EasyMock.eq(1L),
-				EasyMock.anyObject(IntentOperationList.class))).andReturn(true).anyTimes();
+		expect(persistIntent.getKey()).andReturn(1L).anyTimes();
+		expect(persistIntent.persistIfLeader(eq(1L),
+				anyObject(IntentOperationList.class))).andReturn(true).anyTimes();
 
-		EasyMock.expect(networkGraphService.getNetworkGraph()).andReturn(g).anyTimes();
-		networkGraphService.registerNetworkGraphListener(EasyMock.anyObject(INetworkGraphListener.class));
-		EasyMock.expectLastCall();
+		expect(networkGraphService.getNetworkGraph()).andReturn(g).anyTimes();
+		networkGraphService.registerNetworkGraphListener(anyObject(INetworkGraphListener.class));
+		expectLastCall();
 
-		EasyMock.expect(datagridService.createChannel("onos.pathintent", Long.class, IntentOperationList.class))
+		expect(datagridService.createChannel("onos.pathintent", Long.class, IntentOperationList.class))
 		.andReturn(eventChannel).once();
 
-		EasyMock.replay(datagridService);
-		EasyMock.replay(networkGraphService);
-		EasyMock.replay(modContext);
-		EasyMock.replay(controllerRegistryService);
+		expect(datagridService.addListener(
+				eq("onos.pathintent_state"),
+				anyObject(IEventChannelListener.class),
+				eq(Long.class),
+				eq(IntentStateList.class)))
+		.andReturn(eventChannel).once();
+
+		replay(datagridService);
+		replay(networkGraphService);
+		replay(modContext);
+		replay(controllerRegistryService);
 		PowerMock.replay(persistIntent, PersistIntent.class);
 	}
 
 	@After
 	public void tearDown() {
-		EasyMock.verify(datagridService);
-		EasyMock.verify(networkGraphService);
-		EasyMock.verify(modContext);
-		EasyMock.verify(controllerRegistryService);
+		verify(datagridService);
+		verify(networkGraphService);
+		verify(modContext);
+		verify(controllerRegistryService);
 		PowerMock.verify(persistIntent, PersistIntent.class);
 	}
 
@@ -221,7 +228,7 @@
 		System.out.println(plan);
 
 		// TODO this state changes should be triggered by notification of plan module
-		HashMap<String, IntentState> states = new HashMap<>();
+		IntentStateList states = new IntentStateList();
 		states.put("1", IntentState.INST_ACK);
 		states.put("2", IntentState.INST_ACK);
 		states.put("3", IntentState.INST_ACK);
diff --git a/test-network/mininet/mesh_topology.py b/test-network/mininet/mesh_topology.py
new file mode 100755
index 0000000..5cd8091
--- /dev/null
+++ b/test-network/mininet/mesh_topology.py
@@ -0,0 +1,118 @@
+#!/usr/bin/python
+"""Custom topology example
+
+Two directly connected switches plus a host for each switch:
+
+   host --- switch --- switch --- host
+
+Adding the 'topos' dict with a key/value pair to generate our newly defined
+topology enables one to pass in '--topo=mytopo' from the command line.
+"""
+
+import sys, getopt
+from mininet.net import Mininet
+from mininet.node import Controller, RemoteController
+from mininet.log import setLogLevel, info, error, warn, debug
+from mininet.topo import Topo
+from mininet.link import Link, TCLink
+from mininet.util import dumpNodeConnections
+
+class MyController( Controller ):
+    def __init__( self, name, ip='127.0.0.1', port=6633, **kwargs):
+        """Init.
+           name: name to give controller
+           ip: the IP address where the remote controller is
+           listening
+           port: the port where the remote controller is listening"""
+        Controller.__init__( self, name, ip=ip, port=port, **kwargs )
+
+    def start( self ):
+        "Overridden to do nothing."
+        return
+
+    def stop( self ):
+        "Overridden to do nothing."
+        return
+
+    def checkListening( self ):
+        "Warn if remote controller is not accessible"
+        listening = self.cmd( "echo A | telnet -e A %s %d" %
+                              ( self.ip, self.port ) )
+        if 'Unable' in listening:
+            warn( "Unable to contact the remote controller"
+                  " at %s:%d\n" % ( self.ip, self.port ) )
+
+
+class MyTopo( Topo ):
+    "Simple topology example."
+
+    def __init__( self, max_switches ):
+        "Create custom topo."
+
+        # Initialize topology
+        Topo.__init__( self )
+
+        installed_switches = {}
+        # add switches first
+        for sw in range( max_switches ):
+          sw_str = "sw" + `sw + 1`
+          msw = self.addSwitch( sw_str )
+          installed_switches[sw_str] = msw
+        
+        # create links between switches
+        for sw in range( max_switches ):
+          next_sw = sw + 1
+          for link in range( next_sw, max_switches ):
+            link_from = "sw" + `next_sw`
+            link_to = "sw" + `link + 1`
+            print "link_from ", link_from, " link to ", link_to
+            self.addLink( link_from, link_to )
+
+        # finally add links to hosts
+        for sw in range( max_switches ):
+          sw_str = "sw" + `sw + 1`
+          host_str = "h" + `sw + 1`
+          mhost = self.addHost( host_str )
+          msw = installed_switches[sw_str]
+          self.addLink( msw, mhost)
+
+def main(argv):
+  max_switches = ""
+  try:
+    opts,args = getopt.getopt(argv, "hs:", ["help", "switches="])
+  except getopt.GetoptError:
+    print "Usage mesh_topology.py [options]"
+    print "-s, --switches number of switches to set"
+    sys.exit(2)
+  for opt, arg in opts:
+    if opt == '-h':
+      print "Usage mesh_topology.py [options]"
+      print "-s, --switches number of switches to set"
+      sys.exit()
+    elif opt in ("-s", "--switches"):
+      max_switches = arg
+
+  switches = 4
+  if max_switches != "":
+    switches = int(max_switches)
+  topos = { 'mytopo': ( lambda: MyTopo(switches) ) }
+  net = Mininet(topo=MyTopo(switches), controller=MyController, link=TCLink)
+  print dumpNodeConnections(net.switches)
+
+  for sw in range(switches):
+    next_sw = sw + 1
+    mhost = "h" + `next_sw`
+    host = net.get( mhost )
+    if next_sw > 255:
+      divisor = next_sw / 256
+      remainder = next_sw % 256
+      host.setMAC('00:00:%02x:%02x:%02x:%02x' % (192, 168, divisor, remainder)) 
+      print "Host", host.name, "has IP address", host.IP(), "and MAC address", host.MAC()
+    else:
+      host.setMAC('00:00:%02x:%02x:%02x:%02x' % (192, 168, 0, next_sw)) 
+      print "Host", host.name, "has IP address", host.IP(), "and MAC address", host.MAC()
+    
+  net.start()
+
+if __name__ == "__main__":
+  main(sys.argv[1:])
diff --git a/web/rest-intent/add-get-intent.rb b/web/rest-intent/add-get-intent.rb
index 55c8f94..ea3a506 100644
--- a/web/rest-intent/add-get-intent.rb
+++ b/web/rest-intent/add-get-intent.rb
@@ -10,16 +10,26 @@
 }
 
 parser = OptionParser.new do |opts|
-  opts.banner = "Usage add-get-intent [options]"
-  opts.on('-g', '--get_intents', 'get intents state') do
+  opts.banner = "Usage [get-options] [post-options]"
+
+  opts.separator  ""
+  opts.separator  "Get options:"
+
+  opts.on('-G', '--get_intents', 'get intents state') do
+    options[:get_intents] = true
     options[:rest_op] = "get"
   end
+  opts.on('-g', '--get_intent intent_id', 'get intent state') do |intent_id|
+    options[:rest_op] = "get"
+    options[:get_intent] = intent_id
+  end
+
+  opts.separator  ""
+  opts.separator  "Post options:"
+
   opts.on('-t', '--max_intents max_intents', 'max. number of intents') do |max_intents|
     options[:max_intents] = max_intents
   end
-  opts.on('-l', '--application application_id', 'set application id') do |appl_id|
-    options[:application_id] = appl_id.to_i
-  end
   opts.on('-i', '--intent_id intent_id', 'global intent id') do |id|
     options[:intent_id] = id.to_i
   end
@@ -57,10 +67,9 @@
 end
 parser.parse!
 
-
 class Intent
   attr_reader :switches, :ports, :intent_id
-  attr_reader :application_id, :intent_type, :intent_op
+  attr_reader :intent_type, :intent_op
   attr_reader :random_intent, :server, :port
   attr_reader :bulk_limit
 
@@ -72,8 +81,14 @@
     create_specific_intent
   end
 
-  def get_intent
-    request = RestClient.get "http://#{@server}:#{@port}/wm/onos/datagrid/get/intents/json"
+  def get_intent options
+    if options[:get_intents] == true
+      request = RestClient.get "http://#{@server}:#{@port}/wm/onos/datagrid/get/intents/json"
+    else
+      url = "http://#{@server}:#{@port}/wm/onos/datagrid/get/intent/#{options[:get_intent]}/json"
+      request = RestClient.get url
+      #request = RestClient.get "http://#{@server}:#{@port}/wm/onos/datagrid/get/intent/json",{:intent_id => options[:get_intent]}
+    end
     puts request
   end
 
@@ -134,8 +149,6 @@
     @ports = (1..(max_switches - 1)).to_a
     @intent_id = options[:intent_id]
     @intent_id ||= 1
-    @application_id = options[:application_id]
-    @application_id ||= 1
     @intent_type = options[:intent_type]
     @intent_op = options[:intent_op]
     @intent_op ||= "add"
@@ -158,7 +171,7 @@
       dst_port = sw_set.index(src_switch)
       dst_port = dst_port + 1
       intent = {
-        :intent_id => "#{@application_id}:#{@intent_id}",
+        :intent_id => "#{@intent_id}",
         :intent_type => @intent_type,
         :intent_op => @intent_op,
         :srcSwitch => src_switch.to_s,
@@ -188,7 +201,7 @@
 
 intent = Intent.new options
 if options[:rest_op] == "get"
-  intent.get_intent
+  intent.get_intent options
 else
   json_data = intent.post_intent
 end