diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInitiateMsgVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInitiateMsgVer1.java
index 97bd831..60d4af9 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInitiateMsgVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInitiateMsgVer1.java
@@ -1,331 +1,331 @@
-/*
- * 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.PcInitiatedLspRequest;
-import org.onosproject.pcepio.protocol.PcepAttribute;
-import org.onosproject.pcepio.protocol.PcepEndPointsObject;
-import org.onosproject.pcepio.protocol.PcepEroObject;
-import org.onosproject.pcepio.protocol.PcepInitiateMsg;
-import org.onosproject.pcepio.protocol.PcepLspObject;
-import org.onosproject.pcepio.protocol.PcepMessageReader;
-import org.onosproject.pcepio.protocol.PcepMessageWriter;
-import org.onosproject.pcepio.protocol.PcepSrpObject;
-import org.onosproject.pcepio.protocol.PcepType;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides PCEP initiate message.
- */
-class PcepInitiateMsgVer1 implements PcepInitiateMsg {
-
-    protected static final Logger log = LoggerFactory.getLogger(PcepInitiateMsgVer1.class);
-
-    // Ref : PCE initiated tunnel setup draft-ietf-pce-pce-initiated-lsp-03, section 5.1
-    /*      <PCInitiate Message>             ::= <Common Header>
-     *                                           <PCE-initiated-lsp-list>
-     *    Where:
-     *      <PCE-initiated-lsp-list>          ::= <PCE-initiated-lsp-request>[<PCE-initiated-lsp-list>]
-     *      <PCE-initiated-lsp-request>       ::= (<PCE-initiated-lsp-instantiation>|<PCE-initiated-lsp-deletion>)
-     *      <PCE-initiated-lsp-instantiation> ::= <SRP>
-     *                                            <LSP>
-     *                                            <END-POINTS>
-     *                                            <ERO>
-     *                                            [<attribute-list>]
-     *     <PCE-initiated-lsp-deletion>      ::= <SRP>
-     *                                           <LSP>
-     */
-
-    static final byte PACKET_VERSION = 1;
-    /* considering LspDelete Request PcInitiate msg will contain
-     * common header
-     * srp object
-     * lsp object
-     * so min length for this can be
-     * PACKET_MINIMUM_LENGTH = CommonHeaderLen(4)+SrpObjectMinLen(12)+LspObjectMinLen(8)
-     */
-    public static final short PACKET_MINIMUM_LENGTH = 24;
-    public static final short MINIMUM_COMMON_HEADER_LENGTH = 4;
-    public static final PcepType MSG_TYPE = PcepType.INITIATE;
-    private LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList;
-    public static final PcepInitiateMsgVer1.Reader READER = new Reader();
-
-    /**
-     * Reader class for reading of Pcep initiate message from channel buffer.
-     */
-    static class Reader implements PcepMessageReader<PcepInitiateMsg> {
-
-        LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList;
-
-        @Override
-        public PcepInitiateMsg readFrom(ChannelBuffer cb) throws PcepParseException {
-
-            if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
-                return null;
-            }
-
-            llPcInitiatedLspRequestList = new LinkedList<PcInitiatedLspRequest>();
-
-            byte version = cb.readByte();
-            version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
-            if (version != PACKET_VERSION) {
-                throw new PcepParseException("Wrong version. Expected=PcepVersion.PCEP_1(1), received=" + version);
-            }
-            byte type = cb.readByte();
-            if (type != MSG_TYPE.getType()) {
-                throw new PcepParseException("Wrong type. Expected=PcepType.INITIATE(12), recived=" + type);
-            }
-            short length = cb.readShort();
-
-            if (length < PACKET_MINIMUM_LENGTH) {
-                throw new PcepParseException("Wrong length. Initiate message length expected to be >= "
-                        + PACKET_MINIMUM_LENGTH + ", but received=" + length);
-            }
-
-            log.debug("reading PcInitiate message of length " + length);
-
-            // parse Start initiate/deletion list
-            if (!parsePcInitiatedLspRequestList(cb)) {
-                throw new PcepParseException("Parsing PCE-initiated-lsp-Request-list failed");
-            }
-
-            return new PcepInitiateMsgVer1(llPcInitiatedLspRequestList);
-        }
-
-        /**
-         * To parse PcInitiatedLspRequestList from PcInitiate Message.
-         *
-         * @param cb of type channel buffer
-         * @return true if parsing PcInitiatedLspRequestList is success, false otherwise
-         * @throws PcepParseException while parsing from channel buffer
-         */
-        public boolean parsePcInitiatedLspRequestList(ChannelBuffer cb) throws PcepParseException {
-
-            boolean isDelLspRequest = false;
-
-            if (null == cb) {
-                throw new PcepParseException("Channel buffer is empty");
-            }
-
-            while (0 < cb.readableBytes()) {
-                PcInitiatedLspRequest pceInitLspReq = new PcInitiatedLspRequestVer1();
-
-                //store SRP object
-                PcepSrpObject srpObj;
-                srpObj = PcepSrpObjectVer1.read(cb);
-                pceInitLspReq.setSrpObject(srpObj);
-                isDelLspRequest = srpObj.getRFlag();
-
-                //store LSP object
-                PcepLspObject lspObj;
-                lspObj = PcepLspObjectVer1.read(cb);
-                pceInitLspReq.setLspObject(lspObj);
-
-                /* if R bit will be set then pcInitiate msg will contain only LSp and SRP objects
-                 * so if R bit is not set then we should read for Ero and EndPoint objects also.
-                 */
-                if (!isDelLspRequest) {
-
-                    //store EndPoint object
-                    PcepEndPointsObject endPointObj;
-                    endPointObj = PcepEndPointsObjectVer1.read(cb);
-                    pceInitLspReq.setEndPointsObject(endPointObj);
-
-                    //store ERO object
-                    PcepEroObject eroObj;
-                    eroObj = PcepEroObjectVer1.read(cb);
-                    pceInitLspReq.setEroObject(eroObj);
-
-                    if (cb.readableBytes() > MINIMUM_COMMON_HEADER_LENGTH) {
-                        pceInitLspReq.setPcepAttribute(PcepAttributeVer1.read(cb));
-                    }
-                }
-                llPcInitiatedLspRequestList.add(pceInitLspReq);
-            }
-            return true;
-        }
-    }
-
-    /**
-     * Constructor to initialize PcInitiatedLspRequest.
-     *
-     * @param llPcInitiatedLspRequestList list of PcInitiatedLspRequest
-     */
-    PcepInitiateMsgVer1(LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList) {
-
-        if (llPcInitiatedLspRequestList == null) {
-            throw new NullPointerException("PcInitiatedLspRequestList cannot be null.");
-        }
-        this.llPcInitiatedLspRequestList = llPcInitiatedLspRequestList;
-    }
-
-    /**
-     * Builder class for PCEP initiate message.
-     */
-    static class Builder implements PcepInitiateMsg.Builder {
-
-        // Pcep initiate message fields
-        LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList;
-
-        @Override
-        public PcepVersion getVersion() {
-            return PcepVersion.PCEP_1;
-        }
-
-        @Override
-        public PcepType getType() {
-            return PcepType.INITIATE;
-        }
-
-        @Override
-        public PcepInitiateMsg build() {
-            return new PcepInitiateMsgVer1(this.llPcInitiatedLspRequestList);
-        }
-
-        @Override
-        public LinkedList<PcInitiatedLspRequest> getPcInitiatedLspRequestList() {
-            return this.llPcInitiatedLspRequestList;
-        }
-
-        @Override
-        public Builder setPcInitiatedLspRequestList(LinkedList<PcInitiatedLspRequest> ll) {
-            this.llPcInitiatedLspRequestList = ll;
-            return this;
-        }
-    }
-
-    @Override
-    public void writeTo(ChannelBuffer cb) throws PcepParseException {
-        WRITER.write(cb, this);
-    }
-
-    static final Writer WRITER = new Writer();
-
-    /**
-     * Writer class for writing pcep initiate message to channel buffer.
-     */
-    static class Writer implements PcepMessageWriter<PcepInitiateMsgVer1> {
-
-        @Override
-        public void write(ChannelBuffer cb, PcepInitiateMsgVer1 message) throws PcepParseException {
-
-            boolean isDelLspRequest = false;
-            int startIndex = cb.writerIndex();
-            // first 3 bits set to version
-            cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG));
-            // message type 0xC
-            cb.writeByte(MSG_TYPE.getType());
-            // length is length of variable message, will be updated at the end
-            // Store the position of message
-            // length in buffer
-            int msgLenIndex = cb.writerIndex();
-            cb.writeShort(0);
-
-            ListIterator<PcInitiatedLspRequest> listIterator = message.llPcInitiatedLspRequestList.listIterator();
-
-            while (listIterator.hasNext()) {
-
-                PcInitiatedLspRequest listReq = listIterator.next();
-
-                //Srp Object is mandatory
-                PcepSrpObject srpObj = listReq.getSrpObject();
-                if (srpObj instanceof PcepSrpObject) {
-                    isDelLspRequest = srpObj.getRFlag();
-                    srpObj.write(cb);
-                } else {
-                    throw new PcepParseException("SRP Object is mandatory for PcInitiate message.");
-                }
-
-                //LSP Object is mandatory
-                PcepLspObject lspObj = listReq.getLspObject();
-                if (lspObj instanceof PcepLspObject) {
-                    lspObj.write(cb);
-                } else {
-                    throw new PcepParseException("LSP Object is mandatory for PcInitiate message.");
-                }
-
-                /* if R bit will be set then pcInitiate msg will contain only LSp and SRP objects
-                 * so if R bit is not set then we should read for Ero and EndPoint objects also.
-                 */
-
-                if (!isDelLspRequest) {
-
-                    //EndPoints object is mandatory
-                    PcepEndPointsObject endPointObj = listReq.getEndPointsObject();
-                    if (endPointObj instanceof PcepEndPointsObject) {
-                        endPointObj.write(cb);
-                    } else {
-                        throw new PcepParseException("End points Object is mandatory for PcInitiate message.");
-                    }
-
-                    //Ero object is mandatory
-                    PcepEroObject eroObj = listReq.getEroObject();
-                    if (eroObj instanceof PcepEroObject) {
-                        eroObj.write(cb);
-                    } else {
-                        throw new PcepParseException("ERO Object is mandatory for PcInitiate message.");
-                    }
-
-                    //PcepAttribute is optional
-                    PcepAttribute pcepAttribute = listReq.getPcepAttribute();
-                    if (pcepAttribute instanceof PcepAttribute) {
-                        pcepAttribute.write(cb);
-                    }
-                }
-            }
-
-            // PCInitiate message length field
-            int length = cb.writerIndex() - startIndex;
-            cb.setShort(msgLenIndex, (short) length);
-        }
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public PcepType getType() {
-        return MSG_TYPE;
-    }
-
-    @Override
-    public LinkedList<PcInitiatedLspRequest> getPcInitiatedLspRequestList() {
-        return this.llPcInitiatedLspRequestList;
-    }
-
-    @Override
-    public void setPcInitiatedLspRequestList(LinkedList<PcInitiatedLspRequest> ll) {
-        this.llPcInitiatedLspRequestList = ll;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("PcInitiaitedLspRequestList", llPcInitiatedLspRequestList)
-                .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.PcInitiatedLspRequest;
+import org.onosproject.pcepio.protocol.PcepAttribute;
+import org.onosproject.pcepio.protocol.PcepEndPointsObject;
+import org.onosproject.pcepio.protocol.PcepEroObject;
+import org.onosproject.pcepio.protocol.PcepInitiateMsg;
+import org.onosproject.pcepio.protocol.PcepLspObject;
+import org.onosproject.pcepio.protocol.PcepMessageReader;
+import org.onosproject.pcepio.protocol.PcepMessageWriter;
+import org.onosproject.pcepio.protocol.PcepSrpObject;
+import org.onosproject.pcepio.protocol.PcepType;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides PCEP initiate message.
+ */
+class PcepInitiateMsgVer1 implements PcepInitiateMsg {
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepInitiateMsgVer1.class);
+
+    // Ref : PCE initiated tunnel setup draft-ietf-pce-pce-initiated-lsp-03, section 5.1
+    /*      <PCInitiate Message>             ::= <Common Header>
+     *                                           <PCE-initiated-lsp-list>
+     *    Where:
+     *      <PCE-initiated-lsp-list>          ::= <PCE-initiated-lsp-request>[<PCE-initiated-lsp-list>]
+     *      <PCE-initiated-lsp-request>       ::= (<PCE-initiated-lsp-instantiation>|<PCE-initiated-lsp-deletion>)
+     *      <PCE-initiated-lsp-instantiation> ::= <SRP>
+     *                                            <LSP>
+     *                                            <END-POINTS>
+     *                                            <ERO>
+     *                                            [<attribute-list>]
+     *     <PCE-initiated-lsp-deletion>      ::= <SRP>
+     *                                           <LSP>
+     */
+
+    static final byte PACKET_VERSION = 1;
+    /* considering LspDelete Request PcInitiate msg will contain
+     * common header
+     * srp object
+     * lsp object
+     * so min length for this can be
+     * PACKET_MINIMUM_LENGTH = CommonHeaderLen(4)+SrpObjectMinLen(12)+LspObjectMinLen(8)
+     */
+    public static final short PACKET_MINIMUM_LENGTH = 24;
+    public static final short MINIMUM_COMMON_HEADER_LENGTH = 4;
+    public static final PcepType MSG_TYPE = PcepType.INITIATE;
+    private LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList;
+    public static final PcepInitiateMsgVer1.Reader READER = new Reader();
+
+    /**
+     * Reader class for reading of Pcep initiate message from channel buffer.
+     */
+    static class Reader implements PcepMessageReader<PcepInitiateMsg> {
+
+        LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList;
+
+        @Override
+        public PcepInitiateMsg readFrom(ChannelBuffer cb) throws PcepParseException {
+
+            if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
+                return null;
+            }
+
+            llPcInitiatedLspRequestList = new LinkedList<PcInitiatedLspRequest>();
+
+            byte version = cb.readByte();
+            version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
+            if (version != PACKET_VERSION) {
+                throw new PcepParseException("Wrong version. Expected=PcepVersion.PCEP_1(1), received=" + version);
+            }
+            byte type = cb.readByte();
+            if (type != MSG_TYPE.getType()) {
+                throw new PcepParseException("Wrong type. Expected=PcepType.INITIATE(12), recived=" + type);
+            }
+            short length = cb.readShort();
+
+            if (length < PACKET_MINIMUM_LENGTH) {
+                throw new PcepParseException("Wrong length. Initiate message length expected to be >= "
+                        + PACKET_MINIMUM_LENGTH + ", but received=" + length);
+            }
+
+            log.debug("reading PcInitiate message of length " + length);
+
+            // parse Start initiate/deletion list
+            if (!parsePcInitiatedLspRequestList(cb)) {
+                throw new PcepParseException("Parsing PCE-initiated-lsp-Request-list failed");
+            }
+
+            return new PcepInitiateMsgVer1(llPcInitiatedLspRequestList);
+        }
+
+        /**
+         * To parse PcInitiatedLspRequestList from PcInitiate Message.
+         *
+         * @param cb of type channel buffer
+         * @return true if parsing PcInitiatedLspRequestList is success, false otherwise
+         * @throws PcepParseException while parsing from channel buffer
+         */
+        public boolean parsePcInitiatedLspRequestList(ChannelBuffer cb) throws PcepParseException {
+
+            boolean isDelLspRequest = false;
+
+            if (null == cb) {
+                throw new PcepParseException("Channel buffer is empty");
+            }
+
+            while (0 < cb.readableBytes()) {
+                PcInitiatedLspRequest pceInitLspReq = new PcInitiatedLspRequestVer1();
+
+                //store SRP object
+                PcepSrpObject srpObj;
+                srpObj = PcepSrpObjectVer1.read(cb);
+                pceInitLspReq.setSrpObject(srpObj);
+                isDelLspRequest = srpObj.getRFlag();
+
+                //store LSP object
+                PcepLspObject lspObj;
+                lspObj = PcepLspObjectVer1.read(cb);
+                pceInitLspReq.setLspObject(lspObj);
+
+                /* if R bit will be set then pcInitiate msg will contain only LSp and SRP objects
+                 * so if R bit is not set then we should read for Ero and EndPoint objects also.
+                 */
+                if (!isDelLspRequest) {
+
+                    //store EndPoint object
+                    PcepEndPointsObject endPointObj;
+                    endPointObj = PcepEndPointsObjectVer1.read(cb);
+                    pceInitLspReq.setEndPointsObject(endPointObj);
+
+                    //store ERO object
+                    PcepEroObject eroObj;
+                    eroObj = PcepEroObjectVer1.read(cb);
+                    pceInitLspReq.setEroObject(eroObj);
+
+                    if (cb.readableBytes() > MINIMUM_COMMON_HEADER_LENGTH) {
+                        pceInitLspReq.setPcepAttribute(PcepAttributeVer1.read(cb));
+                    }
+                }
+                llPcInitiatedLspRequestList.add(pceInitLspReq);
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Constructor to initialize PcInitiatedLspRequest.
+     *
+     * @param llPcInitiatedLspRequestList list of PcInitiatedLspRequest
+     */
+    PcepInitiateMsgVer1(LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList) {
+
+        if (llPcInitiatedLspRequestList == null) {
+            throw new NullPointerException("PcInitiatedLspRequestList cannot be null.");
+        }
+        this.llPcInitiatedLspRequestList = llPcInitiatedLspRequestList;
+    }
+
+    /**
+     * Builder class for PCEP initiate message.
+     */
+    static class Builder implements PcepInitiateMsg.Builder {
+
+        // Pcep initiate message fields
+        LinkedList<PcInitiatedLspRequest> llPcInitiatedLspRequestList;
+
+        @Override
+        public PcepVersion getVersion() {
+            return PcepVersion.PCEP_1;
+        }
+
+        @Override
+        public PcepType getType() {
+            return PcepType.INITIATE;
+        }
+
+        @Override
+        public PcepInitiateMsg build() {
+            return new PcepInitiateMsgVer1(this.llPcInitiatedLspRequestList);
+        }
+
+        @Override
+        public LinkedList<PcInitiatedLspRequest> getPcInitiatedLspRequestList() {
+            return this.llPcInitiatedLspRequestList;
+        }
+
+        @Override
+        public Builder setPcInitiatedLspRequestList(LinkedList<PcInitiatedLspRequest> ll) {
+            this.llPcInitiatedLspRequestList = ll;
+            return this;
+        }
+    }
+
+    @Override
+    public void writeTo(ChannelBuffer cb) throws PcepParseException {
+        WRITER.write(cb, this);
+    }
+
+    static final Writer WRITER = new Writer();
+
+    /**
+     * Writer class for writing pcep initiate message to channel buffer.
+     */
+    static class Writer implements PcepMessageWriter<PcepInitiateMsgVer1> {
+
+        @Override
+        public void write(ChannelBuffer cb, PcepInitiateMsgVer1 message) throws PcepParseException {
+
+            boolean isDelLspRequest = false;
+            int startIndex = cb.writerIndex();
+            // first 3 bits set to version
+            cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG));
+            // message type 0xC
+            cb.writeByte(MSG_TYPE.getType());
+            // length is length of variable message, will be updated at the end
+            // Store the position of message
+            // length in buffer
+            int msgLenIndex = cb.writerIndex();
+            cb.writeShort(0);
+
+            ListIterator<PcInitiatedLspRequest> listIterator = message.llPcInitiatedLspRequestList.listIterator();
+
+            while (listIterator.hasNext()) {
+
+                PcInitiatedLspRequest listReq = listIterator.next();
+
+                //Srp Object is mandatory
+                PcepSrpObject srpObj = listReq.getSrpObject();
+                if (srpObj instanceof PcepSrpObject) {
+                    isDelLspRequest = srpObj.getRFlag();
+                    srpObj.write(cb);
+                } else {
+                    throw new PcepParseException("SRP Object is mandatory for PcInitiate message.");
+                }
+
+                //LSP Object is mandatory
+                PcepLspObject lspObj = listReq.getLspObject();
+                if (lspObj instanceof PcepLspObject) {
+                    lspObj.write(cb);
+                } else {
+                    throw new PcepParseException("LSP Object is mandatory for PcInitiate message.");
+                }
+
+                /* if R bit will be set then pcInitiate msg will contain only LSp and SRP objects
+                 * so if R bit is not set then we should read for Ero and EndPoint objects also.
+                 */
+
+                if (!isDelLspRequest) {
+
+                    //EndPoints object is mandatory
+                    PcepEndPointsObject endPointObj = listReq.getEndPointsObject();
+                    if (endPointObj instanceof PcepEndPointsObject) {
+                        endPointObj.write(cb);
+                    } else {
+                        throw new PcepParseException("End points Object is mandatory for PcInitiate message.");
+                    }
+
+                    //Ero object is mandatory
+                    PcepEroObject eroObj = listReq.getEroObject();
+                    if (eroObj instanceof PcepEroObject) {
+                        eroObj.write(cb);
+                    } else {
+                        throw new PcepParseException("ERO Object is mandatory for PcInitiate message.");
+                    }
+
+                    //PcepAttribute is optional
+                    PcepAttribute pcepAttribute = listReq.getPcepAttribute();
+                    if (pcepAttribute instanceof PcepAttribute) {
+                        pcepAttribute.write(cb);
+                    }
+                }
+            }
+
+            // PCInitiate message length field
+            int length = cb.writerIndex() - startIndex;
+            cb.setShort(msgLenIndex, (short) length);
+        }
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public PcepType getType() {
+        return MSG_TYPE;
+    }
+
+    @Override
+    public LinkedList<PcInitiatedLspRequest> getPcInitiatedLspRequestList() {
+        return this.llPcInitiatedLspRequestList;
+    }
+
+    @Override
+    public void setPcInitiatedLspRequestList(LinkedList<PcInitiatedLspRequest> ll) {
+        this.llPcInitiatedLspRequestList = ll;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("PcInitiaitedLspRequestList", llPcInitiatedLspRequestList)
+                .toString();
+    }
+}
