diff --git a/src/main/java/net/onrc/onos/datastore/RCObject.java b/src/main/java/net/onrc/onos/datastore/RCObject.java
index a2d8c6e..77f5d15 100644
--- a/src/main/java/net/onrc/onos/datastore/RCObject.java
+++ b/src/main/java/net/onrc/onos/datastore/RCObject.java
@@ -56,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;
@@ -150,6 +150,7 @@
 
     protected void serializeAndSetValue(Kryo kryo,
 	    Map<Object, Object> javaObject) {
+	
 
 	// value
 	byte[] rcTemp = new byte[1024 * 1024];
@@ -175,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;
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/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;
+}
