diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepSrpObjectVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepSrpObjectVer1.java
index 2aa19aa..e76de01 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepSrpObjectVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepSrpObjectVer1.java
@@ -1,389 +1,389 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onosproject.pcepio.protocol.ver1;
-
-import java.util.LinkedList;
-import java.util.ListIterator;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepSrpObject;
-import org.onosproject.pcepio.types.PcepObjectHeader;
-import org.onosproject.pcepio.types.PcepValueType;
-import org.onosproject.pcepio.types.SymbolicPathNameTlv;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides PCEP SRP obejct.
- */
-public class PcepSrpObjectVer1 implements PcepSrpObject {
-
-    /*
-     * ref : draft-ietf-pce-stateful-pce-10, section : 7.2
-    0                   1                   2                   3
-    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    | Object-Class  |   OT  |Res|P|I|   Object Length (bytes)       |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                          Flags                              |R|
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                        SRP-ID-number                          |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                                                               |
-    //                      Optional TLVs                          //
-    |                                                               |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-     */
-    protected static final Logger log = LoggerFactory.getLogger(PcepSrpObjectVer1.class);
-
-    public static final byte SRP_OBJ_TYPE = 1;
-    public static final byte SRP_OBJ_CLASS = 33;
-    public static final byte SRP_OBJECT_VERSION = 1;
-    public static final short SRP_OBJ_MINIMUM_LENGTH = 12;
-    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
-    public static final boolean DEFAULT_RFLAG = false;
-
-    static final PcepObjectHeader DEFAULT_SRP_OBJECT_HEADER = new PcepObjectHeader(SRP_OBJ_CLASS, SRP_OBJ_TYPE,
-            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, SRP_OBJ_MINIMUM_LENGTH);
-
-    private PcepObjectHeader srpObjHeader;
-    private static int flags;
-    private boolean bRFlag;
-    private int srpId;
-
-    //Optional TLV
-    private LinkedList<PcepValueType> llOptionalTlv;
-    public static final byte BBIT_SET = 1;
-    public static final byte BBIT_RESET = 0;
-
-    /**
-     * Constructor to initialize member variables.
-     *
-     * @param srpObjHeader srp object header
-     * @param bRFlag R flag
-     * @param srpID srp Id
-     * @param llOptionalTlv list of optional tlv
-     */
-    public PcepSrpObjectVer1(PcepObjectHeader srpObjHeader, boolean bRFlag, int srpID,
-            LinkedList<PcepValueType> llOptionalTlv) {
-
-        this.srpObjHeader = srpObjHeader;
-        this.bRFlag = bRFlag;
-        this.srpId = srpID;
-        this.llOptionalTlv = llOptionalTlv;
-    }
-
-    /**
-     * sets the SRP object header.
-     *
-     * @param obj srp object header
-     */
-    public void setSrpObjHeader(PcepObjectHeader obj) {
-        this.srpObjHeader = obj;
-    }
-
-    @Override
-    public void setSrpID(int srpID) {
-        this.srpId = srpID;
-    }
-
-    @Override
-    public void setRFlag(boolean bRFlag) {
-        this.bRFlag = bRFlag;
-    }
-
-    /**
-     * Returns SRP object header.
-     *
-     * @return srpObjHeader
-     */
-    public PcepObjectHeader getSrpObjHeader() {
-        return this.srpObjHeader;
-    }
-
-    @Override
-    public int getSrpID() {
-        return this.srpId;
-    }
-
-    @Override
-    public boolean getRFlag() {
-        return this.bRFlag;
-    }
-
-    @Override
-    public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
-        this.llOptionalTlv = llOptionalTlv;
-
-    }
-
-    @Override
-    public LinkedList<PcepValueType> getOptionalTlv() {
-        return this.llOptionalTlv;
-    }
-
-    /**
-     * Reads from channel buffer and returns instance of PCEP SRP object.
-     *
-     * @param cb of channel buffer.
-     * @return PCEP SRP object
-     * @throws PcepParseException when srp object is not received in channel buffer
-     */
-    public static PcepSrpObject read(ChannelBuffer cb) throws PcepParseException {
-
-        log.debug("SrpObject::read");
-        PcepObjectHeader srpObjHeader;
-        boolean bRFlag;
-
-        int srpID;
-        int flags;
-        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
-
-        srpObjHeader = PcepObjectHeader.read(cb);
-
-        if (SRP_OBJ_CLASS != srpObjHeader.getObjClass()) {
-            throw new PcepParseException("SRP object expected. But received " + srpObjHeader.getObjClass());
-        }
-
-        //take only SrpObject buffer.
-        ChannelBuffer tempCb = cb.readBytes(srpObjHeader.getObjLen() - MINIMUM_COMMON_HEADER_LENGTH);
-        flags = tempCb.readInt();
-        bRFlag = (0 < flags) ? true : false;
-        srpID = tempCb.readInt();
-
-        llOptionalTlv = parseOptionalTlv(tempCb);
-
-        return new PcepSrpObjectVer1(srpObjHeader, bRFlag, srpID, llOptionalTlv);
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-
-        int objStartIndex = cb.writerIndex();
-
-        //write common header
-        int objLenIndex = srpObjHeader.write(cb);
-
-        //write Flags
-        byte bFlag;
-
-        bFlag = (bRFlag) ? BBIT_SET : BBIT_RESET;
-
-        cb.writeInt(bFlag);
-
-        //write SrpId
-        cb.writeInt(srpId);
-
-        // Add optional TLV
-        if (!packOptionalTlv(cb)) {
-            throw new PcepParseException("Failed to write srp tlv to channel buffer.");
-        }
-
-        //now write SRP Object Length
-        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
-
-        return cb.writerIndex();
-    }
-
-    /**
-     * Parse Optional TLvs from the channel buffer.
-     *
-     * @param cb of type channel buffer
-     * @return list of optional tlvs
-     * @throws PcepParseException when unsupported tlv is received in srp object
-     */
-    public static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
-
-        LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<PcepValueType>();
-
-        while (MINIMUM_COMMON_HEADER_LENGTH <= cb.readableBytes()) {
-
-            PcepValueType tlv;
-            short hType = cb.readShort();
-            short hLength = cb.readShort();
-
-            switch (hType) {
-
-            case SymbolicPathNameTlv.TYPE:
-                tlv = SymbolicPathNameTlv.read(cb, hLength);
-                cb.skipBytes(hLength);
-                break;
-
-            default:
-                throw new PcepParseException("Unsupported TLV received in SRP Object.");
-            }
-
-            // Check for the padding
-            int pad = hLength % 4;
-            if (0 < pad) {
-                pad = 4 - pad;
-                if (pad <= cb.readableBytes()) {
-                    cb.skipBytes(pad);
-                }
-            }
-            llOutOptionalTlv.add(tlv);
-        }
-
-        return llOutOptionalTlv;
-    }
-
-    /**
-     * Writes optional tlvs to channel buffer.
-     *
-     * @param cb of type channel buffer
-     * @return true if writing optional tlv to channel buffer is success.
-     */
-    protected boolean packOptionalTlv(ChannelBuffer cb) {
-
-        ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
-
-        while (listIterator.hasNext()) {
-            PcepValueType tlv = listIterator.next();
-
-            if (null == tlv) {
-                log.debug("tlv is null from OptionalTlv list");
-                continue;
-            }
-            tlv.write(cb);
-
-            // need to take care of padding
-            int pad = tlv.getLength() % 4;
-
-            if (0 != pad) {
-                pad = 4 - pad;
-                for (int i = 0; i < pad; ++i) {
-                    cb.writeByte((byte) 0);
-                }
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Builder class for PCEP srp Object.
-     */
-    public static class Builder implements PcepSrpObject.Builder {
-        private boolean bIsHeaderSet = false;
-        private boolean bIsSrpIdset = false;
-        private boolean bIsRFlagSet = false;
-
-        private PcepObjectHeader srpObjHeader;
-        private int srpId;
-        private boolean bRFlag;
-        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
-
-        private boolean bIsPFlagSet = false;
-        private boolean bPFlag;
-
-        private boolean bIsIFlagSet = false;
-        private boolean bIFlag;
-
-        @Override
-        public PcepSrpObject build() throws PcepParseException {
-            PcepObjectHeader srpObjHeader = this.bIsHeaderSet ? this.srpObjHeader : DEFAULT_SRP_OBJECT_HEADER;
-
-            boolean bRFlag = this.bIsRFlagSet ? this.bRFlag : DEFAULT_RFLAG;
-
-            if (!this.bIsSrpIdset) {
-                throw new PcepParseException("SrpID not set while building SRP Object.");
-            }
-
-            if (bIsPFlagSet) {
-                srpObjHeader.setPFlag(bPFlag);
-            }
-
-            if (bIsIFlagSet) {
-                srpObjHeader.setIFlag(bIFlag);
-            }
-
-            return new PcepSrpObjectVer1(srpObjHeader, bRFlag, this.srpId, this.llOptionalTlv);
-        }
-
-        @Override
-        public PcepObjectHeader getSrpObjHeader() {
-            return this.srpObjHeader;
-        }
-
-        @Override
-        public Builder setSrpObjHeader(PcepObjectHeader obj) {
-            this.srpObjHeader = obj;
-            this.bIsHeaderSet = true;
-            return this;
-        }
-
-        @Override
-        public int getSrpID() {
-            return this.srpId;
-        }
-
-        @Override
-        public Builder setSrpID(int srpID) {
-            this.srpId = srpID;
-            this.bIsSrpIdset = true;
-            return this;
-        }
-
-        @Override
-        public boolean getRFlag() {
-            return this.bRFlag;
-        }
-
-        @Override
-        public Builder setRFlag(boolean bRFlag) {
-            this.bRFlag = bRFlag;
-            this.bIsRFlagSet = true;
-            return this;
-        }
-
-        @Override
-        public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
-            this.llOptionalTlv = llOptionalTlv;
-            return this;
-        }
-
-        @Override
-        public LinkedList<PcepValueType> getOptionalTlv() {
-            return this.llOptionalTlv;
-        }
-
-        @Override
-        public Builder setPFlag(boolean value) {
-            this.bPFlag = value;
-            this.bIsPFlagSet = true;
-            return this;
-        }
-
-        @Override
-        public Builder setIFlag(boolean value) {
-            this.bIFlag = value;
-            this.bIsIFlagSet = true;
-            return this;
-        }
-
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("RFlag", bRFlag).add("SRPID", srpId)
-                .add("OptionalTlvList", llOptionalTlv).toString();
-    }
-}
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.pcepio.protocol.ver1;
+
+import java.util.LinkedList;
+import java.util.ListIterator;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepSrpObject;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.onosproject.pcepio.types.PcepValueType;
+import org.onosproject.pcepio.types.SymbolicPathNameTlv;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides PCEP SRP obejct.
+ */
+public class PcepSrpObjectVer1 implements PcepSrpObject {
+
+    /*
+     * ref : draft-ietf-pce-stateful-pce-10, section : 7.2
+    0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    | Object-Class  |   OT  |Res|P|I|   Object Length (bytes)       |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                          Flags                              |R|
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                        SRP-ID-number                          |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                                                               |
+    //                      Optional TLVs                          //
+    |                                                               |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(PcepSrpObjectVer1.class);
+
+    public static final byte SRP_OBJ_TYPE = 1;
+    public static final byte SRP_OBJ_CLASS = 33;
+    public static final byte SRP_OBJECT_VERSION = 1;
+    public static final short SRP_OBJ_MINIMUM_LENGTH = 12;
+    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
+    public static final boolean DEFAULT_RFLAG = false;
+
+    static final PcepObjectHeader DEFAULT_SRP_OBJECT_HEADER = new PcepObjectHeader(SRP_OBJ_CLASS, SRP_OBJ_TYPE,
+            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, SRP_OBJ_MINIMUM_LENGTH);
+
+    private PcepObjectHeader srpObjHeader;
+    private static int flags;
+    private boolean bRFlag;
+    private int srpId;
+
+    //Optional TLV
+    private LinkedList<PcepValueType> llOptionalTlv;
+    public static final byte BBIT_SET = 1;
+    public static final byte BBIT_RESET = 0;
+
+    /**
+     * Constructor to initialize member variables.
+     *
+     * @param srpObjHeader srp object header
+     * @param bRFlag R flag
+     * @param srpID srp Id
+     * @param llOptionalTlv list of optional tlv
+     */
+    public PcepSrpObjectVer1(PcepObjectHeader srpObjHeader, boolean bRFlag, int srpID,
+            LinkedList<PcepValueType> llOptionalTlv) {
+
+        this.srpObjHeader = srpObjHeader;
+        this.bRFlag = bRFlag;
+        this.srpId = srpID;
+        this.llOptionalTlv = llOptionalTlv;
+    }
+
+    /**
+     * sets the SRP object header.
+     *
+     * @param obj srp object header
+     */
+    public void setSrpObjHeader(PcepObjectHeader obj) {
+        this.srpObjHeader = obj;
+    }
+
+    @Override
+    public void setSrpID(int srpID) {
+        this.srpId = srpID;
+    }
+
+    @Override
+    public void setRFlag(boolean bRFlag) {
+        this.bRFlag = bRFlag;
+    }
+
+    /**
+     * Returns SRP object header.
+     *
+     * @return srpObjHeader
+     */
+    public PcepObjectHeader getSrpObjHeader() {
+        return this.srpObjHeader;
+    }
+
+    @Override
+    public int getSrpID() {
+        return this.srpId;
+    }
+
+    @Override
+    public boolean getRFlag() {
+        return this.bRFlag;
+    }
+
+    @Override
+    public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
+        this.llOptionalTlv = llOptionalTlv;
+
+    }
+
+    @Override
+    public LinkedList<PcepValueType> getOptionalTlv() {
+        return this.llOptionalTlv;
+    }
+
+    /**
+     * Reads from channel buffer and returns instance of PCEP SRP object.
+     *
+     * @param cb of channel buffer.
+     * @return PCEP SRP object
+     * @throws PcepParseException when srp object is not received in channel buffer
+     */
+    public static PcepSrpObject read(ChannelBuffer cb) throws PcepParseException {
+
+        log.debug("SrpObject::read");
+        PcepObjectHeader srpObjHeader;
+        boolean bRFlag;
+
+        int srpID;
+        int flags;
+        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
+
+        srpObjHeader = PcepObjectHeader.read(cb);
+
+        if (SRP_OBJ_CLASS != srpObjHeader.getObjClass()) {
+            throw new PcepParseException("SRP object expected. But received " + srpObjHeader.getObjClass());
+        }
+
+        //take only SrpObject buffer.
+        ChannelBuffer tempCb = cb.readBytes(srpObjHeader.getObjLen() - MINIMUM_COMMON_HEADER_LENGTH);
+        flags = tempCb.readInt();
+        bRFlag = (0 < flags) ? true : false;
+        srpID = tempCb.readInt();
+
+        llOptionalTlv = parseOptionalTlv(tempCb);
+
+        return new PcepSrpObjectVer1(srpObjHeader, bRFlag, srpID, llOptionalTlv);
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+
+        int objStartIndex = cb.writerIndex();
+
+        //write common header
+        int objLenIndex = srpObjHeader.write(cb);
+
+        //write Flags
+        byte bFlag;
+
+        bFlag = (bRFlag) ? BBIT_SET : BBIT_RESET;
+
+        cb.writeInt(bFlag);
+
+        //write SrpId
+        cb.writeInt(srpId);
+
+        // Add optional TLV
+        if (!packOptionalTlv(cb)) {
+            throw new PcepParseException("Failed to write srp tlv to channel buffer.");
+        }
+
+        //now write SRP Object Length
+        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
+
+        return cb.writerIndex();
+    }
+
+    /**
+     * Parse Optional TLvs from the channel buffer.
+     *
+     * @param cb of type channel buffer
+     * @return list of optional tlvs
+     * @throws PcepParseException when unsupported tlv is received in srp object
+     */
+    public static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
+
+        LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<PcepValueType>();
+
+        while (MINIMUM_COMMON_HEADER_LENGTH <= cb.readableBytes()) {
+
+            PcepValueType tlv;
+            short hType = cb.readShort();
+            short hLength = cb.readShort();
+
+            switch (hType) {
+
+            case SymbolicPathNameTlv.TYPE:
+                tlv = SymbolicPathNameTlv.read(cb, hLength);
+                cb.skipBytes(hLength);
+                break;
+
+            default:
+                throw new PcepParseException("Unsupported TLV received in SRP Object.");
+            }
+
+            // Check for the padding
+            int pad = hLength % 4;
+            if (0 < pad) {
+                pad = 4 - pad;
+                if (pad <= cb.readableBytes()) {
+                    cb.skipBytes(pad);
+                }
+            }
+            llOutOptionalTlv.add(tlv);
+        }
+
+        return llOutOptionalTlv;
+    }
+
+    /**
+     * Writes optional tlvs to channel buffer.
+     *
+     * @param cb of type channel buffer
+     * @return true if writing optional tlv to channel buffer is success.
+     */
+    protected boolean packOptionalTlv(ChannelBuffer cb) {
+
+        ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
+
+        while (listIterator.hasNext()) {
+            PcepValueType tlv = listIterator.next();
+
+            if (null == tlv) {
+                log.debug("tlv is null from OptionalTlv list");
+                continue;
+            }
+            tlv.write(cb);
+
+            // need to take care of padding
+            int pad = tlv.getLength() % 4;
+
+            if (0 != pad) {
+                pad = 4 - pad;
+                for (int i = 0; i < pad; ++i) {
+                    cb.writeByte((byte) 0);
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Builder class for PCEP srp Object.
+     */
+    public static class Builder implements PcepSrpObject.Builder {
+        private boolean bIsHeaderSet = false;
+        private boolean bIsSrpIdset = false;
+        private boolean bIsRFlagSet = false;
+
+        private PcepObjectHeader srpObjHeader;
+        private int srpId;
+        private boolean bRFlag;
+        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
+
+        private boolean bIsPFlagSet = false;
+        private boolean bPFlag;
+
+        private boolean bIsIFlagSet = false;
+        private boolean bIFlag;
+
+        @Override
+        public PcepSrpObject build() throws PcepParseException {
+            PcepObjectHeader srpObjHeader = this.bIsHeaderSet ? this.srpObjHeader : DEFAULT_SRP_OBJECT_HEADER;
+
+            boolean bRFlag = this.bIsRFlagSet ? this.bRFlag : DEFAULT_RFLAG;
+
+            if (!this.bIsSrpIdset) {
+                throw new PcepParseException("SrpID not set while building SRP Object.");
+            }
+
+            if (bIsPFlagSet) {
+                srpObjHeader.setPFlag(bPFlag);
+            }
+
+            if (bIsIFlagSet) {
+                srpObjHeader.setIFlag(bIFlag);
+            }
+
+            return new PcepSrpObjectVer1(srpObjHeader, bRFlag, this.srpId, this.llOptionalTlv);
+        }
+
+        @Override
+        public PcepObjectHeader getSrpObjHeader() {
+            return this.srpObjHeader;
+        }
+
+        @Override
+        public Builder setSrpObjHeader(PcepObjectHeader obj) {
+            this.srpObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public int getSrpID() {
+            return this.srpId;
+        }
+
+        @Override
+        public Builder setSrpID(int srpID) {
+            this.srpId = srpID;
+            this.bIsSrpIdset = true;
+            return this;
+        }
+
+        @Override
+        public boolean getRFlag() {
+            return this.bRFlag;
+        }
+
+        @Override
+        public Builder setRFlag(boolean bRFlag) {
+            this.bRFlag = bRFlag;
+            this.bIsRFlagSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
+            this.llOptionalTlv = llOptionalTlv;
+            return this;
+        }
+
+        @Override
+        public LinkedList<PcepValueType> getOptionalTlv() {
+            return this.llOptionalTlv;
+        }
+
+        @Override
+        public Builder setPFlag(boolean value) {
+            this.bPFlag = value;
+            this.bIsPFlagSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setIFlag(boolean value) {
+            this.bIFlag = value;
+            this.bIsIFlagSet = true;
+            return this;
+        }
+
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("RFlag", bRFlag).add("SRPID", srpId)
+                .add("OptionalTlvList", llOptionalTlv).toString();
+    }
+}
