diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLspaObjectVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLspaObjectVer1.java
index a592c45..a0e2389 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLspaObjectVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLspaObjectVer1.java
@@ -1,523 +1,523 @@
-/*
- * 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.PcepLspaObject;
-import org.onosproject.pcepio.types.PcepObjectHeader;
-import org.onosproject.pcepio.types.PcepValueType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides PCEP label Object .
- */
-public class PcepLspaObjectVer1 implements PcepLspaObject {
-
-    /* LSPA Object Body Format
-
-    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
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                       Exclude-any                             |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                       Include-any                             |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                       Include-all                             |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |  Setup Prio   |  Holding Prio |     Flags   |L|   Reserved    |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                                                               |
-    |                      Optional TLVs                            |
-    |                                                               |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(PcepLspaObjectVer1.class);
-
-    public static final byte LSPA_OBJ_TYPE = 1;
-    public static final byte LSPA_OBJ_CLASS = 9;
-    public static final byte LSPA_OBJECT_VERSION = 1;
-    public static final short LSPA_OBJ_MINIMUM_LENGTH = 20;
-    public static final int OBJECT_HEADER_LENGTH = 4;
-
-    static final PcepObjectHeader DEFAULT_LSPA_OBJECT_HEADER = new PcepObjectHeader(LSPA_OBJ_CLASS, LSPA_OBJ_TYPE,
-            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, LSPA_OBJ_MINIMUM_LENGTH);
-
-    public static final int SETUP_PRIORITY_SHIFT_VALUE = 24;
-    public static final int HOLD_PRIORITY_SHIFT_VALUE = 16;
-    public static final int BFLAG_SHIFT_VALUE = 8;
-    public static final int LFLAG_SET = 1;
-    public static final int LFLAG_RESET = 0;
-    private PcepObjectHeader lspaObjHeader;
-    private int iExcludeAny;
-    private int iIncludeAny;
-    private int iIncludeAll;
-    private byte cSetupPriority;
-    private byte cHoldPriority;
-    private boolean bLFlag;
-    private LinkedList<PcepValueType> llOptionalTlv; //Optional TLV
-
-    /**
-     * Constructor to initialize member variables.
-     *
-     * @param lspaObjHeader lspa object header
-     * @param bLFlag b l flag
-     * @param iExcludeAny excludeAny value
-     * @param iIncludeAny includeAny value
-     * @param iIncludeAll includeAll value
-     * @param cSetupPriority setup priority value
-     * @param cHoldPriority hold priority value
-     * @param llOptionalTlv list of optional tlv
-     */
-    public PcepLspaObjectVer1(PcepObjectHeader lspaObjHeader, boolean bLFlag, int iExcludeAny, int iIncludeAny,
-            int iIncludeAll, byte cSetupPriority, byte cHoldPriority, LinkedList<PcepValueType> llOptionalTlv) {
-
-        this.lspaObjHeader = lspaObjHeader;
-        this.bLFlag = bLFlag;
-        this.iExcludeAny = iExcludeAny;
-        this.iIncludeAny = iIncludeAny;
-        this.iIncludeAll = iIncludeAll;
-        this.cSetupPriority = cSetupPriority;
-        this.cHoldPriority = cHoldPriority;
-        this.llOptionalTlv = llOptionalTlv;
-    }
-
-    /**
-     * Sets Object Header.
-     *
-     * @param obj lspa object header
-     */
-    public void setLspaObjHeader(PcepObjectHeader obj) {
-        this.lspaObjHeader = obj;
-    }
-
-    @Override
-    public void setExcludeAny(int iExcludeAny) {
-        this.iExcludeAny = iExcludeAny;
-    }
-
-    @Override
-    public void setIncludeAny(int iIncludeAny) {
-        this.iIncludeAny = iIncludeAny;
-    }
-
-    @Override
-    public void setSetupPriority(byte cSetupPriority) {
-        this.cSetupPriority = cSetupPriority;
-    }
-
-    @Override
-    public void setHoldPriority(byte cHoldPriority) {
-        this.cHoldPriority = cHoldPriority;
-    }
-
-    @Override
-    public void setLFlag(boolean bLFlag) {
-        this.bLFlag = bLFlag;
-    }
-
-    /**
-     * Returns lspa Object Header.
-     *
-     * @return lspa Object Header
-     */
-    public PcepObjectHeader getLspaObjHeader() {
-        return this.lspaObjHeader;
-    }
-
-    @Override
-    public int getExcludeAny() {
-        return this.iExcludeAny;
-    }
-
-    @Override
-    public int getIncludeAny() {
-        return this.iIncludeAny;
-    }
-
-    @Override
-    public int getIncludeAll() {
-        return this.iIncludeAll;
-    }
-
-    @Override
-    public byte getSetupPriority() {
-        return this.cSetupPriority;
-    }
-
-    @Override
-    public byte getHoldPriority() {
-        return this.cHoldPriority;
-    }
-
-    @Override
-    public boolean getLFlag() {
-        return this.bLFlag;
-    }
-
-    @Override
-    public void setIncludeAll(int value) {
-        this.iIncludeAll = value;
-
-    }
-
-    @Override
-    public LinkedList<PcepValueType> getOptionalTlv() {
-        return this.llOptionalTlv;
-    }
-
-    @Override
-    public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
-        this.llOptionalTlv = llOptionalTlv;
-
-    }
-
-    /**
-     * Reads channel buffer and returns object of PcepLspaObject.
-     *
-     * @param cb of type channel buffer.
-     * @return object of PcepLspaObject
-     * @throws PcepParseException while parsing lspa object from channel buffer
-     */
-    public static PcepLspaObject read(ChannelBuffer cb) throws PcepParseException {
-
-        log.debug("LspaObject::read");
-        PcepObjectHeader lspaObjHeader;
-        int iExcludeAny;
-        int iIncludeAny;
-        int iIncludeAll;
-        byte cSetupPriority;
-        byte cHoldPriority;
-        boolean bLFlag;
-        byte flags;
-
-        // Optional TLV
-        LinkedList<PcepValueType> llOptionalTlv;
-
-        lspaObjHeader = PcepObjectHeader.read(cb);
-
-        //take only Lspa Object buffer.
-        ChannelBuffer tempCb = cb.readBytes(lspaObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
-        iExcludeAny = tempCb.readInt();
-        iIncludeAny = tempCb.readInt();
-        iIncludeAll = tempCb.readInt();
-        cSetupPriority = tempCb.readByte();
-        cHoldPriority = tempCb.readByte();
-        flags = tempCb.readByte();
-        tempCb.readByte();
-
-        bLFlag = (flags & (byte) LFLAG_SET) == LFLAG_SET ? true : false;
-
-        llOptionalTlv = parseOptionalTlv(tempCb);
-
-        return new PcepLspaObjectVer1(lspaObjHeader, bLFlag, iExcludeAny, iIncludeAny, iIncludeAll, cSetupPriority,
-                cHoldPriority, llOptionalTlv);
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-
-        //write Object header
-        int objStartIndex = cb.writerIndex();
-
-        int objLenIndex = lspaObjHeader.write(cb);
-
-        if (objLenIndex <= 0) {
-            throw new PcepParseException("Failed to write lspa object header. Index " + objLenIndex);
-        }
-
-        cb.writeInt(iExcludeAny);
-        cb.writeInt(iIncludeAny);
-        cb.writeInt(iIncludeAll);
-
-        int iTemp = cSetupPriority << SETUP_PRIORITY_SHIFT_VALUE;
-        iTemp = iTemp | (cHoldPriority << HOLD_PRIORITY_SHIFT_VALUE);
-        byte bFlag;
-        bFlag = (bLFlag) ? (byte) LFLAG_SET : LFLAG_RESET;
-        iTemp = iTemp | (bFlag << BFLAG_SHIFT_VALUE);
-        cb.writeInt(iTemp);
-
-        // Add optional TLV
-        if (!packOptionalTlv(cb)) {
-            throw new PcepParseException("Faild to write lspa objects tlv to channel buffer");
-        }
-
-        short length = (short) (cb.writerIndex() - objStartIndex);
-
-        lspaObjHeader.setObjLen(length); //will be helpful during print().
-
-        //As per RFC the length of object should be multiples of 4
-        short pad = (short) (length % 4);
-
-        if (pad != 0) {
-            pad = (short) (4 - pad);
-            for (int i = 0; i < pad; i++) {
-                cb.writeByte((byte) 0);
-            }
-            length = (short) (length + pad);
-        }
-        cb.setShort(objLenIndex, length);
-        return cb.writerIndex();
-    }
-
-    /**
-     * Parse list of optional tlvs.
-     *
-     * @param cb channel buffer
-     * @return list of optional tlvs.
-     * @throws PcepParseException when fails to parse optional tlv list.
-     */
-    public static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
-
-        LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<PcepValueType>();
-
-        return llOutOptionalTlv;
-    }
-
-    /**
-     * Writes optional tlvs to channel buffer.
-     *
-     * @param cb channel buffer
-     * @return true
-     */
-    protected boolean packOptionalTlv(ChannelBuffer cb) {
-        int hTlvType;
-        int hTlvLength;
-
-        ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
-        while (listIterator.hasNext()) {
-            PcepValueType tlv = listIterator.next();
-            if (null == tlv) {
-                log.debug("Warning: tlv is null from OptionalTlv list");
-                continue;
-            }
-            hTlvType = tlv.getType();
-            hTlvLength = tlv.getLength();
-            if (0 == hTlvLength) {
-                log.debug("Warning: invalid length in tlv of OptionalTlv list");
-                continue;
-            }
-
-            cb.writeShort(hTlvType);
-            cb.writeShort(hTlvLength);
-
-            switch (hTlvType) {
-            //TODO: optional TLV for LSPA to be added
-
-            default:
-                log.debug("Warning: PcepLspaObject: unknown tlv");
-            }
-
-            // As per RFC the length of object should
-            // be multiples of 4
-            int pad = hTlvLength % 4;
-
-            if (0 < pad) {
-                pad = 4 - pad;
-                if (pad <= cb.readableBytes()) {
-                    cb.skipBytes(pad);
-                }
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Builder class for PCEP lspa object.
-     */
-    public static class Builder implements PcepLspaObject.Builder {
-        private boolean bIsHeaderSet = false;
-
-        private PcepObjectHeader lspaObjHeader;
-
-        private boolean bLFlag;
-        private int iExcludeAny;
-        private boolean bIsExcludeAnySet = false;
-        private int iIncludeAny;
-        private boolean bIsIncludeAnySet = false;
-        private int iIncludeAll;
-        private boolean bIsIncludeAllSet = false;
-        private byte cSetupPriority;
-        private boolean bIsSetupPrioritySet = false;
-        private byte cHoldPriority;
-        private boolean bIsHoldPrioritySet = false;
-        private LinkedList<PcepValueType> llOptionalTlv;
-
-        private boolean bIsPFlagSet = false;
-        private boolean bPFlag;
-
-        private boolean bIsIFlagSet = false;
-        private boolean bIFlag;
-
-        @Override
-        public PcepLspaObject build() throws PcepParseException {
-
-            PcepObjectHeader lspaObjHeader = this.bIsHeaderSet ? this.lspaObjHeader : DEFAULT_LSPA_OBJECT_HEADER;
-
-            if (!this.bIsExcludeAnySet) {
-                throw new PcepParseException("ExcludeAny NOT Set while building PcepLspaObject.");
-            }
-            if (!this.bIsIncludeAnySet) {
-                throw new PcepParseException("IncludeAny NOT Set while building PcepLspaObject.");
-            }
-            if (!this.bIsIncludeAllSet) {
-                throw new PcepParseException("IncludeAll NOT Set while building PcepLspaObject.");
-            }
-            if (!this.bIsSetupPrioritySet) {
-                throw new PcepParseException("Setup Priority NOT Set while building PcepLspaObject.");
-            }
-            if (!this.bIsHoldPrioritySet) {
-                throw new PcepParseException("Hold Priority NOT Set while building PcepLspaObject.");
-            }
-
-            if (bIsPFlagSet) {
-                lspaObjHeader.setPFlag(bPFlag);
-            }
-
-            if (bIsIFlagSet) {
-                lspaObjHeader.setIFlag(bIFlag);
-            }
-
-            return new PcepLspaObjectVer1(lspaObjHeader, bLFlag, iExcludeAny, iIncludeAny, iIncludeAll, cSetupPriority,
-                    cHoldPriority, llOptionalTlv);
-        }
-
-        @Override
-        public PcepObjectHeader getLspaObjHeader() {
-            return this.lspaObjHeader;
-        }
-
-        @Override
-        public Builder setLspaObjHeader(PcepObjectHeader obj) {
-            this.lspaObjHeader = obj;
-            this.bIsHeaderSet = true;
-            return this;
-        }
-
-        @Override
-        public boolean getLFlag() {
-            return this.bLFlag;
-        }
-
-        @Override
-        public Builder setLFlag(boolean value) {
-            this.bLFlag = value;
-            return this;
-        }
-
-        @Override
-        public int getExcludeAny() {
-            return this.iExcludeAny;
-        }
-
-        @Override
-        public Builder setExcludeAny(int value) {
-            this.iExcludeAny = value;
-            this.bIsExcludeAnySet = true;
-            return this;
-        }
-
-        @Override
-        public int getIncludeAny() {
-            return this.iIncludeAny;
-        }
-
-        @Override
-        public Builder setIncludeAny(int value) {
-            this.iIncludeAny = value;
-            this.bIsIncludeAnySet = true;
-            return this;
-        }
-
-        @Override
-        public int getIncludeAll() {
-            return this.iIncludeAll;
-        }
-
-        @Override
-        public Builder setIncludeAll(int value) {
-            this.iIncludeAll = value;
-            this.bIsIncludeAllSet = true;
-            return this;
-        }
-
-        @Override
-        public byte getSetupPriority() {
-            return this.cSetupPriority;
-        }
-
-        @Override
-        public Builder setSetupPriority(byte value) {
-            this.cSetupPriority = value;
-            this.bIsSetupPrioritySet = true;
-            return this;
-        }
-
-        @Override
-        public byte getHoldPriority() {
-            return this.cHoldPriority;
-        }
-
-        @Override
-        public Builder setHoldPriority(byte value) {
-            this.cHoldPriority = value;
-            this.bIsHoldPrioritySet = true;
-            return this;
-        }
-
-        @Override
-        public LinkedList<PcepValueType> getOptionalTlv() {
-            return this.llOptionalTlv;
-        }
-
-        @Override
-        public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
-            this.llOptionalTlv = llOptionalTlv;
-
-            return this;
-        }
-
-        @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("LFlag", bLFlag).add("SetupPriority", cSetupPriority)
-                .add("HoldPriority", cHoldPriority).add("IncludeAll", iIncludeAll).add("IncludeAny", iIncludeAny)
-                .add("ExcludeAny", iExcludeAny).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.PcepLspaObject;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.onosproject.pcepio.types.PcepValueType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides PCEP label Object .
+ */
+public class PcepLspaObjectVer1 implements PcepLspaObject {
+
+    /* LSPA Object Body Format
+
+    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
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                       Exclude-any                             |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                       Include-any                             |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                       Include-all                             |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |  Setup Prio   |  Holding Prio |     Flags   |L|   Reserved    |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                                                               |
+    |                      Optional TLVs                            |
+    |                                                               |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepLspaObjectVer1.class);
+
+    public static final byte LSPA_OBJ_TYPE = 1;
+    public static final byte LSPA_OBJ_CLASS = 9;
+    public static final byte LSPA_OBJECT_VERSION = 1;
+    public static final short LSPA_OBJ_MINIMUM_LENGTH = 20;
+    public static final int OBJECT_HEADER_LENGTH = 4;
+
+    static final PcepObjectHeader DEFAULT_LSPA_OBJECT_HEADER = new PcepObjectHeader(LSPA_OBJ_CLASS, LSPA_OBJ_TYPE,
+            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, LSPA_OBJ_MINIMUM_LENGTH);
+
+    public static final int SETUP_PRIORITY_SHIFT_VALUE = 24;
+    public static final int HOLD_PRIORITY_SHIFT_VALUE = 16;
+    public static final int BFLAG_SHIFT_VALUE = 8;
+    public static final int LFLAG_SET = 1;
+    public static final int LFLAG_RESET = 0;
+    private PcepObjectHeader lspaObjHeader;
+    private int iExcludeAny;
+    private int iIncludeAny;
+    private int iIncludeAll;
+    private byte cSetupPriority;
+    private byte cHoldPriority;
+    private boolean bLFlag;
+    private LinkedList<PcepValueType> llOptionalTlv; //Optional TLV
+
+    /**
+     * Constructor to initialize member variables.
+     *
+     * @param lspaObjHeader lspa object header
+     * @param bLFlag b l flag
+     * @param iExcludeAny excludeAny value
+     * @param iIncludeAny includeAny value
+     * @param iIncludeAll includeAll value
+     * @param cSetupPriority setup priority value
+     * @param cHoldPriority hold priority value
+     * @param llOptionalTlv list of optional tlv
+     */
+    public PcepLspaObjectVer1(PcepObjectHeader lspaObjHeader, boolean bLFlag, int iExcludeAny, int iIncludeAny,
+            int iIncludeAll, byte cSetupPriority, byte cHoldPriority, LinkedList<PcepValueType> llOptionalTlv) {
+
+        this.lspaObjHeader = lspaObjHeader;
+        this.bLFlag = bLFlag;
+        this.iExcludeAny = iExcludeAny;
+        this.iIncludeAny = iIncludeAny;
+        this.iIncludeAll = iIncludeAll;
+        this.cSetupPriority = cSetupPriority;
+        this.cHoldPriority = cHoldPriority;
+        this.llOptionalTlv = llOptionalTlv;
+    }
+
+    /**
+     * Sets Object Header.
+     *
+     * @param obj lspa object header
+     */
+    public void setLspaObjHeader(PcepObjectHeader obj) {
+        this.lspaObjHeader = obj;
+    }
+
+    @Override
+    public void setExcludeAny(int iExcludeAny) {
+        this.iExcludeAny = iExcludeAny;
+    }
+
+    @Override
+    public void setIncludeAny(int iIncludeAny) {
+        this.iIncludeAny = iIncludeAny;
+    }
+
+    @Override
+    public void setSetupPriority(byte cSetupPriority) {
+        this.cSetupPriority = cSetupPriority;
+    }
+
+    @Override
+    public void setHoldPriority(byte cHoldPriority) {
+        this.cHoldPriority = cHoldPriority;
+    }
+
+    @Override
+    public void setLFlag(boolean bLFlag) {
+        this.bLFlag = bLFlag;
+    }
+
+    /**
+     * Returns lspa Object Header.
+     *
+     * @return lspa Object Header
+     */
+    public PcepObjectHeader getLspaObjHeader() {
+        return this.lspaObjHeader;
+    }
+
+    @Override
+    public int getExcludeAny() {
+        return this.iExcludeAny;
+    }
+
+    @Override
+    public int getIncludeAny() {
+        return this.iIncludeAny;
+    }
+
+    @Override
+    public int getIncludeAll() {
+        return this.iIncludeAll;
+    }
+
+    @Override
+    public byte getSetupPriority() {
+        return this.cSetupPriority;
+    }
+
+    @Override
+    public byte getHoldPriority() {
+        return this.cHoldPriority;
+    }
+
+    @Override
+    public boolean getLFlag() {
+        return this.bLFlag;
+    }
+
+    @Override
+    public void setIncludeAll(int value) {
+        this.iIncludeAll = value;
+
+    }
+
+    @Override
+    public LinkedList<PcepValueType> getOptionalTlv() {
+        return this.llOptionalTlv;
+    }
+
+    @Override
+    public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
+        this.llOptionalTlv = llOptionalTlv;
+
+    }
+
+    /**
+     * Reads channel buffer and returns object of PcepLspaObject.
+     *
+     * @param cb of type channel buffer.
+     * @return object of PcepLspaObject
+     * @throws PcepParseException while parsing lspa object from channel buffer
+     */
+    public static PcepLspaObject read(ChannelBuffer cb) throws PcepParseException {
+
+        log.debug("LspaObject::read");
+        PcepObjectHeader lspaObjHeader;
+        int iExcludeAny;
+        int iIncludeAny;
+        int iIncludeAll;
+        byte cSetupPriority;
+        byte cHoldPriority;
+        boolean bLFlag;
+        byte flags;
+
+        // Optional TLV
+        LinkedList<PcepValueType> llOptionalTlv;
+
+        lspaObjHeader = PcepObjectHeader.read(cb);
+
+        //take only Lspa Object buffer.
+        ChannelBuffer tempCb = cb.readBytes(lspaObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
+        iExcludeAny = tempCb.readInt();
+        iIncludeAny = tempCb.readInt();
+        iIncludeAll = tempCb.readInt();
+        cSetupPriority = tempCb.readByte();
+        cHoldPriority = tempCb.readByte();
+        flags = tempCb.readByte();
+        tempCb.readByte();
+
+        bLFlag = (flags & (byte) LFLAG_SET) == LFLAG_SET ? true : false;
+
+        llOptionalTlv = parseOptionalTlv(tempCb);
+
+        return new PcepLspaObjectVer1(lspaObjHeader, bLFlag, iExcludeAny, iIncludeAny, iIncludeAll, cSetupPriority,
+                cHoldPriority, llOptionalTlv);
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+
+        //write Object header
+        int objStartIndex = cb.writerIndex();
+
+        int objLenIndex = lspaObjHeader.write(cb);
+
+        if (objLenIndex <= 0) {
+            throw new PcepParseException("Failed to write lspa object header. Index " + objLenIndex);
+        }
+
+        cb.writeInt(iExcludeAny);
+        cb.writeInt(iIncludeAny);
+        cb.writeInt(iIncludeAll);
+
+        int iTemp = cSetupPriority << SETUP_PRIORITY_SHIFT_VALUE;
+        iTemp = iTemp | (cHoldPriority << HOLD_PRIORITY_SHIFT_VALUE);
+        byte bFlag;
+        bFlag = (bLFlag) ? (byte) LFLAG_SET : LFLAG_RESET;
+        iTemp = iTemp | (bFlag << BFLAG_SHIFT_VALUE);
+        cb.writeInt(iTemp);
+
+        // Add optional TLV
+        if (!packOptionalTlv(cb)) {
+            throw new PcepParseException("Faild to write lspa objects tlv to channel buffer");
+        }
+
+        short length = (short) (cb.writerIndex() - objStartIndex);
+
+        lspaObjHeader.setObjLen(length); //will be helpful during print().
+
+        //As per RFC the length of object should be multiples of 4
+        short pad = (short) (length % 4);
+
+        if (pad != 0) {
+            pad = (short) (4 - pad);
+            for (int i = 0; i < pad; i++) {
+                cb.writeByte((byte) 0);
+            }
+            length = (short) (length + pad);
+        }
+        cb.setShort(objLenIndex, length);
+        return cb.writerIndex();
+    }
+
+    /**
+     * Parse list of optional tlvs.
+     *
+     * @param cb channel buffer
+     * @return list of optional tlvs.
+     * @throws PcepParseException when fails to parse optional tlv list.
+     */
+    public static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
+
+        LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<PcepValueType>();
+
+        return llOutOptionalTlv;
+    }
+
+    /**
+     * Writes optional tlvs to channel buffer.
+     *
+     * @param cb channel buffer
+     * @return true
+     */
+    protected boolean packOptionalTlv(ChannelBuffer cb) {
+        int hTlvType;
+        int hTlvLength;
+
+        ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
+        while (listIterator.hasNext()) {
+            PcepValueType tlv = listIterator.next();
+            if (null == tlv) {
+                log.debug("Warning: tlv is null from OptionalTlv list");
+                continue;
+            }
+            hTlvType = tlv.getType();
+            hTlvLength = tlv.getLength();
+            if (0 == hTlvLength) {
+                log.debug("Warning: invalid length in tlv of OptionalTlv list");
+                continue;
+            }
+
+            cb.writeShort(hTlvType);
+            cb.writeShort(hTlvLength);
+
+            switch (hTlvType) {
+            //TODO: optional TLV for LSPA to be added
+
+            default:
+                log.debug("Warning: PcepLspaObject: unknown tlv");
+            }
+
+            // As per RFC the length of object should
+            // be multiples of 4
+            int pad = hTlvLength % 4;
+
+            if (0 < pad) {
+                pad = 4 - pad;
+                if (pad <= cb.readableBytes()) {
+                    cb.skipBytes(pad);
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Builder class for PCEP lspa object.
+     */
+    public static class Builder implements PcepLspaObject.Builder {
+        private boolean bIsHeaderSet = false;
+
+        private PcepObjectHeader lspaObjHeader;
+
+        private boolean bLFlag;
+        private int iExcludeAny;
+        private boolean bIsExcludeAnySet = false;
+        private int iIncludeAny;
+        private boolean bIsIncludeAnySet = false;
+        private int iIncludeAll;
+        private boolean bIsIncludeAllSet = false;
+        private byte cSetupPriority;
+        private boolean bIsSetupPrioritySet = false;
+        private byte cHoldPriority;
+        private boolean bIsHoldPrioritySet = false;
+        private LinkedList<PcepValueType> llOptionalTlv;
+
+        private boolean bIsPFlagSet = false;
+        private boolean bPFlag;
+
+        private boolean bIsIFlagSet = false;
+        private boolean bIFlag;
+
+        @Override
+        public PcepLspaObject build() throws PcepParseException {
+
+            PcepObjectHeader lspaObjHeader = this.bIsHeaderSet ? this.lspaObjHeader : DEFAULT_LSPA_OBJECT_HEADER;
+
+            if (!this.bIsExcludeAnySet) {
+                throw new PcepParseException("ExcludeAny NOT Set while building PcepLspaObject.");
+            }
+            if (!this.bIsIncludeAnySet) {
+                throw new PcepParseException("IncludeAny NOT Set while building PcepLspaObject.");
+            }
+            if (!this.bIsIncludeAllSet) {
+                throw new PcepParseException("IncludeAll NOT Set while building PcepLspaObject.");
+            }
+            if (!this.bIsSetupPrioritySet) {
+                throw new PcepParseException("Setup Priority NOT Set while building PcepLspaObject.");
+            }
+            if (!this.bIsHoldPrioritySet) {
+                throw new PcepParseException("Hold Priority NOT Set while building PcepLspaObject.");
+            }
+
+            if (bIsPFlagSet) {
+                lspaObjHeader.setPFlag(bPFlag);
+            }
+
+            if (bIsIFlagSet) {
+                lspaObjHeader.setIFlag(bIFlag);
+            }
+
+            return new PcepLspaObjectVer1(lspaObjHeader, bLFlag, iExcludeAny, iIncludeAny, iIncludeAll, cSetupPriority,
+                    cHoldPriority, llOptionalTlv);
+        }
+
+        @Override
+        public PcepObjectHeader getLspaObjHeader() {
+            return this.lspaObjHeader;
+        }
+
+        @Override
+        public Builder setLspaObjHeader(PcepObjectHeader obj) {
+            this.lspaObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public boolean getLFlag() {
+            return this.bLFlag;
+        }
+
+        @Override
+        public Builder setLFlag(boolean value) {
+            this.bLFlag = value;
+            return this;
+        }
+
+        @Override
+        public int getExcludeAny() {
+            return this.iExcludeAny;
+        }
+
+        @Override
+        public Builder setExcludeAny(int value) {
+            this.iExcludeAny = value;
+            this.bIsExcludeAnySet = true;
+            return this;
+        }
+
+        @Override
+        public int getIncludeAny() {
+            return this.iIncludeAny;
+        }
+
+        @Override
+        public Builder setIncludeAny(int value) {
+            this.iIncludeAny = value;
+            this.bIsIncludeAnySet = true;
+            return this;
+        }
+
+        @Override
+        public int getIncludeAll() {
+            return this.iIncludeAll;
+        }
+
+        @Override
+        public Builder setIncludeAll(int value) {
+            this.iIncludeAll = value;
+            this.bIsIncludeAllSet = true;
+            return this;
+        }
+
+        @Override
+        public byte getSetupPriority() {
+            return this.cSetupPriority;
+        }
+
+        @Override
+        public Builder setSetupPriority(byte value) {
+            this.cSetupPriority = value;
+            this.bIsSetupPrioritySet = true;
+            return this;
+        }
+
+        @Override
+        public byte getHoldPriority() {
+            return this.cHoldPriority;
+        }
+
+        @Override
+        public Builder setHoldPriority(byte value) {
+            this.cHoldPriority = value;
+            this.bIsHoldPrioritySet = true;
+            return this;
+        }
+
+        @Override
+        public LinkedList<PcepValueType> getOptionalTlv() {
+            return this.llOptionalTlv;
+        }
+
+        @Override
+        public Builder setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
+            this.llOptionalTlv = llOptionalTlv;
+
+            return this;
+        }
+
+        @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("LFlag", bLFlag).add("SetupPriority", cSetupPriority)
+                .add("HoldPriority", cHoldPriority).add("IncludeAll", iIncludeAll).add("IncludeAny", iIncludeAny)
+                .add("ExcludeAny", iExcludeAny).add("OptionalTlvList", llOptionalTlv).toString();
+    }
+}
